swift - 如何使用 Xcode 10 中可用的 API 使枚举符合 Hashable?
问题描述
在我的 Swift 4.2.1 代码中,我有这个枚举:
enum MyEnum {
case caseOne(Int)
case caseTwo(String)
case caseThree
}
它符合Equatable
:
extension MyEnum: Equatable {
static func == (lhs: MyEnum, rhs: MyEnum) -> Bool {
switch (lhs, rhs) {
case (.caseOne, .caseOne), (.caseTwo, .caseTwo), (.caseThree, .caseThree):
return true
default:
return false
}
}
}
我需要使其符合Hashable
,这就是我添加扩展名的原因:
extension MyEnum: Hashable {
var hashValue: Int {
switch self {
case .caseOne:
return 1
case .caseTwo:
return 2
case .caseThree:
return 3
}
}
}
现在我想迁移到 Xcode 10 中可用的新 API。我删除了我的实现hashValue
并添加了以下实现hash(into:)
:
extension MyEnum: Hashable {
func hash(into hasher: inout Hasher) {
switch self {
case .caseOne:
hasher.combine(1)
case .caseTwo:
hasher.combine(2)
case .caseThree:
hasher.combine(3)
}
}
}
您能否告诉我是否正确切换到新 API?我使用这个测试,如果一切正常,它会打印true
两次:
var testDictionary = [MyEnum: Int]()
testDictionary[.caseOne(100)] = 100
testDictionary[.caseOne(1000)] = 1000
testDictionary[.caseTwo("100")] = 100
testDictionary[.caseTwo("1000")] = 1000
let countCaseOne = testDictionary.reduce(0) {
if case .caseOne = $1.key {
return $0 + 1
}
return $0
} == 1
print(countCaseOne) // true
let countCaseTwo = testDictionary.reduce(0) {
if case .caseTwo = $1.key {
return $0 + 1
}
return $0
} == 1
print(countCaseTwo) // true
解决方案
您可以Hashable
按照另一个答案中的建议使用自动生成的一致性(在您的类型不包含任何非Hashable
类型日期的情况下)。
但这就是您在一般情况下可以做的事情(自动生成的代码也可能看起来像这样):
extension MyEnum: Hashable {
func hash(into hasher: inout Hasher) {
switch self {
case .caseOne(let value):
hasher.combine(value) // combine with associated value, if it's not `Hashable` map it to some `Hashable` type and then combine result
case .caseTwo(let value):
hasher.combine(value) // combine with associated value, if it's not `Hashable` map it to some `Hashable` type and then combine result
case .caseThree:
// you can `combine` with some `Hashable` constant, but here it's ok just to skip
break
}
}
}
推荐阅读
- reactjs - 使用路由器的 Codesplit 给出“init 不是函数”错误
- c++ - 无法从多个 UDP 设备接收数据
- javascript - 将对象值减去数组不正确
- python - 将嵌套 python 列表写入 csv 文件
- android - Android BLE:订阅多个特征通知
- r - 从多个文本文件创建一个 data.frame,其中行名作为 r 中的列
- python - Praw 阻止 subreddits
- atlassian-sourcetree - Sourcetree - 如何接受旧提交并将其强制置顶?
- laravel-backpack - 如何访问自定义(非 CRUD)页面上的背包字段?
- jestjs - 用 Vue3 错误开玩笑:无法解构“未定义”的属性“配置”,因为它是未定义的