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)
答案 0 :(得分: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
)
答案 1 :(得分:1)
请记住,在实际更改属性后调用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 { }
。