繁体   English   中英

为什么以下协议具有此必需功能?

[英]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,以便如果我们将b1b2都键入为Bird,则可以决定它们是否相等。 并且我们可以使昆虫采用“相等的”,以便如果我们将i1i2都键入为昆虫,则可以确定它们是否相等。

但是现在假设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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM