【发布时间】:2018-07-23 02:13:36
【问题描述】:
我正在尝试强制执行由 Int 支持的简单类型不会与其他 Ints 混淆。
假设你有以下类型别名:
typealias EnemyId = Int
typealias WeaponId = Int
我希望以下出现编译器错误:
var enemy: EnemyId = EnemyId("1")
enemy = WeaponId("1") // this should fail
我想失败的那行,应该失败,因为这两种类型(EnemyId 和 WeaponId)是不同的类型。
实现这一目标最好、最干净的方法是什么?
更新
在查看了答案和 cmets 之后,我想添加我使用枚举想出的内容:
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)")
目前,Mattt 的答案要短得多,也更符合您对 Swift 的期望。
更新 #2
我还没有访问 swift 4.1,所以我必须执行以下操作:
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
}
}
然而,我的解析结果增加了几百毫秒,因此我不得不恢复到 typealias,但它非常接近我想要的。
【问题讨论】:
-
这看起来像
enum会更有用。这样,编译器可以防止您发生此类意外转换,您永远不必担心无效的敌人或武器类型,并且您可以使用Weapon.sword(在大多数情况下甚至是.sword)来引用值,而不必声明像WEAPON_SWORD这样的常量。 -
@NobodyNada 我也玩过枚举,但是预定义每个可能的 ID 是多余的。至少我无法找到令人满意的解决方案。