Scala中Ordered trait未提供equals方法,是否属于设计问题?
先直接给结论:这绝对不是设计缺陷,反而恰恰体现了Scala在类型系统和设计原则上的严谨性,咱们从几个角度唠明白:
职责分离,不搞一锅烩
Orderedtrait的核心职责就是处理排序相关的偏序比较(也就是<、<=这些用来定顺序的逻辑),而相等性判断(equals)属于等价关系的范畴,是Equalstrait的本职工作。把这俩拆开,完全符合单一职责原则——一个组件只聚焦一件事,避免把不相关的逻辑硬绑在一起。比如有些类型只需要排序但不需要自定义相等性,或者反过来,这种拆分能让代码更灵活,不会强制你做没必要的实现。偏序和等价关系本来就不是一回事
排序用的偏序关系,和判断相等的等价关系,逻辑上有本质区别。举个实际的例子:假设你有个Person类,按年龄排序,但两个年龄相同的人显然不能算同一个人。如果Ordered强制要求实现equals,就会把“排序时视为同序”和“逻辑上完全相等”这两个概念混在一起,很容易写出bug。灵活的组合方式,满足不同需求
如果你确实需要同时支持排序和自定义相等性,Scala完全给你留了口子——你可以同时混入Ordered和Equals,甚至基于compare方法来实现equals(但这是可选的,不是必须的)。比如:case class Person(name: String, age: Int) extends Ordered[Person] with Equals { override def compare(that: Person): Int = this.age.compareTo(that.age) // 按需实现equals:这里如果只看年龄相等,就这么写;如果要看name+age,就改逻辑 override def equals(obj: Any): Boolean = obj match { case that: Person => this.age == that.age case _ => false } }这种设计的好处就是,你完全可以根据业务需求来决定
equals的逻辑,而不是被排序逻辑绑架。对齐Java生态,兼顾兼容性
Java的Comparable接口也只定义了compareTo方法,没有强制要求equals。Scala的Ordered设计对齐了这一点,方便Scala和Java代码的互操作。要是强行在Ordered里加equals,反而会打破这种兼容性,徒增复杂度。
总的来说,这种设计是Scala权衡了职责分离、逻辑合理性和生态兼容性后的最优解,完全不是设计问题。
内容的提问来源于stack exchange,提问作者Mandroid

