首页 > 解决方案 > Swift 在协议上具有可比性

问题描述

祝大家新年快乐

protocol Birthday {
    var date: Date { get set }
}
    
class Person: Birthday {
    var date: Date
    var fullName: String

    // ...
}

class Car: Birthday {
    var date: Date
    var color: UIColor

    // ...
}

我希望这符合Comparable,所以我可以做到

Person() > Car()

代替

Person().date > Car().date

我怎样才能做到这一点?太感谢了

标签: swiftprotocolscomparable

解决方案


你可以做的>微不足道。只需编写以下顶级函数:

func > (lhs: Birthday, rhs: Birthday) -> Bool { lhs.date > rhs.date }

但是您不能将生日与可比较。Comparable 要求类型实现以下内容:

static func < (lhs: Self, rhs: Self) -> Bool

Self是符合协议的类型。协议不符合自己。它们不是“类型”。它们描述类型。(在某些情况下,可能会生成一个隐式存在类型,但在 Swift 中无法操作存在类型。)为了具有可比性,一个类型必须能够将自己与另一个相同类型的事物进行比较,而您无法通过协议。

但是您可以使用您的协议创建任何特定的语法。您只需要编写函数。

虽然这里有一个技术限制(协议不符合自己),即使 Swift 语法可以支持符合自己的协议(并且将来会有一些方法),你仍然不应该以这种方式实现 Comparable。Comparable 需要 Equatable。一个人永远不能等同于一辆汽车。那是因为 Equatable 需要的不仅仅是一个==函数。它需要可替代性。如果两件事在 Equatable 意义上是“平等​​的”,那么系统总是可以用一个代替另一个,而你永远不会关心它给了你哪一个。对于人和汽车来说,情况并非如此。

为避免此类问题,不建议<在此处使用。这意味着这些东西只有一个合理的顺序,而“生日”并不是这些东西的唯一顺序。因此,如果您想比较日期,我绝对建议您明确并比较日期。


推荐阅读