Scala中Ordering.by()与Ordering.on()的区别是什么?
Scala中Ordering.by()与Ordering.on()的区别
1. 定义位置差异
Ordering.by是Ordering伴生对象的静态方法,直接通过Ordering类名调用。Ordering.on是Ordering特质的实例方法,必须通过一个已有的Ordering实例(比如Ordering[Int])来调用。
2. 核心功能与参数方向
Ordering.by()
它的核心是从「映射函数」出发,基于目标类型的隐式Ordering生成源类型的Ordering。签名简化为:
def by[A, B](f: A => B)(implicit ord: Ordering[B]): Ordering[A]
举个例子,按用户年龄排序:
case class User(name: String, age: Int) // 直接通过映射函数_.age生成User的Ordering,隐式使用Ordering[Int] val userOrderByAge = Ordering.by[User, Int](_.age)
Ordering.on()
它的核心是基于「已有的Ordering实例」,通过映射函数将其适配到新的类型。签名简化为:
def on[B](f: B => A): Ordering[B] // 这里A是当前Ordering实例的类型
同样按用户年龄排序,用on的写法:
// 先拿到Int的Ordering实例,再通过on映射到User类型 val userOrderOnAge = Ordering[Int].on[User](_.age)
3. 使用场景与风格差异
- 用
by更简洁:当你只关心映射函数,不想显式写出目标类型的Ordering实例时,直接用by即可,它会自动查找目标类型的隐式Ordering。 - 用
on更直观:当你已经持有某个类型的Ordering实例,想把它“复用”到另一个类型(通过映射函数)时,on的语义更清晰——相当于“把这个Ordering应用到映射后的结果上”。
4. 本质等价性
二者可以互相替代,本质是同一逻辑的两种表达:
Ordering.by(f)完全等价于Ordering[B].on(f)(前提是B的隐式Ordering存在)ord.on(f)完全等价于Ordering.by(f)(ord)
Scala同时提供这两个方法,纯粹是为了适配不同的代码书写风格和上下文场景,让开发者可以选择更贴合当前代码逻辑的表达方式。
内容的提问来源于stack exchange,提问作者18446744073709551615
相关产品推荐
相关产品推荐

