Reputation: 1
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)
Upvotes: 0
Views: 151
Reputation: 318814
Remember, didSet
is called after the property has actually been changed. oldValue
will contain the previous value.
You want to check if the new value is negative.
Update the code to:
var radius: Double {
didSet {
if radius < 0 {
radius = 0
}
}
}
You want to check if radius
(the latest value) is negative.
You also need to update your init
method:
init(radius r: Double) {
radius = r >= 0 ? r : 0
}
This is because didSet
and willSet
are not called during initialization. So your init
method needs to validate the parameter.
As a side note can further simplify your radius
and circumference
properties as follows:
var area:Double {
return Double.pi * pow(radius, 2)
}
A read-only computer property doesn't need the get { }
.
Upvotes: 1
Reputation: 5330
didSet
property observers aren't called during init
. You can wrap the assignment in a defer { ... }
statement to force didSet
to be called.
For example:
init(radius r: Double) {
defer { radius = r }
}
If you'd like the default radius to be 0
, I'd recommend using a default parameter value for radius
like so:
init(radius r: Double = 0) {
defer { radius = r }
}
...that way you avoid having two init methods and still initialize a Circle
as Circle()
(radius = 0
) and as Circle(radius: 3)
(radius = 3
).
Upvotes: 2