2016-06-09 26 views
5

mi sto cercando di capire quanto segue, artificiosa, ad esempio:Perché una classe non deve fornire un inizializzatore fessibile se implementa un protocollo che ne dichiara uno?

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 dichiara un failable initializer. MyObject è conforme allo MyProtocol e il codice di esempio viene compilato ed eseguito senza problemi.

La mia domanda è: perché non lo fa MyObjecthanno per fornire un inizializzatore failable (come da MyProtocol)?

+2

L'initialiser fallibile è ancora un initialiser che restituisce un. 'MyObject' nel caso ideale. Viene trumped dall'inizializzatore non-failiable della stessa firma. Devi ancora fornire all'inizializzatore la stessa firma per la compilazione del codice. Immagino sia un inizializzatore fallibile che non può fallire. In un modo. – Fogmeister

+1

Forse perché gli optional sono opzionali? Haha ma su una nota più seria un oggetto intializzato che è sempre ". Qualcuno" soddisferà il tuo protocollo. – NSGangster

risposta

6

Questo è per la stessa ragione che questo compila:

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

init può sostituire (cioè sostituite) init?.

Vedere anche il docs (quando qualcosa è così chiaramente documentato, sembra stupido a chiedere "perché", è solo un fatto che riguarda la lingua):

Un requisito inizializzatore failable può essere soddisfatta da un failable o inizializzatore non disponibile su un tipo conforme.

(Come evidenziato in sede di commento della domanda e della risposta, questo ha perfettamente senso se si pensa alla differenza tra un init? che accade mai a fallire ed un init con la stessa firma - vale a dire, non ci è non differenza efficaci per dirla in altro modo:. puoi dirmi che io possa fallire, ma non mi può dire che ho devo fallire)

+0

Quando si ha un'istanza di B, * è * un'implementazione per init?(). Questo non è vero nel mio caso, poiché MyObject non fornisce un'implementazione per l'inizializzatore di file disponibili di MyProtocol. – RobertJoseph

+3

È perché un inizializzatore che è disponibile deve restituire un oggetto 'nil' OR' non-nil'. Poiché un inizializzatore non disponibile restituisce sempre un oggetto 'non-nil', soddisfa il suo protocollo e un tipo di ha solo senso. – NSGangster

+1

@NSGangster Molto ben messo. @RobertJoseph, ecco un altro modo di vederlo: immagina di aver implementato 'init? ', Ma, in realtà, la tua implementazione _never_ ha restituito' nil'. Chiaramente, ciò che soddisferebbe il requisito. Bene, l'implementazione di 'init' è la stessa. – matt