2016-06-09 5 views
5

Ich versuche, die folgenden, gekünstelt, Beispiel zu verstehen:Warum muss eine Klasse keinen initialisierbaren Initializer bereitstellen, wenn sie ein Protokoll implementiert, das einen deklariert?

protocol MyProtocol { 
    init?(string: String) 
} 

class MyObject: MyProtocol { 
    let s: String 
    required init(string: String) { 
    self.s = string 
    } 
} 

let o = MyObject(string: "test") 
print(o.s) 

MyProtocol deklariert ein failable initializer. MyObject entspricht MyProtocol und der Beispielcode wird kompiliert und ohne Problem ausgeführt.

Meine Frage ist: Warum nicht MyObjecthaben eine failable initializer bereitzustellen (per MyProtocol)?

+2

Der fehlbare initialiser noch ein initialiser ist, dass ein zurückgibt. 'MyObject' im Idealfall. Es wird von dem fehlerfreien Initialisierer derselben Signatur übertrumpft. Sie müssen dem Initialisierer immer noch die gleiche Signatur für den zu kompilierenden Code bereitstellen. Ich denke, es ist ein fehlbarer Initialisierer, der nicht fehlschlagen kann. In gewisser Weise. – Fogmeister

+1

Vielleicht weil optionale Optionen optional sind? Haha aber auf eine ernstere Note wird ein initialisiertes Objekt, das immer '.Some' ist, dein Protokoll erfüllen. – NSGangster

Antwort

6

Dies ist aus dem gleichen Grund, dass diese kompiliert:

class A { 
    init?(s:String) {} 
    init() {} 
} 
class B : A { 
    override init(s:String) {super.init()} 
} 

init überschreiben können (das heißt für die substituiert sein kann) init?.

Siehe auch die docs (wenn etwas so klar dokumentiert, so scheint es dumm, „warum“ zu fragen, es ist nur eine Tatsache, über die Sprache):

A failable initializer Anforderung durch einen failable erfüllt werden können oder nicht failable Initialisierer auf einem übereinstimmenden Typ.

(Wie in den Kommentaren über die Frage und die Antwort darauf hingewiesen, macht dies durchaus Sinn, wenn Sie über den Unterschied zwischen einem init? denken, die nie zum Scheitern verurteilt und ein init mit derselben Signatur passiert - nämlich dort, ist kein effektive Unterschied es anders auszudrücken:. Sie kann mir sagen, dass ich scheitern , aber Sie können mir nicht sagen, dass ich scheitern muss)

+0

Wenn Sie eine Instanz von B haben, ist * eine Implementierung für init?(). Das trifft in meinem Fall nicht zu, da MyObject keine Implementierung für den fehlgeleiteten Initialisierer von MyProtocol bereitstellt. – RobertJoseph

+3

Das liegt daran, dass ein Initialisierer, der fehlbar ist, ein Objekt "nil" oder "non-nil" zurückgeben muss. Da ein nicht failable-Initialisierer immer ein 'non-nil'-Objekt zurückgibt, erfüllt es sein Protokoll und macht nur einen Sinn. – NSGangster

+1

@ NSGangster Sehr gut gestellt. @RobertJoseph, hier ist eine andere Art, es zu sehen: Stellen Sie sich vor, Sie hätten 'init?' Implementiert, aber Ihre Implementierung _never_ hat 'nil' zurückgegeben. Klar, dass _das_ die Anforderung erfüllen würde. Nun, das Implementieren von 'init' ist das gleiche. – matt