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:如果我犯了一些错误(代码,语言,语法,…),欢迎纠正我:)

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...