Почему не сработал?
Во многих примерах didSet
Я вижу на SO, этот код вернется 0
Однако я не могу заставить его возвращать что-либо кроме исходного значения. Что я делаю неправильно?
стриж
struct Circle {
var radius: Double {
didSet {
if radius < 0 {
radius = 0
}
}
}
}
var circ = Circle(radius: -25)
print(circ.radius)
Выход
-25
5 ответов
didSet
не вызывается во время инициализации, только после. Если вы хотите проверить данные во время инициализации, ваш инициализатор должен это сделать.
Если вы добавите:
circ.radius = -50
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 }
}
}
Как пишет Пол в комментариях наблюдателей за недвижимостью 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
Также вы можете использовать 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
}
}
Используйте для этого 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