为什么我在Swift中初始化变量的行上得到“在初始化之前使用的变量”错误?

时间:2014-11-20 11:49:46

标签: ios swift

我很难理解为什么我在使用Swift的iOS项目中遇到此编译器错误。如果我创建以下类:

class InitTest {

    let a: Int
    let b: Int
    let c: Int

    init () {
        self.a = 3
        self.b = 4
        self.c = self.runCalculation()
    }

    func runCalculation () -> Int {
        return self.a * self.b
    }
}

我在行self.c = self.runCalculation()上遇到编译错误,说"变量' self.c'在被初始化之前使用"。

起初我认为这是因为编译器无法验证runCalculation()方法没有访问self.c,但后来我尝试将init方法混合起来:

init () {
    self.a = 3
    self.c = self.runCalculation()
    self.b = 4
}

这次错误是"变量' self.b'在初始化之前使用" (在同一self.runCalculation()行)。这表明编译器 能够检查方法访问哪些属性,因此,据我所知,初始案例应该没有问题。

当然这是一个简单的例子,我可以很容易地重构以避免调用计算方法,但在一个真实的项目中,可能会有几个计算,每个计算都可能非常复杂。我希望能够将逻辑分开以保持可读性。

幸运的是,这是一个简单的解决方法:

init () {
    self.a = 3
    self.b = 4

    self.c = 0
    self.c = self.runCalculation()
}

(或使用属性初始化程序let c = 0)但我想了解编译器在第一个示例中遇到问题的原因。我错过了什么或是不必要的限制吗?

1 个答案:

答案 0 :(得分:45)

由于两阶段初始化,Swift有这种行为。来自Apple的Swift书:

  

Swift中的类初始化是一个两阶段的过程。在第一个   阶段,每个存储的属性由类分配初始值   介绍它。一旦每个存储属性的初始状态   已确定,第二阶段开始,每个班级都给出   有机会在之前进一步定制其存储的属性   新实例被认为可以使用了。

在第一阶段结束之前,类需要某种默认值。定制值是第二阶段的一部分。

Objective-C没有这种行为,因为它总是可以将0作为基元的默认值,而nil作为对象,但在Swift中没有提供这种默认值的机制。 / p>