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

hay*_*rdi 4 swift

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

class Product {
    let name: String!

    init?(name:String) {
        if name.isEmpty { return nil }
        self.name = name
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Air*_*ity 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 }
     }
}
Run Code Online (Sandbox Code Playgroud)

另请注意,结构不需要在失败之前初始化所有成员,只有类(可能是因为结构没有并发症deinit或继承).