我正在使用 Swift 5.7 新功能,并且正在尝试实现一些异构集。
我已将代码简化为这个简单的游乐场:
protocol Stuff: Hashable {
var identifier: String { get }
}
struct StuffA: Stuff {
let identifier: String
func hash(into hasher: inout Hasher) {
hasher.combine(identifier)
}
}
struct StuffB: Stuff {
let identifier: String
func hash(into hasher: inout Hasher) {
hasher.combine(identifier)
}
}
var arrayOfStuff: Array<any Stuff> = []
arrayOfStuff.append(StuffA(identifier: "a"))
arrayOfStuff.append(StuffB(identifier: "b"))
// Works like a charm
var setOfStuff: Set<any Stuff> = Set()
// error: Type 'any Stuff' cannot conform to 'Hashable'
setOfStuff.insert(StuffA(identifier: "a"))
setOfStuff.insert(StuffB(identifier: "b"))
第一次尝试使用
Array<any Stuff>
显示 any
可以与协议一起使用来指定通用约束。
第二次尝试失败,因为 swift 无法检查 Hashable 一致性。我知道
Stuff
不符合Hashable,它只是继承。但是你如何告诉编译器 any Stuff
会符合要求呢?
问题是 Set 需要具体类型而不是“any”。目前这是 swift 令人沮丧的部分。您必须创建一个符合协议的类型,但仍然显式地使其符合单独的要求/协议?我最近在复杂的代码中遇到了同样的情况,这真是令人沮丧。基本上你必须创建一个符合你的协议和所需的“可哈希”的任意类型在我的例子中,我制作了一个 LineItem 包装器,它包装了“任何 LineItemRepresentable(我的协议)”并符合我不能只是通过要求协议支持来支持..