Protocol Extension Initializer forcing to call self.init

有些话、适合烂在心里 提交于 2019-12-06 05:43:31

问题


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?


回答1:


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).



来源:https://stackoverflow.com/questions/50270261/protocol-extension-initializer-forcing-to-call-self-init

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!