![](/img/trans.png)
[英]Why Comparable protocol does not have default implementation of Equatable?
[英]Why does the following protocol have this required function?
在WWDC 2015上提到了以下代码:
protocol Drawable {
func isEqualTo(other: Drawable) -> Bool
func draw()
}
extension Drawable where Self : Equatable {
func isEqualTo(other: Drawable) -> Bool {
if let o = other as? Self { return self == o }
return false
}
}
在整个协议扩展方面,我有些困惑。 他们为什么在Drawable
协议中具有isEqualTo(other: Drawable) -> Bool
,然后仅在self
等于时才扩展? 为什么isEqualTo
是所有Drawable对象的必需方法? 在我看来,如果新的类/结构未实现Equatable
,则对象将无法通过逻辑检查是否相等,因此它们将无法实现equatable方法。 我认为将其作为可选实现会更有意义。 我的逻辑错在哪里?
解决的问题是泛型的局限性。
假设我们有一个Bird结构和Insect结构。 通用的等式表让我们定义==
,其中实际对象类型是相同类型。 因此,我们可以使Bird采用Equatable,以便如果我们将b1
和b2
都键入为Bird,则可以决定它们是否相等。 并且我们可以使昆虫采用“相等的”,以便如果我们将i1
和i2
都键入为昆虫,则可以确定它们是否相等。
但是现在假设Bird和Insect都采用Flier协议。 您不能让Flier采用Equatable,因为泛型的工作方式受到限制。 因此,如果将两个对象键入为Flier,则无法实现它们的等效性。
视频演示了协议扩展解决了此问题。 通过Flier上的协议扩展,您可以定义一个不同的方法来比较两个Flier,并确定它们是否相等-即,首先确定它们是否属于同一类,然后应用==
。 因此,您可以理解Flier(协议)的等效性。
我只能猜测为什么isEqualTo:
是可绘制协议的必需方法。 也许,无论绘制这些东西是什么,都不会浪费时间绘制相同的东西两次?
但是,我可以对此进行评论。
Equatable
是一种Swift协议(在Objective-C中不可用),该协议要求为该类型定义一个==
运算符。
在Objective-C中,没有运算符重载。 此外,在Objective-C中,使用==
比较对象只是比较它们的指针。 如果对象是同一对象(相同的内存位置),则==
返回true。 如果要查看对象是否是不同的对象但仍被视为相等,则必须使用isEqualTo:
这是NSObject
定义的方法,默认实现只是返回==
比较的结果。 但是类往往会覆盖它。
在Swift中, ==
具有不同的行为。 在Swift中, ==
返回的行为类似于我们期望isEqualTo:
方法在Objective-C中的行为。 这是因为Swift具有===
运算符,用于比较引用。 如果这些对象相同 (相同的内存位置),则===
返回true,但是==
是一种自定义实现的方法,该方法确定即使对象位于不同的内存位置,这些对象是否也相等。
因此,我猜想Drawable
协议在将isEqualTo:
声明为其必需的方法之一时,会记住Objective-C类。
我们也可以这样写Drawable
协议:
protocol Drawable: Equatable {
func draw()
}
从严格的Swift角度来看,这是大致等效的协议定义。 但这意味着使用Drawable
对象的人都希望在Swift中将它们与==
进行比较,而不是isEqualTo:
而且,这意味着如果我们想在协议中使用任何Objective-C定义的对象,现在我们必须为它们中的每个实现一个自定义==
函数,这很可能看起来像这样:
func == (left ObjCClass, right ObjCClass) -> Bool {
return left.isEqualTo(right)
}
但是,我们必须对每个要定义为Drawable
Objective-C类进行此操作。
替代方法是使用isEqualTo:
定义您的协议,该协议非常常见,是一种Objective-C方法。
现在,要使我们所有的Swift类型都符合Drawable
,我们要做的就是实现draw()
方法并符合Equatable
。 只要我们符合Equatable
,扩展名就会将isEqualTo:
方法添加到我们的Swift类型中,作为有效的简单return left == right
(并且Equatable
协议保证了==
方法的存在)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.