大家新年快乐
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
我该怎么做?非常感谢
答案 0 :(得分:2)
您可以轻松完成 >
。只需编写以下顶级函数:
func > (lhs: Birthday, rhs: Birthday) -> Bool { lhs.date > rhs.date }
但是您不能将生日与 Comparable 相匹配。 Comparable 要求类型实现以下内容:
static func < (lhs: Self, rhs: Self) -> Bool
Self
是符合协议的类型。协议不符合自身。它们不是“类型”。它们描述类型。 (在某些情况下,可能会生成隐式存在类型,但不能在 Swift 中操作存在类型。)为了具有可比性,类型必须能够将自身与相同类型的另一个事物进行比较,而你无法通过协议获得它。
但是您可以创建协议的任何特定语法。您只需要编写函数即可。
虽然这里有一个技术限制(协议不符合自己),即使 Swift 语法可以支持符合自己的协议(并且将来有办法),你仍然不应该以这种方式实现 Comparable . Comparable 需要 Equatable。一个人永远不能等同于一辆汽车。这是因为 Equatable 需要的不仅仅是 ==
函数。它需要可替代性。如果两件事在 Equatable 意义上是“相等的”,那么系统可以总是用一个替换另一个,而你永远不会关心它给了你哪一个。而对于人和汽车来说,情况就不是这样了。
为避免此类问题,不建议在此处使用 <
。这意味着这些东西只有一个合理的顺序,而“生日”并不是这些东西的唯一顺序。因此,如果您想比较日期,我绝对建议您直接比较日期。
答案 1 :(得分:0)
感谢@Rob Napier 的精彩回答。
我想添加一些东西 - 对于那些想要符合 Comparable
能够对数组进行排序的人,我写了这个扩展:
extension Array where Element: Birthday {
mutating func sort() {
sort(by: { $0.date < $1.date })
}
func sorted() -> [Element] {
return sorted(by: { $0.date < $1.date })
}
}