我试图强制由 Int
支持的简单类型不会与其他 Int
混合。
假设您有以下类型别名:
typealias EnemyId = Int
typealias WeaponId = Int
我希望以下内容出现编译器错误:
var enemy: EnemyId = EnemyId("1")
enemy = WeaponId("1") // this should fail
我想要失败的行应该失败,因为两种类型(EnemyId 和 WeaponId)是不同的类型。
实现这一目标的最好、最干净的方法是什么?
更新
查看答案和评论后,我想添加我使用枚举想到的内容:
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
}
}
然而,它给我的解析增加了几百毫秒,因此我不得不恢复到类型别名,但这非常接近我想要的。
最佳答案
请注意,在 Swift 4.1 中,像 Rob 和 Cristik 这样的包装结构建议编写起来变得微不足道,因为当您声明采用 Hashable 时,您将获得 hashValue
的自动合成实现和==
在幕后。
因此,为了您的目的,编写以下内容可能就足够了:
struct EnemyId: Hashable {
let value: Int
}
struct WeaponId: Hashable {
let value: Int
}
在这两种情况下,您都可以“免费”获得成员初始化器 init(value:)
加上 ==
加上 hashValue
。
关于swift - 你能在 swift 中强制执行类型别名吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48813776/