There are a cases where I might want to model data where it makes sense for a value to be restricted to a given range.
For example, if I want to represent a "mammal", I might want to restrict a legs
property to 0–4.
My first attempt is shown below:
class Mammal {
var _numLegs:Int?
var numLegs:Int {
get {
return _numLegs!
}
set {
if 0...4 ~= newValue {
self._numLegs = newValue
}
else {
self._numLegs = nil
}
}
}
}
However, this seems unsatisfactory since all properties are "public" there is nothing stopping the customer of the class from setting Mammal._numLegs
to some arbitrary value.
Any better ways to do it?
Just for fun I decided to write a snippet with @jackWu's suggestion (+1) in order to try that didSet
thing:
class Mammal {
var numLegs:UInt? {
didSet { if numLegs? > 4 { numLegs = nil } }
}
init() {
numLegs = nil
}
}
It works perfectly. As soon as you try to set numLegs to 5 or greater, boom, it gets nilled automatically. Please note that I used Uint to avoid negative leg quantities :)
I really like the elegance of didSet
.
In this specific case, you want a property observer
, you could implement it like this:
class Mammal {
init () {
numLegs = 0
super.init()
}
var numLegs:Int {
didSet: {
if !(numLegs ~= 0...4) {
numLegs = max(0,min(numLegs,4)) // Not sure if this is what you want though
}
}
}
}
Looking at this though, I'm not sure if this would recurse and call didSet
again...I guess it wouldn't be too bad because it would pass the check the second time
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