swift2 – 如何在协议扩展中定义初始化程序?
protocol Car { var wheels : Int { get set} init(wheels: Int) } extension Car { init(wheels: Int) { self.wheels = wheels } } on self.wheelels = wheel我得到错误 Error: variable 'self' passed by reference before being initialized 如何在协议扩展中定义初始化程序?
正如您可以看到,这在这些情况下不起作用,因为编译必须确保在使用struct / enum / class之前初始化所有属性。
您可以使另一个初始化程序成为一个要求,因此编译器知道所有属性都已初始化: protocol Car { var wheels : Int { get set } // make another initializer // (which you probably don't want to provide a default implementation) // a protocol requirement. Care about recursive initializer calls :) init() init(wheels: Int) } extension Car { // now you can provide a default implementation init(wheels: Int) { self.init() self.wheels = wheels } } // example usage // mark as final final class HoverCar: Car { var wheels = 0 init() {} } let drivableHoverCar = HoverCar(wheels: 4) drivableHoverCar.wheels // 6 从Xcode 7.3 beta 1开始,它可以像预期一样使用结构体,但不适用于类,因为如果它们不是最终的,那么协议中的init(wheels:Int)就是一个必需的init,它可以被覆盖,因此不能通过扩展来添加。解决方法(按照编译器的建议):使课程最终化。 另一种解决办法(深入;没有最后的班级) 要使用类而不使它们成为最终,您还可以在协议中删除init(wheels:Int)要求。看来它的行为与以前没有什么不同,但考虑这个代码: protocol Car { var wheels : Int { get set } init() // there is no init(wheels: Int) } extension Car { init(wheels: Int) { self.init() print("Extension") self.wheels = wheels } } class HoverCar: Car { var wheels = 0 required init() {} init(wheels: Int) { print("HoverCar") self.wheels = wheels } } // prints "HoverCar" let drivableHoverCar = HoverCar(wheels: 4) func makeNewCarFromCar<T: Car>(car: T) -> T { return T(wheels: car.wheels) } // prints "Extension" makeNewCarFromCar(drivableHoverCar) 因此,如果您从通用上下文中创建一个Car,其中调用init的类型仅被称为Car即使在HoverCar中定义了初始化程序,也会调用扩展初始化程序。这只是因为在协议中没有init(wheels:Int)要求。 如果添加它,则将前一个问题声明为final,但现在打印两次“HoverCar”。无论哪种方式,第二个问题可能永远不会发生,所以它可能是一个更好的解决方案 Sidenote:如果我犯了一些错误(代码,语言,语法,…),欢迎纠正我:) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |