假设我有一个协议Item
,以及一个符合它的结构ConcreteItem
。
protocol Item {
var name: String { get }
}
struct ConcreteItem: Item {
let name: String
}
在某些时候,我希望有两套ConcreteItem
。
let set1 = Set([ConcreteItem(name: "item1")])
let set2 = Set([ConcreteItem(name: "item2"), ConcreteItem(name: "item1")])
我希望返回名为"item1"
的项目。
我可以ConcreteItem
符合Hashable
,Set
代码也可以使用。但是,让我说我也有以下内容:
struct AnotherConcreteItem: Item {
let name: String
}
我希望AnotherConcreteItem
仅仅因为符合Hashable
而符合Item
。
然而,当我尝试实现这个想法时:
extension Item: Hashable {
var hashValue: Int {
return name.characters.count
}
}
我收到以下错误:Extension of protocol 'Item' cannot have an inheritance clause
。
答案 0 :(得分:0)
协议扩展'Item'不能有继承子句
此处的项目是协议,因此符合Hashable
协议将无效。有关详细信息,请参阅here
答案 1 :(得分:0)
您尝试使用某些协议可能会做什么,但不是全部。如果您尝试遵循的协议没有任何关联类型或Self
,则可以这样做。
示例:
protocol A {
func foo()
}
protocol Item: A {
var name: String { get }
}
struct ConcreteItem: Item {
let name: String
}
extension Item {
func foo() {
}
}
符合Item
的所有内容也符合A
。
但是,Hashable
有Self
个约束。要符合Hashable
,您还必须符合Equatable
。为符合Equatable
,==
的实现必须在具体类中,而不是其他协议,因为Equatable
不能用作参数类型。你能做的最多就是这样:
protocol Item: Hashable {
var name: String { get }
}
struct ConcreteItem: Item {
let name: String
// you need to implement == in every concrete class
static func ==(lhs: ConcreteItem, rhs: ConcreteItem) -> Bool {
return ...
}
}
extension Item {
var hashValue: Int {
return name.characters.count
}
}