0
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)
4

2 回答 2

2

didSetinit. 您可以将赋值包装在defer { ... }语句中以强制didSet调用。

例如:

init(radius r: Double) {
    defer { radius = r }
}

如果您希望默认半径为0,我建议您使用默认参数值,radius如下所示:

init(radius r: Double = 0) {
    defer { radius = r }
}

...这样您就可以避免使用两个 init 方法,并且仍然将 a 初始化CircleCircle()( 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
}

这是因为在初始化期间didSetwillSet没有调用。所以你的init方法需要验证参数。

作为旁注可以进一步简化您的radiuscircumference属性,如下所示:

var area:Double {
    return Double.pi * pow(radius, 2)
}

只读计算机属性不需要get { }.

于 2017-09-08T22:11:39.230 回答