协议扩展初始化程序强制调用 self.init
Protocol Extension Initializer forcing to call self.init
我刚刚阅读了 Apple Swift 4 有关协议初始化程序要求并在协议扩展中提供默认实现的文档。
import UIKit
protocol Protocol {
init()
}
extension Protocol {
init() {
print("SDf")
self.init() // Line 1
// Compiler error occured if this is omitted
//"'self.init' isn't called on all paths before returning from initializer"
}
}
struct Structure: Protocol {
init(string: String) {
}
}
Structure() // Line 2
现在如您所见,执行将进入循环,因为默认情况下该结构没有 init()
的实现,因此将调用提供的协议 init 并调用自身再次,所以它进入无限循环。
现在,知道这一点后,如果我删除第 1 行,编译器会给出错误。
问。为什么它强制我在第 1 行使用 self.init()
,我该如何摆脱这种情况?
考虑这个例子:
protocol P {
init()
}
extension P {
init() {
} // error: 'self.init' isn't called on all paths before returning from initializer
}
struct S : P {
var str: String
}
let s = S()
print(s.str)
假设它已编译——我们可以创建一个 S
值,而无需为 str
属性 提供值。这就是编译器抱怨 init()
的协议扩展实现没有调用 self.init
的原因。它需要你链接到 一些其他 初始化程序要求——一个你没有为其提供默认实现的要求(否则你可能会进入递归循环,正如你发现的那样),因此采用类型需要实现的一个,以便它可以完全初始化自己。
例如,这是合法的:
protocol P {
init()
init(str: String)
}
extension P {
init() {
self.init(str: "some default")
}
}
struct S : P {
var str: String
}
let s = S()
print(s.str) // some default
因为现在我们链接到 init(str:)
要求,S
必须 实施(在这种情况下,implicit memberwise initialiser).
我刚刚阅读了 Apple Swift 4 有关协议初始化程序要求并在协议扩展中提供默认实现的文档。
import UIKit
protocol Protocol {
init()
}
extension Protocol {
init() {
print("SDf")
self.init() // Line 1
// Compiler error occured if this is omitted
//"'self.init' isn't called on all paths before returning from initializer"
}
}
struct Structure: Protocol {
init(string: String) {
}
}
Structure() // Line 2
现在如您所见,执行将进入循环,因为默认情况下该结构没有 init()
的实现,因此将调用提供的协议 init 并调用自身再次,所以它进入无限循环。
现在,知道这一点后,如果我删除第 1 行,编译器会给出错误。
问。为什么它强制我在第 1 行使用 self.init()
,我该如何摆脱这种情况?
考虑这个例子:
protocol P {
init()
}
extension P {
init() {
} // error: 'self.init' isn't called on all paths before returning from initializer
}
struct S : P {
var str: String
}
let s = S()
print(s.str)
假设它已编译——我们可以创建一个 S
值,而无需为 str
属性 提供值。这就是编译器抱怨 init()
的协议扩展实现没有调用 self.init
的原因。它需要你链接到 一些其他 初始化程序要求——一个你没有为其提供默认实现的要求(否则你可能会进入递归循环,正如你发现的那样),因此采用类型需要实现的一个,以便它可以完全初始化自己。
例如,这是合法的:
protocol P {
init()
init(str: String)
}
extension P {
init() {
self.init(str: "some default")
}
}
struct S : P {
var str: String
}
let s = S()
print(s.str) // some default
因为现在我们链接到 init(str:)
要求,S
必须 实施(在这种情况下,implicit memberwise initialiser).