在super.init之前使用表达式中的初始化属性的Swift错误

时间:2014-12-04 19:23:57

标签: swift properties initialization

这并不重要,而且有一些解决方法,但这很令人困惑。

请参阅下面的最小示例。我指的是初始化属性,但在调用super.init()之前。为什么下面指出的语句有编译错误?在表达式的右手边使用属性与左手有什么特别之处吗?

我查看了Swift语言指南,但找不到任何相关内容。 swift编译器在这里搞砸了,还是有关于我失踪的属性,自我和init的东西?或所有引用" myProperty"在调用super.init之前出错?

(注意,如果属性是一个常量(使用' let')或者如果属性是另一种类型(如Int),则无关紧要 - 同样的事情发生。)

class MyClass : NSObject {
    var myProperty: Bool

    override init() {
        myProperty = true

        if myProperty { /* this is ok */ }
        if myProperty || true { /* this is ok */ }
        if true || myProperty  { /* this is NOT ok! ('self used before super.init') - WHY? */ }

        super.init()

        if true || myProperty  { /* now this is ok */ }
    }
}

2 个答案:

答案 0 :(得分:4)

这是||被声明为

的副作用
func ||<T : BooleanType>(lhs: T, rhs: @autoclosure () -> Bool) -> Bool

所以编译器会处理

true || myProperty

作为

true || { self.myProperty }()

原因是||运算符的&#34;短路&#34; 行为:如果是第一个 操作数为true,则根本不能评估第二个操作数。

旁注:我认为这是在以后的阶段简化  编译/优化过程 这样最终的代码实际上并没有创建并调用一个闭包。)

在闭包内访问self会导致错误消息。你会

得到同样的错误
override init() {
    myProperty = true
    let a = { self }() // ERROR: self used before super.init
    super.init()
    let b = { self }() // OK after super.init
}

答案 1 :(得分:0)

我认为它是intended behavior并且是两阶段初始化的一部分。

这是以下规则的结果:

  • 所有属性必须在调用super.init 之前初始化,与声明位于同一行,或者在super.init之前的init中初始化
  • 初始值设定项可能不调用任何实例方法,读取任何实例属性的值,或者将self称为值,直到第一阶段之后初始化已完成