In many examples of didSet I see on SO, this code will return 0, however, I can't get it to return anything other than the original value. What am I doing wrong?
Swift
struct Circle {
    var radius: Double {
        didSet {
            if radius < 0 {
                radius = 0
            }
        }
    }
}
var circ = Circle(radius: -25)
print(circ.radius)
Output
-25
didSet isn't called during initialization, only afterwards. If you want to validate data during initialization, your initializer should do it.
If you add:
circ.radius = -50
print(circ.radius)
you'll see it working as you'd expect, and the output will be 0.0.
You can make sure didSet in the init, if you put it in a defer statement. Also works in deinit. 
class Circle {
    var radius: Double {
       didSet {
          if radius < 0 {
             radius = 0
          }
       }
    }
    init(radius: Double) {
        defer { self.radius = radius }
    }
}
As written by Paul in the comments, property observers didSet and willSet are not called during value initialization. 
If you want to call them for a value also on initialization, you could add a function call to re-set the radius property after it has been initially set in the initializer:
struct Circle {
    var radius: Double {
        didSet {
            if radius < 0 {
                radius = 0
            }
        }
    }
    init(radius: Double) {
        self.radius = radius
        setRadius(radius) // <-- this will invoke didSet
    }
    mutating func setRadius(radius: Double) {
        self.radius = radius
    }
}
var circ = Circle(radius: -25)
print(circ.radius) // 0.0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With