2017-10-24 4 views
0

Ich habe das folgende Stück Code, das Protokoll MyDisplayable hat drei optionale String s, und ich habe eine Standard-Implementierung des Protokolls über die Erweiterung. Meine Frage ist, da ich sicher bin, dass die Erweiterung die drei Strings zurückgibt, gibt es eine Möglichkeit, sie als nicht-optional zu verwenden, und besteht irgendein Risiko, wenn eine andere Implementierung sie überschreibt? (Siehe die Frage Punkte 1 und 2 in Code unten)Swift Protokoll Standard-Implementierung für optionale Readonly Variablen

Vielen Dank!

protocol MyDisplayable { 
    var displayName: String? { get } 
    var shortDescription: String? { get } 
    var longDescription: String? { get } 
} 

protocol MyObject : MyDisplayable, CustomStringConvertible { 
} 

extension MyObject { 
    var displayName: String? { 
     return "noname" 
    } 

    var shortDescription: String? { 
     return "something can't be described" 
    } 

    var longDescription: String? { 
     return "no way to describe it further" 
    } 

    var description: String { 
     // **1. is there a way to use the strings as if they are non-optional?** 
     // **2. is it a problem if another class implements the protocol and returns `nil` for any of the strings, but here they are force unwrapped?** 
     return "\(displayName!): \(shortDescription!)\n\(longDescription!)" 
    } 
} 

class Something : MyObject { 
} 

let something = Something() 
print("Something: \(something)") 
+0

Wenn ich du wäre würde ich solche Dinge nicht komplizieren; und anstatt dieses spezielle Problem zu lösen, finden Sie besser einen anderen Weg, um Ihr Ziel zu erreichen. Sich mit einem Knall herumzuhacken, macht manchmal die Sache schlimmer, zusätzlich dazu, dass der Compiler schwerer ist. Vielleicht könntest du * ohne * 'MyObject' machen und hast einfach nicht-optionale Strings in' MyDisplayable' mit den vorgegebenen Standardwerten. – user1244109

Antwort

0

Leider ist es nicht möglich, eine deklarierte Option als nicht optional zu behandeln. Sie haben diese Zeichenfolgen in Ihrem Protokoll als optional deklariert. Wenn Sie dieses Protokoll implementieren, bleiben sie optional.

Sie können jedoch mithilfe von Getter-Setter sicherstellen, dass Ihre Variablen immer einen Wert speichern, auch wenn sie als optional deklariert sind.

Ich werde mit einigen Code erarbeiten:

protocol MyDisplayable { 
    var displayName: String? { get set } 
    var shortDescription: String? { get set } 
    var longDescription: String? { get set } 
} 

protocol MyObject : MyDisplayable, CustomStringConvertible { 
} 

extension MyObject { 
    var displayName: String? { 
     get { 
      return "noname" 
     } 
     set { 
      newValue ?? "" 
     } 
    } 

    var shortDescription: String? { 
     get { 
      return "something can't be described" 
     } 
     set { 
      newValue ?? "" 
     } 
    } 

    var longDescription: String? { 
     get { 
      return "no way to describe it further" 
     } 
     set { 
      newValue ?? "" 
     } 
    } 

    var description: String { 
     // **1. is there a way to use the strings as if they are non-optional?** 
     // **2. is it a problem if another class implements the protocol and returns `nil` for any of the strings, but here they are force unwrapped?** 
     return "\(displayName!): \(shortDescription!)\n\(longDescription!)" 
    } 
} 

class Something : MyObject { 
} 

let something = Something() 
print("Something: \(something)") 

Jetzt auch wenn einige andere Klasse überschreibt einen Nullwert für diese Strings werden sie leere Zeichenfolge zurückgeben „“. Sie sind immer noch optional, da sie als optional deklariert werden, aber jetzt haben sie immer einen Nicht-Null-Wert.

+0

Gute Idee brechen, obwohl es eine Schande, dass das Protokoll Setter auszusetzen hat. – hzxu

0

Wie wäre es mit bedingten Auspacken in Ihrer Standardimplementierung?

return "\(displayName ?? ""): \(shortDescription ?? "")\n\(longDescription ?? "")" 
+0

Ja, das ist besser, aber es hat immer noch das Problem, dass, wenn eine andere Klasse die Standardimplementierung überschreibt, die Strings "nil" sein könnten, was die Beschreibung durchbricht. – hzxu

+0

In Ihrer Klasse, sagen wir, ich übergehe displayName, um nil zurückzugeben. Es funktioniert immer noch, richtig! Klasse Etwas: MyObject { var displayName: String? { return null } } die pflegt die obige Umsetzung –

Verwandte Themen