In our Coding Dojo, we're currently practicing Object Calisthenics. One of the rules is:
Wrap all primitives and strings (wrap primitive types in classes)
I'm practicing this on the "Greed is Good" kata, which is about scores from dice rolls.
Off course, I could model a diceroll as let roll = 5 // inferred to be Int
but this violates the mentioned rule.
I would prefer to have an actual DiceRoll type that acts like a number (i.e. so you can add them for instance), but also is limited to values 1...6.
I now have an enum representing this type:
enum DiceThrow {
case one
case two
case three
case four
case five
case six
init?(_ intValue: Int) {
switch intValue {
case 1:
self = .one
case 2:
self = .two
case 3:
self = .three
case 4:
self = .four
case 5:
self = .five
case 6:
self = .six
default:
return nil
}
}
}
My question is: is there a number type in Swift here I can limit the values to a specific range?
And if not, what is the best practice to represent something like this?
Ideally, I would have compiler support that does not let me express invalid values. I.e.: let roll = DiceRoll(7) // Compile error
But this is more of a 'bonus' than a necessity.
The best practice for representing what you now have is with a raw value, which does exactly the same as your initialiser even returning nil when you feed it a value out of range:
enum DiceThrow: Int {
case one = 1
case two
case three
case four
case five
case six
}
let roll = DiceThrow(rawValue: 7)