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

Swift如何定义协议约束枚举next返回同类型并支持等值比较

错误原因

  • 原协议没有约束next的返回值与协议遵循者为同一类型:你声明的关联类型T没有添加T == Self的约束,编译器无法确认input.next的类型和target(类型为T)属于同一种类型,不满足==运算符的操作数类型要求
  • 缺少Equatable协议约束:==运算符仅对遵循Equatable协议的类型可用,原代码没有添加相关约束

解决方法

直接使用Swift内置的Self关键字(代表当前遵循协议的类型本身)声明next的返回值,同时让协议继承Equatable即可,完全不需要额外声明关联类型,代码更简洁:

protocol MySequenceProtocol: Equatable {
    // 强制next返回值为遵循协议的类型本身
    var next: Self { get }
}

你的两个枚举均为无关联值的枚举,Swift会自动合成Equatable的实现,不需要手动编写==方法,原有枚举代码无需改动。

修改后的完整可运行代码如下:

protocol MySequenceProtocol: Equatable {
    var next: Self { get }
}

enum Weekdays: MySequenceProtocol {
   case monday, tuesday, wednesday, thursday, friday, saturday, sunday
    
    var next: Weekdays {
        switch self {
        case .monday:
            return .tuesday
        default:
            return .monday
        }
    }
}

enum Months: MySequenceProtocol {
   case jan, feb, march
    
    var next: Months {
        switch self {
        case .jan:
            return .feb
        case .feb:
            return .march
        default:
            return .jan
        }
    }
}

func compareNext<T: MySequenceProtocol>(input: T, target: T) {
    if input.next == target {
        print("match")
    }
}

// 测试调用
compareNext(input: Weekdays.monday, target: .tuesday) // 输出 match
compareNext(input: Months.jan, target: .feb) // 输出 match

可选方案

如果你不想让协议强制继承Equatable,也可以把Equatable约束加在泛型函数上,写法如下:

// 协议不继承Equatable
protocol MySequenceProtocol {
    var next: Self { get }
}

// 函数泛型添加Equatable约束
func compareNext<T: MySequenceProtocol & Equatable>(input: T, target: T) {
    if input.next == target {
        print("match")
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 01:36:04