Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't a class have to provide a failable initializer if it implements a protocol that declares one?

I am trying to understand the following, contrived, example:

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 declares a failable initializer. MyObject conforms to MyProtocol and the example code compiles and executes without issue.

My question is: Why doesn't MyObject have to provide a failable initializer (as per MyProtocol)?

like image 914
RobertJoseph Avatar asked Jun 09 '16 15:06

RobertJoseph


1 Answers

This is for the same reason that this compiles:

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

init can override (i.e. be substituted for) init?.

See also the docs (when something is so clearly documented, it seems silly to ask "why"; it's just a fact about the language):

A failable initializer requirement can be satisfied by a failable or nonfailable initializer on a conforming type.

(As pointed out in the comments on the question and on the answer, this makes perfect sense if you think about the difference between an init? that happens never to fail and an init with the same signature — namely, there is no effective difference. To put it another way: You can tell me that I may fail, but you cannot tell me that I must fail.)

like image 133
matt Avatar answered Sep 22 '22 21:09

matt