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
相关产品推荐
相关产品推荐

