这编译得很好:
class Foo {
var number = 0
var name: String
init(name: String){ self.name = name }
}
class SubFoo: Foo {
init(_ x: Int){
super.init(name: "abc")
}
var a: Int {
set {}
get {
return 0
}
}
}
a
是一个计算属性,因此不需要初始化。
但这不编译:
class SubFoo: Foo {
init(_ x: Int){
super.init(name: "abc")
}
var a: Int {
willSet {}
didSet {
print(oldValue)
}
}
}
SubFoo init 方法显示了这一点:
error: property 'self.a' not initialized at super.init call super.init(name: "sdf")
a
仍然不是“真正的”属性,那么编译器在这里究竟期望什么?
奇怪的是我可以通过这样做来消除错误:
init(_ x: Int){
a=0
super.init(name: "sdf")
}
为什么 willSet
需要 a=0
而不是普通的 set
?
最佳答案
虽然 willSet
和 didSet
出现在属性后面的括号中,类似于计算方法 get
和 set
,他们不是指计算属性行为。 willSet
和 didSet
作用于存储的属性。这也是为什么您可以为它们提供默认值,但不能为 get/set
提供默认值的原因:
var a: Int = 6 { // this line would not compile for a computed property
willSet {
}
didSet {
print(oldValue)
}
}
这就是 init
中编译器错误的原因——没有对存储的属性进行初始化。
关于swift - 为什么 will/didSet 会触发初始化错误,而不是常规的 set/get?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44487035/