Swift 5.7中协议如何遵循Equatable?三种尝试均失败
在自定义协议中使用Equatable的正确方式
你遇到的三个错误各有明确原因,对应不同的解决方案:
错误原因分析与修复
变体A:协议作为类型需用any修饰
Swift 5.7及以后版本要求,当把协议作为存在类型(即容纳多种实现类型的容器)使用时,必须用any关键字标注。所以变体A的代码只需修改为变体B的写法,即可解决该错误。
变体B:C类需手动实现Equatable
报错“Type 'C' does not conform to protocol 'Equatable'”说明你的C类被要求遵循Equatable协议(比如你声明了class C: Equatable,或者将C实例放到了需要Equatable约束的集合中)。此时需要手动为C实现==方法,利用any Person的动态Equatable能力完成数组元素的比较:
protocol Person: Equatable { var name: String { get } } struct A: Person { var name = "John" } struct B: Person { var name = "Josh" } class C: Equatable { var persons: [any Person] = [A(), B()] static func == (lhs: C, rhs: C) -> Bool { guard lhs.persons.count == rhs.persons.count else { return false } // 利用any Person的动态派发,调用具体类型的==实现 for (left, right) in zip(lhs.persons, rhs.persons) { if left != right { return false } } return true } }
变体C:some Person只能表示单一具体类型
some Person是不透明类型,它只能代表某一种遵循Person协议的具体类型,无法同时容纳A和B的实例。如果你的数组只需要存放同一种Person实现(比如全是A),可以这样写:
class C { // 数组元素全为A类型,some Person会自动推导为A var persons: [some Person] = [A(), A()] }
如果需要容纳多种类型,some Person并不适用。
核心要点
- 当需要容纳多种协议实现类型时,使用
[any Person];若所在类型需遵循Equatable,手动实现对应的比较逻辑。 - 当数组仅需单一协议实现类型时,使用
[some Person]或直接用具体类型(如[A])。
内容的提问来源于stack exchange,提问作者JaSHin
相关产品推荐
相关产品推荐

