Swift文档说,
“您可以使用不可失败的初始化程序来覆盖可失败的初始化程序,但反之则不能。”
有人可以解释为什么失败的初始化程序不能覆盖失败的初始化程序吗?
答案 0 :(得分:2)
失败的初始化程序将返回一个可选值。如果使用不可失败的初始化程序覆盖该值,则返回的是非可选值,编译器会将其包装在可选值中。反之亦然。当您的重写的初始值设定项返回nil
时,编译器应做什么?如何将其映射到不返回可选值的初始化程序中?
我的印象是,当您覆盖失败的 具有非失败初始化器的初始化器,返回值是non 可选,因此没有任何意义。
好吧,如果您在覆盖的类上调用init
,它将返回非可选的内容。要查看可选的返回值,您需要诱使Swift在基类上调用init
。
您如何做到的?这是一种方法:
class Foo {
var x: Int
required init?() {
x = 4
}
}
class Bar : Foo {
// required includes override automatically
required init() {
super.init()!
x = 5
}
}
let bar1 = (Bar.self).init() // this is equivalent to Bar()
let bar2 = (Bar.self as Foo.Type).init()
print(type(of: bar1)) // Bar
print(type(of: bar2)) // Optional<Foo>
print(type(of: bar2!)) // Bar
print(bar1.x) // 5
print(bar2!.x) // 5
注意::(Bar.self as Foo.Type).init()
返回了一个可选内容,即使它是使用不可失败的Bar
初始化程序创建的。
注意:我必须添加required
才能完成这项工作,而required
是自动override
。如果将Foo
的init设置为非失败,并将Bar
的init设置为失败,则会看到错误消息 Failable initializer'init()'不能覆盖非失败的初始化程序