I was just reading the Apple Swift 4 document regarding the Protocol Initializer Requirements and providing a default implementation in the protocol extension.
import UIKit
protocol Protocol {
init()
}
extension Protocol {
init() {
print("SDf")
self.init() // Line 1
// Compiler error occured if this is omitted
//"'self.init' isn't called on all paths before returning from initializer"
}
}
struct Structure: Protocol {
init(string: String) {
}
}
Structure() // Line 2
Now as you can see, the execution will go into a loop, as by default the structure doesn't have an implementation for init()
, so the protocol provided init will be called and it will call itself again, and so it goes into an infinite loop.
Now, knowing this, if I remove Line 1, the compiler gives the error.
Q. Why is it forcing me to use self.init()
on Line 1, and how can I get out of this situation?
Consider this example:
protocol P {
init()
}
extension P {
init() {
} // error: 'self.init' isn't called on all paths before returning from initializer
}
struct S : P {
var str: String
}
let s = S()
print(s.str)
Suppose it compiled – we'd be able to create an S
value without providing a value for the str
property. That's why the compiler is complaining that your protocol extension implementation of init()
isn't calling self.init
. It needs you to chain to some other initialiser requirement – one that you don't provide a default implementation for (otherwise you could get into a recursive loop, as you found out), and therefore one that the adopting type needs to implement such that it can fully initialise itself.
For example, this is legal:
protocol P {
init()
init(str: String)
}
extension P {
init() {
self.init(str: "some default")
}
}
struct S : P {
var str: String
}
let s = S()
print(s.str) // some default
because now we're chaining to the init(str:)
requirement, which S
must implement (in this case it's satisfied by the implicit memberwise initialiser).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With