【发布时间】:2016-01-28 16:28:20
【问题描述】:
这是来自文档,Failable Initializers for Classes 部分:
class Product {
let name: String!
init?(name: String) {
self.name = name
if name.isEmpty { return nil }
}
}
if let bowTie = Product(name: "") {
// no need to check if bowTie.name == nil
print("The product's name is \(bowTie.name)")
}
这是这样描述的:
在上面的例子中,Product 类的 name 属性是 定义为具有隐式展开的可选字符串类型 (细绳!)。因为它是可选类型,这意味着名称 属性在被分配特定之前的默认值为 nil 初始化期间的值。这个 nil 的默认值又意味着 Product 类引入的所有属性都有一个 有效的初始值。因此,Product 的可失败初始化程序 可以在初始化器开始时触发初始化失败 如果它被传递一个空字符串,在分配一个特定的值之前 初始化器中的 name 属性。
看看最后一句话:
因此,Product 的可失败初始化程序 可以在初始化器开始时触发初始化失败 如果它被传递一个空字符串,在分配一个特定的值之前 初始化器中的 name 属性。
这不能从提供的代码中看出。在提供的代码中,可以看到在return nil部分之前已经发生了赋值,并且是String(非可选)或String? (可选)会起作用。
另一件事是,在提供的示例中,如果将其定义为常量,则使用隐式展开的可选项是没有意义的。常量必须在初始化完成之前初始化为默认值。
对此有任何想法,或者是否有人看到不提交雷达的理由?也许我错过了什么?我实际上有一个想法,为什么在这里使用隐式展开可选,但这是一个不好的例子。对我来说,这会更有意义:
class Product {
var name: String! //let is changed to var
init?(name: String) {
if name.isEmpty { return nil } //Check here if passed value is non-empty
self.name = name
}
}
这样,可以在对name 属性进行任何分配之前触发初始化失败。
【问题讨论】:
-
请注意,在上一个示例中,Swift 将抱怨(编译时错误)属性
name在从失败的初始化程序返回nil之前尚未初始化。 name 编辑为可变对象之后不再 :) -
@dfri 你确定吗?名称被声明为 var(并且隐式展开为可选),因此它可以工作。
-
@Whirlwind 请注意我对评论的编辑:在您将
name从不可变更改为可变之前,它考虑了您的示例。 -
@dfri 是的,是的。我知道 :) 我没有立即注意到编辑。
标签: ios swift initializer failable