努力理解 Swift 3 用非可失败初始化器覆盖可失败初始化器
Struggling to Understand Swift 3 Overriding of Failable Initialisers with Nonfailable Initialisers
我正在尝试学习覆盖 swift 中的失败初始化程序的概念,并且遇到了以下语句:
the only way to delegate up to the superclass initializer is to
force-unwrap the result of the failable superclass initializer.
课本上没有提供任何代码来真正解释它的真正含义?有人可以向我解释一下吗?如果附带代码示例就更好了!
不得不承认,"Overriding a Failable Initialiser" 部分相当混乱。
下面的示例应该可以阐明这种情况:
假设,你有一个基础 class 和一个失败的初始化器:
class Base {
let name: String
init?(name: String) {
guard !name.isEmpty else {
return nil
}
self.name = name
}
}
请注意,初始化失败 returns 可选。
在这里,初始化器要求你传递一个非空字符串,否则初始化器"fails"——也就是说,它returns一个可选的,其值为nil
(分别为.None
).
现在,让我们定义一个派生自 Base
的 class。在第一个版本中,这将无法编译,很难!
class Derived: Base {
let age: Int
init(name: String, age: Int) {
self.age = age
super.init(name: name) //<- error
}
}
编译器发出以下错误:
error: a non-failable initializer cannot chain to failable initializer 'init(name:)' written with 'init?'
super.init(name: name)
^
这里的问题是,subclass 的非失败初始化器委托给失败的基础 class 初始化器。
我们有两个选项来解决这个问题:
1。强制展开可失败的初始化程序:
class Derived: Base {
let age: Int
init(name: String, age: Int) {
self.age = age
super.init(name: name)! // <- force unwrap
}
}
此解决方案的警告是,如果您将空的 name
传递给 subclass 初始化程序,例如
let derived = Derived(name: "", age: 12)
在尝试强制从基础 class 初始化器中解包可选时会导致致命错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
2. 使 subclass 初始化程序也可失败:
class Derived: Base {
let age: Int
init?(name: String, age: Int) { // use failable initialiser
self.age = age
super.init(name: name) // <- propagate the failure with init?
}
}
此解决方案只是将 nil
结果从基础 class 初始化器传播到调用者 - 这使得调用者负责适当地处理可选。
我正在尝试学习覆盖 swift 中的失败初始化程序的概念,并且遇到了以下语句:
the only way to delegate up to the superclass initializer is to force-unwrap the result of the failable superclass initializer.
课本上没有提供任何代码来真正解释它的真正含义?有人可以向我解释一下吗?如果附带代码示例就更好了!
不得不承认,"Overriding a Failable Initialiser" 部分相当混乱。
下面的示例应该可以阐明这种情况:
假设,你有一个基础 class 和一个失败的初始化器:
class Base {
let name: String
init?(name: String) {
guard !name.isEmpty else {
return nil
}
self.name = name
}
}
请注意,初始化失败 returns 可选。
在这里,初始化器要求你传递一个非空字符串,否则初始化器"fails"——也就是说,它returns一个可选的,其值为nil
(分别为.None
).
现在,让我们定义一个派生自 Base
的 class。在第一个版本中,这将无法编译,很难!
class Derived: Base {
let age: Int
init(name: String, age: Int) {
self.age = age
super.init(name: name) //<- error
}
}
编译器发出以下错误:
error: a non-failable initializer cannot chain to failable initializer 'init(name:)' written with 'init?'
super.init(name: name)
^
这里的问题是,subclass 的非失败初始化器委托给失败的基础 class 初始化器。
我们有两个选项来解决这个问题:
1。强制展开可失败的初始化程序:
class Derived: Base {
let age: Int
init(name: String, age: Int) {
self.age = age
super.init(name: name)! // <- force unwrap
}
}
此解决方案的警告是,如果您将空的 name
传递给 subclass 初始化程序,例如
let derived = Derived(name: "", age: 12)
在尝试强制从基础 class 初始化器中解包可选时会导致致命错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
2. 使 subclass 初始化程序也可失败:
class Derived: Base {
let age: Int
init?(name: String, age: Int) { // use failable initialiser
self.age = age
super.init(name: name) // <- propagate the failure with init?
}
}
此解决方案只是将 nil
结果从基础 class 初始化器传播到调用者 - 这使得调用者负责适当地处理可选。