initialization - Why would you use `init!` instead of `init?` when implementing a Failable Initializer in Swift? -


the swift documentation initialization: failable initializers details how use init? create failable initializer, initializer returns optional of type initializes. optionals, nil or non-nil.

the docs mention can use init! create failable initializer, returns implicitly unwrapped optional of type initializes (see the init! failable initializer section). unwraps optional , indicates "should" non-nil. if nil , accessed without checking, programmer may skip since marked "should non-nil", runtime error generated.

two questions:

  1. when/why use init! instead of init? when implementing failable initializer?
  2. since init! returns implicitly unwrapped optional "should" non-nil, why wouldn't use init instead of init!?

in vast majority of cases should use init rather init!. there few cases init! necessary. common in experience when "must succeed" initializer wants call failable initializer. consider case:

struct notempty {     let something: string     init?(something: string) {         guard !something.isempty else { return nil }         self.something =     }      init() {         self.init(something: "unknown")! // <-- illegal     } } 

we know init() succeed because we're passing non-empty string. there's no way express standard initializer (and compiler can't prove it's true anyway). instead, need use init!:

init!() {     self.init(something: "unknown") } 

now caller can treat result though non-optional (which is), though according types have failed. programming error , you'd crash. ! here says "yeah, know fail, promise never will." , in swift, "promise" means "or else please crash."


Comments

Popular posts from this blog

python - pip install -U PySide error -

arrays - C++ error: a brace-enclosed initializer is not allowed here before ‘{’ token -

cytoscape.js - How to add nodes to Dagre layout with Cytoscape -