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 回答