“Protocol ... can only be used as a generic constraint because it has Self or associated type requirements” 的意思是什么?

134

我正在尝试创建一个基于Swift中自定义协议(实际上是HashSet)的字典,但它给出了标题中的错误:

因为它有Self或相关类型要求,所以协议'myProtocol'只能用作泛型约束条件

但我无法理解这句话。

protocol Observing: Hashable { }

var observers = HashSet<Observing>()

@jtbandes 这不是重复问题。我想知道错误信息实际上是什么意思。什么是“Self或关联类型要求”? - devios1
2个回答

103

协议 Observing 继承自协议 Hashable,后者又继承自协议 Equatable。协议 Equatable有以下要求:

func ==(lhs: Self, rhs: Self) -> Bool

如果一个协议中包含Self,那么它只能在类型约束中使用。

这里有一个类似的问题。


8
因为编译器必须确保两边是相同的类型,但协议只需确保满足合同。我明白了。尽管如此,似乎Equatable不一定意味着Equatable,因为这并不是生成哈希码所必需的。 - devios1
4
哦,等等,它确实需要,因为“字典”需要能够知道给定的对象是否确实是正确的键,因为两个不同的对象可能会生成相同的哈希码。嗯,这有点棘手。所以这里的问题实际上是出在“可判等性”。 - devios1
6
看一下Alexis Gallagher在精彩演讲中的0:56部分,题目是“具有相关类型的协议及其实现方式(或许)”。链接:https://youtu.be/XWoNjiSPqI8。 - finneycanhelp
@finneycanhelp 谢谢你分享这个。很棒的视频! - devios1
3
Swift 是我见过的设计最糟糕的编程语言之一。 - user187676

12
为了解决这个问题,您可以使用泛型。考虑以下示例:
class GenericClass<T: Observing> {
   var observers = HashSet<T>()
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接