2016-06-09 10 views
5

Próbuję zrozumieć, co następuje, wymyślony, przykład:Dlaczego klasa nie musi dostarczyć awaryjnego inicjalizatora, jeśli implementuje protokół, który ją deklaruje?

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 deklaruje failable initializer. MyObject jest zgodny z MyProtocol, a przykładowy kod kompiluje się i wykonuje bez problemu.

Moje pytanie brzmi: Dlaczego nie MyObjectmieć dostarczenie failable inicjator (zgodnie MyProtocol)?

+2

omylny initialiser jest nadal initialiser że zwraca. 'MyObject' w idealnym przypadku. Jest podszyta przez nieweryfikowalny inicjator tego samego podpisu. Nadal musisz dostarczyć inicjatorowi tę samą sygnaturę dla kodu do kompilacji. Sądzę, że jest to omylny inicjator, który nie może zawieść. W pewien sposób. – Fogmeister

+1

Być może dlatego, że opcje są opcjonalne? Haha, ale na bardziej poważny zanotować intialized obiekt, który jest zawsze '.Some' będzie spełniać twój protokół. – NSGangster

Odpowiedz

6

to z tego samego powodu, że zestawia:

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

init może przeważać (to być podstawione) init?.

Patrz także docs (kiedy coś jest tak jasno udokumentowane, wydaje się głupie pytanie „dlaczego”, to po prostu fakt o języku):

failable wymóg inicjator może być spełnione przez failable lub niewymyślny inicjator na zgodnym typie.

(Jak zauważył w komentarzach na pytanie oraz na odpowiedź, to ma sens, jeśli myślisz o różnicę między init? że nigdy nie zdarza się niepowodzeniem i init z tym samym podpisem - mianowicie, że jest nie skuteczne różnica Ujmując to w inny sposób. Możesz mi powiedzieć, że może nie, ale nie można powiedzieć, że ja musi fail)

+0

Gdy masz instancję B tam * jest * implementacja dla init?(). W moim przypadku nie jest to prawdą, ponieważ MyObject nie zapewnia implementacji inicjalizatora MyProtocol, który może się uruchomić. – RobertJoseph

+3

To dlatego, że inicjator, który jest uszkodzony, musi zwrócić obiekt 'nil' OR' non-nil'. Ponieważ niewiążący inicjator zawsze zwraca obiekt "niezerowy", spełnia on swój protokół i ma tylko sens. – NSGangster

+1

@NSGangster Bardzo dobrze. @RobertJoseph, oto inny sposób widzenia go: Wyobraź sobie, że zaimplementowałeś 'init?', Ale w rzeczywistości twoja implementacja _never_ zwróciła 'nil'. Oczywiście, to by spełniło wymagania. Cóż, implementacja 'init' jest taka sama. – matt

Powiązane problemy