Почему оператор присваивания '=' не работает в моем операторе if в моем наблюдателе свойства didSet?
struct Circle {
// Properties
var radius: Double {
didSet {
if oldValue < 0 {
radius = 0
}
}
}
var area:Double {
get{
return Double.pi * pow(radius, 2)
}
}
var circumference: Double {
get {
return 2 * radius * Double.pi
}
}
init() {
radius = 0
}
init(radius r: Double) {
radius = r
}
}
// test circle
var testCircle = Circle()
print ("radius:", testCircle.radius, "area: ", testCircle.area, "circumference: ", testCircle.circumference)
var testCircle2 = Circle(radius: 2.5)
print("radius: ", testCircle2.radius, " area: ", testCircle2.area, "circumference: ", testCircle2.circumference)
var testCircle3 = Circle(radius: 20)
print("radius: ", testCircle3.radius, "area: ", testCircle3.area, "circumference: ", testCircle3.circumference)
var testCircle4 = Circle(radius: -4.5)
print("radius: ", testCircle4.radius, "area: ", testCircle4.area, "circumference: ", testCircle4.circumference)
2 ответа
didSet
во время init
, Вы можете обернуть задание в defer { ... }
заявление о силе didSet
быть названным.
Например:
init(radius r: Double) {
defer { radius = r }
}
Если вы хотите, чтобы радиус по умолчанию был 0
Я бы рекомендовал использовать значение параметра по умолчанию для radius
вот так:
init(radius r: Double = 0) {
defer { radius = r }
}
... таким образом вы избегаете использования двух методов init и по-прежнему инициализируете Circle
как Circle()
(radius = 0
) и в качестве Circle(radius: 3)
(radius = 3
).
Помните, didSet
вызывается после фактического изменения свойства oldValue
будет содержать предыдущее значение.
Вы хотите проверить, является ли новое значение отрицательным.
Обновите код до:
var radius: Double {
didSet {
if radius < 0 {
radius = 0
}
}
}
Вы хотите проверить, если radius
(последнее значение) отрицательно.
Вы также должны обновить свой init
метод:
init(radius r: Double) {
radius = r >= 0 ? r : 0
}
Это потому что didSet
а также willSet
не вызываются во время инициализации. Так что ваши init
Метод должен проверить параметр.
Как примечание может еще больше упростить ваш radius
а также circumference
свойства следующим образом:
var area:Double {
return Double.pi * pow(radius, 2)
}
Свойство компьютера только для чтения не нуждается в get { }
,