为什么我在Swift中初始化这个variables的时候得到一个“初始化之前使用的variables”错误?

我努力理解为什么我在使用Swift的iOS项目中遇到这个编译器错误。 如果我创build了以下类:

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()这行中得到了一个编译器错误,说“初始化之前使用了variables'self.c'”。

起初我以为这是因为编译器无法validationrunCalculation()方法没有访问self.c ,但后来我试着将init方法混合了一下:

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

这次错误是“初始化之前使用的variables”self.b“(在同一个self.runCalculation()行)。 这表明编译器能够检查方法访问哪些属性,并且据我所知,应该不会遇到初始情况。

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

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

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

(或使用属性初始化let c = 0 ),但我想了解为什么编译器有问题的第一个例子。 我错过了什么,或者是不必要的限制?

Swift由于两阶段初始化而具有这种行为。 从苹果的Swift书中:

Swift中的类初始化是一个两阶段的过程。 在第一阶段,每个存储的属性由引入它的类来分配一个初始值。 一旦确定了每个存储属性的初始状态,第二阶段开始,并且每个类都有机会在新实例被认为准备好使用之前进一步定制其存储的属性。

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

Objective-C没有这样的行为,因为它可以总是给出0作为基元的默认值,对于nil来说是nil的,但是在Swift中没有给出这种默认值的机制。