这是来自 swift编程语言 ibook的代码示例:
class Product {
let name: String!
init?(name:String) {
if name.isEmpty { return nil }
self.name = name
}
}
除非将name声明为变量而不是常量,否则它不起作用。是否已在Swift 1.2中引入了有关此问题的更改,我不知道?
答案 0 :(得分:6)
这是由于1.2中的更改现在,在从类的可用初始化程序返回nil
之前,必须将所有属性设置为有效值。原因是,即使在初始化程序失败之后,类的deinit
仍然运行,并且对于正确的代码,它需要知道所有属性都是有效初始化的(还要记住该类可能是一个子类,并且继承类在其初始化程序失败后也可能依赖于属性的有效初始化。)
默认情况下,隐式解包的选项会初始化为nil
- 但前提是它们被声明为var
。如果使用let
声明它们,则它们是不可变的,因此只能初始化一次,因此不能以nil
开始,然后再更改。因此,var
版本有效,但let
版本无效。
注意,在最近对Swift书的更新中,代码略有不同 - 它首先初始化name
,然后失败:
class Product {
let name: String!
init?(name: String) {
self.name = name
if name.isEmpty { return nil }
}
}
另请注意,结构不需要在失败之前初始化所有成员,只有类(可能是因为结构没有deinit
或继承的复杂性。)