无法声明Swift隐式解包可选作为常量

时间:2015-04-29 23:58:58

标签: swift

这是来自 swift编程语言 ibook的代码示例:

class Product {
    let name: String!

    init?(name:String) {
        if name.isEmpty { return nil }
        self.name = name
    }
}

除非将name声明为变量而不是常量,否则它不起作用。是否已在Swift 1.2中引入了有关此问题的更改,我不知道?

1 个答案:

答案 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或继承的复杂性。)