在didSet
的许多示例中,我在SO上看到,此代码将返回0
,但是,我不能让它返回除原始值之外的任何内容。我做错了什么?
夫特
struct Circle {
var radius: Double {
didSet {
if radius < 0 {
radius = 0
}
}
}
}
var circ = Circle(radius: -25)
print(circ.radius)
输出
-25
答案 0 :(得分:13)
didSet
在初始化期间不会被调用,之后才会被调用。如果要在初始化期间验证数据,初始化程序应该这样做。
如果你添加:
circ.radius = -50
print(circ.radius)
您会看到它按预期工作,输出结果为0.0
。
答案 1 :(得分:4)
如果您将didSet
语句放入init
,则可以确保defer
中的deinit
。也适用于class Circle {
var radius: Double {
didSet {
if radius < 0 {
radius = 0
}
}
}
init(radius: Double) {
defer { self.radius = radius }
}
}
。
Traceback (most recent call last):
File "/usr/lib/python3.5/shelve.py", line 111, in __getitem__
value = self.cache[key]
KeyError: 'lb'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/discord/client.py", line 307, in _run_event
yield from getattr(self, event)(*args, **kwargs)
File "imgbot.py", line 85, in on_message
lead = getlb()
File "imgbot.py", line 75, in getlb
sortedlb = sortlb()
File "imgbot.py", line 50, in sortlb
utemp = ulbs['lb']
File "/usr/lib/python3.5/shelve.py", line 113, in __getitem__
f = BytesIO(self.dict[key.encode(self.keyencoding)])
KeyError: b'lb'
答案 2 :(得分:2)
正如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
答案 3 :(得分:0)
为此使用init:
struct Circle {
var radius: Double
init(radius: Double) {
self.radius = radius < 0 ? 0 : radius
}
}
var circ = Circle(radius: -25)
print(circ.radius)
0.0