为什么 didSet 不起作用?
Why doesn't didSet work?
在许多 didSet
的示例中,我在 SO 上看到,此代码将 return 0
,但是,除了原始值。我做错了什么?
Swift
struct Circle {
var radius: Double {
didSet {
if radius < 0 {
radius = 0
}
}
}
}
var circ = Circle(radius: -25)
print(circ.radius)
输出
-25
didSet
不会在初始化期间调用,只会在之后调用。如果您想在初始化期间验证数据,您的初始化程序应该这样做。
如果您添加:
circ.radius = -50
print(circ.radius)
您会看到它按预期工作,输出将是 0.0
。
正如 Paul 在评论中所写,属性 观察者 didSet
和 willSet
在值初始化期间不会被调用。
如果你想在初始化时也调用它们来获取值,你可以添加一个函数调用来重新设置 radius
属性 在初始化程序中初始设置后:
struct Circle {
var radius: Double {
didSet {
if radius < 0 {
radius = 0
}
}
}
init(radius: Double) {
self.radius = radius
setRadius(radius) // <-- this will invoke didSet
}
mutating func setRadius(radius: Double) {
self.radius = radius
}
}
var circ = Circle(radius: -25)
print(circ.radius) // 0.0
你可以确保 didSet
在 init
中,如果你把它放在 defer
语句中。也适用于 deinit
。
class Circle {
var radius: Double {
didSet {
if radius < 0 {
radius = 0
}
}
}
init(radius: Double) {
defer { self.radius = radius }
}
}
为此使用初始化:
struct Circle {
var radius: Double
init(radius: Double) {
self.radius = radius < 0 ? 0 : radius
}
}
var circ = Circle(radius: -25)
print(circ.radius)
0.0
你也可以使用 lazy 和 init(radius ....
struct Circle {
lazy var radius: Double = 0.0 {
didSet {
print("didSet called")
if radius < 0 {
radius = 0
}
}
}
init(radius:Double) {
self.radius = radius
}
}
在许多 didSet
的示例中,我在 SO 上看到,此代码将 return 0
,但是,除了原始值。我做错了什么?
Swift
struct Circle {
var radius: Double {
didSet {
if radius < 0 {
radius = 0
}
}
}
}
var circ = Circle(radius: -25)
print(circ.radius)
输出
-25
didSet
不会在初始化期间调用,只会在之后调用。如果您想在初始化期间验证数据,您的初始化程序应该这样做。
如果您添加:
circ.radius = -50
print(circ.radius)
您会看到它按预期工作,输出将是 0.0
。
正如 Paul 在评论中所写,属性 观察者 didSet
和 willSet
在值初始化期间不会被调用。
如果你想在初始化时也调用它们来获取值,你可以添加一个函数调用来重新设置 radius
属性 在初始化程序中初始设置后:
struct Circle {
var radius: Double {
didSet {
if radius < 0 {
radius = 0
}
}
}
init(radius: Double) {
self.radius = radius
setRadius(radius) // <-- this will invoke didSet
}
mutating func setRadius(radius: Double) {
self.radius = radius
}
}
var circ = Circle(radius: -25)
print(circ.radius) // 0.0
你可以确保 didSet
在 init
中,如果你把它放在 defer
语句中。也适用于 deinit
。
class Circle {
var radius: Double {
didSet {
if radius < 0 {
radius = 0
}
}
}
init(radius: Double) {
defer { self.radius = radius }
}
}
为此使用初始化:
struct Circle {
var radius: Double
init(radius: Double) {
self.radius = radius < 0 ? 0 : radius
}
}
var circ = Circle(radius: -25)
print(circ.radius)
0.0
你也可以使用 lazy 和 init(radius ....
struct Circle {
lazy var radius: Double = 0.0 {
didSet {
print("didSet called")
if radius < 0 {
radius = 0
}
}
}
init(radius:Double) {
self.radius = radius
}
}