You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让带any关键字的协议遵循Equatable协议?

Swift自定义协议遵循Equatable的常见问题解决

问题根源

你遇到的报错本质是Equatable协议依赖Self类型一致性,而any ExampleDataProtocol是经过类型擦除的存在类型,编译器无法保证两个any ExampleDataProtocol实例的具体类型相同,因此无法直接应用Equatable的比较逻辑。

你原代码里的两个问题:

  1. 结构体SomeStruct无法自动合成Equatable实现:因为属性是存在类型,编译器不知道如何生成比较逻辑。
  2. 手动实现==时直接比较any ExampleDataProtocol实例:存在类型本身不满足Equatable的Self类型要求,编译器拒绝执行比较。

另外你给协议扩展添加的static func ==(lhs: any ExampleDataProtocol, rhs: any ExampleDataProtocol)是多余的,Equatable协议只要求实现static func ==(lhs: Self, rhs: Self),这个any参数的方法不属于协议要求,反而会造成混淆。

解决方案

步骤1:修正协议定义与扩展

先去掉多余的any参数==方法,只保留符合Equatable要求的Self版本:

protocol ExampleDataProtocol: Equatable {
    var someData: Int { get set }
}

public extension ExampleDataProtocol {
    static func ==(lhs: Self, rhs: Self) -> Bool {
        return lhs.someData == rhs.someData
    }
}

步骤2:手动实现结构体的Equatable逻辑

在结构体的==方法中,先判断两个any ExampleDataProtocol实例的具体类型是否一致,再强转后调用协议的比较方法:

struct SomeStruct: Equatable {
    var someData: any ExampleDataProtocol
    
    static func == (lhs: SomeStruct, rhs: SomeStruct) -> Bool {
        // 先检查两个实例的具体类型是否相同
        guard let rhsMatchingType = rhs.someData as? type(of: lhs.someData) else {
            return false
        }
        // 类型一致后,调用协议的==方法比较
        return lhs.someData == rhsMatchingType
    }
}

补充说明

这种实现严格遵循Equatable的语义:只有当两个SomeStruct中的someData是同一具体类型,且属性值相等时,才判定两个SomeStruct实例相等。如果需要放宽类型要求(比如不同类型但someData值相同就判定相等),可以直接比较someData的属性值,但这不符合常规的Equatable语义,需要谨慎使用:

static func == (lhs: SomeStruct, rhs: SomeStruct) -> Bool {
    return lhs.someData.someData == rhs.someData.someData
}

内容的提问来源于stack exchange,提问作者Mocha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 13:47:25