谁能阐明为什么这行不通?我收到错误消息Binary operator '==' cannot be applied to operands of type 'Self' and 'CustomEquatable'
protocol CustomEquatable {
func isEqualTo(_ other: CustomEquatable) -> Bool
}
extension CustomEquatable where Self: Equatable {
func isEqualTo(_ other: CustomEquatable) -> Bool {
return self == other
}
}
答案 0 :(得分:2)
让我们从您的CustomEquatable
协议开始,不带扩展名:
protocol CustomEquatable { func isEqualTo(_ other: CustomEquatable) -> Bool }
让我们定义一些用于实验的类型:
struct A: Equatable {
let name: String
}
struct B: Equatable {
let id: Int
}
假设我们然后希望A
和B
符合CustomEquatable
。然后我们要考虑四种情况:
a1.isEqualTo(a2)
是什么意思(其中a1
和a2
均为A
类型)?b1.isEqualTo(b2)
是什么意思(其中b1
和b2
均为B
类型)?a.isEqualTo(b)
是什么意思(其中a
是A
,而b
是B
)?b.isEqualTo(a)
是什么意思(其中b
是B
,而a
是A
)?对于前两种情况,可能的答案是:a1.isEqualTo(a2)
为a1 == a2
,仅当b1.isEqualTo(b2)
为b1 == b2
。
对于后两种情况,我们必须确定A
是否等于B
的方法。我认为最简单的解决方案是A
永远不能等于B
。
所以我们可以这样写一致性:
extension A: CustomEquatable {
func isEqualTo(_ other: CustomEquatable) -> Bool {
return (other as? A) == self
}
}
extension B: CustomEquatable {
func isEqualTo(_ other: CustomEquatable) -> Bool {
return (other as? B) == self
}
}
这两个一致性的唯一区别是强制转换类型(在as?
的右侧)。因此我们可以将符合性分解为协议扩展,如下所示:
extension CustomEquatable where Self: Equatable {
func isEqualTo(_ other: CustomEquatable) -> Bool {
return (other as? Self) == self
}
}
通过此协议扩展,我们可以使A
和B
符合CustomEquatable
,而无需为每个实现isEqualTo
:
extension A: CustomEquatable { }
extension B: CustomEquatable { }
要测试代码:
let a1 = A(name: "a1")
let a2 = A(name: "a2")
let b1 = B(id: 1)
let b2 = B(id: 2)
a1.isEqualTo(a1) // true
a1.isEqualTo(a2) // false
b1.isEqualTo(b1) // true
b1.isEqualTo(b2) // false
a1.isEqualTo(b1) // false
b1.isEqualTo(a1) // false
答案 1 :(得分:1)
请从37:25开始观看WWDC 2015 Protocol-Oriented Programming in Swift
这几乎是从视频中摘录的。您必须将other
有条件下调到Self
。
如果类型相同,则可以使用==
,否则两个对象都不相等。
protocol CustomEquatable {
func isEqualTo(_ other: CustomEquatable) -> Bool
}
extension CustomEquatable where Self: Equatable {
func isEqualTo(_ other: CustomEquatable) -> Bool {
if let other = other as? Self { return self == other }
return false
}
}