I am trying to enforce a simple type backed by an Int
does not get mixed up with other Int
s.
Say you have the following typealiases :
typealias EnemyId = Int
typealias WeaponId = Int
I would like the following to have a compiler error:
var enemy: EnemyId = EnemyId("1")
enemy = WeaponId("1") // this should fail
The line I want to fail, should fail, because the two types (EnemyId and WeaponId) are different types.
What would be the nicest, cleanest way of achieving this?
UPDATE
After reviewing the answers and comments, I wanted to add what I came up with using enums:
enum Enemy {
case id(Int)
var id: Int {
switch self {
case .id(let i):
return i
}
}
}
let enemy = Enemy.id(1)
print("enemy: \(enemy.id)")
Currently Mattt's answer is much shorter and more in line with what you expect in Swift.
UPDATE #2
I do not yet have access to swift 4.1 so I had to do the following:
struct EnemyId : Hashable {
private let value: Int
init(_ value: Int) {
self.value = value
}
init?(_ string:String) {
guard let value = Int(string) else { return nil }
self.init(value)
}
static func ==(_ lhs: EnemyId, _ rhs: EnemyId) -> Bool {
return lhs.value == rhs.value
}
var hashValue: Int {
return value.hashValue
}
}
It however turned out to add a couple of hundreds of milliseconds to my parsing, therefore I had to revert to the typealias, but it was very close to what I wanted.
Note that in Swift 4.1 wrapper structs like Rob and Cristik are suggesting become trivial to write, because when you declare adoption of Hashable, you get automatically synthesized implementations of hashValue
and ==
behind the scenes.
Thus, for your purposes, it might be sufficient to write:
struct EnemyId: Hashable {
let value: Int
}
struct WeaponId: Hashable {
let value: Int
}
You get the memberwise initializer init(value:)
plus ==
plus hashValue
"for free" in both cases.
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