当我学习语言时,我正在通过学习 - 快速操场并将其升级到Swift 2.0.下面的代码(可能与之前版本的Swift一起工作)现在产生两个错误:"在初始化所有存储属性之前使用'self'"和在初始化之前使用"Constant'self.capitalCity"
class Country { let name: String let capitalCity: City! init(name: String, capitalName: String) { self.name = name self.capitalCity = City(name: capitalName, country: self) } } class City { let name: String unowned let country: Country init(name: String, country: Country) { self.name = name self.country = country } }
阅读类似问题的答案我看到我可以改为let capitalCity: City!
,var capitalCity: City!
语法错误得到解决.
我意识到,在这个人为的例子中,一个国家的首都可以改变,所以这样会很好,但如果有一个案例的价值确实是一个常数......
有没有办法解决语法错误,同时保持capitalCity不变?
在这种情况下,我建议你通过计算属性使属性变为变量但隐藏它(使它看起来像一个常量):
class Country { let name: String private var _capitalCity: City! var capitalCity: City { return _capitalCity } init(name: String, capitalName: String) { self.name = name self._capitalCity = City(name: capitalName, country: self) } }
有没有办法在保持
capitalCity
常量的同时解决语法错误?
不是你设置的方式.问题的根源实际上是为了设置capitalCity
,你必须创建一个城市,其country
是self
.这是self
编译器反对的用法:
self.capitalCity = City(name: capitalName, country: self) ^^^^
由于您已将City的配置country
为常量,因此在初始化City时必须提供此值.因此你没有出路; 你必须做capitalCity
一个可选的,var
以便它有一些合法的其他初始值,即nil
.您提出的解决方案实际上是这样的:
class Country { let name: String var capitalCity: City! = nil // implicit or explicit init(name: String, capitalName: String) { self.name = name // end of initialization! // name is set (to name), and capitalCity is set (to nil)... // ... and so the compiler is satisfied; // now, we _change_ capitalCity from nil to an actual City, // and in doing that, we _are_ allowed to mention `self` self.capitalCity = City(name: capitalName, country: self) } }