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 回答
2
didSet
在init
. 您可以将赋值包装在defer { ... }
语句中以强制didSet
调用。
例如:
init(radius r: Double) {
defer { radius = r }
}
如果您希望默认半径为0
,我建议您使用默认参数值,radius
如下所示:
init(radius r: Double = 0) {
defer { radius = r }
}
...这样您就可以避免使用两个 init 方法,并且仍然将 a 初始化Circle
为Circle()
( radius = 0
) 和Circle(radius: 3)
( radius = 3
)。
于 2017-09-08T22:12:17.747 回答
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 { }
.
于 2017-09-08T22:11:39.230 回答