给定:
case class Person(name: String)
并且尝试着去做:
scala> List(Person("Tom"), Person("Bob")).sorted
导致关于缺少订购的投诉。
<console>:8: error: could not find implicit value for parameter ord: Ordering[Person]
List(Person("Tom"), Person("Bob")).sorted
然而这:
case class Person(name: String) extends Ordered[Person] {
def compare(that: Person) = this.name compare that.name }
工作正常,符合预期:
scala> List(Person("Tom"), Person("Bob")).sorted
res12: List[Person] = List(Person(Bob), Person(Tom))
虽然没有命令或暗示。
- 问题#1:* 这是怎么回事?(我的钱是在一些隐含的...)
然而,鉴于上述情况和以下事实:
scala> Person("Tom") > Person("Bob")
res15: Boolean = true
有效,还有这个:
scala> List(Some(2), None, Some(1)).sorted
开箱即用:
res13: List[Option[Int]] = List(None, Some(1), Some(2))
我期望这一点:
scala> Some(2) > Some(1)
也会起作用,但它不能:
<console>:6: error: value > is not a member of Some[Int]
Some(2) > Some(1)
- 问题#2:* 为什么不,我如何才能让它工作?
6条答案
按热度按时间kdfy810k1#
如果你安装了对默认范围来说有点太神奇的奖励暗示,你可以这样比较选项:
这个导入为你提供了一个从Ordering到类的隐式的中缀操作,这样就足够了,不需要另一个导入。
piwo6bdm2#
关于你的第一个问题:
Ordered[T]
扩展了Comparable[T]
。Ordering
伴随对象为任何可以转换为Comparable[T]
的值提供了隐式Ordering[T]
:A : Ordering => Ordered[A]
没有隐式转换-这就是Some(1) > Some(2)
无法工作的原因。定义这样的转换是否是一个好主意值得怀疑,因为您可能最终将对象 Package 成
Ordered
示例,然后再创建一个Ordering
示例(依此类推...)。您可以创建两个Ordered
示例,在作用域中具有不同的Ordering
示例,这当然不是您想要的。mwkjh3gx3#
List的
sorted
方法的定义为:因此,隐式的事情确实发生了,但是标准库中的许多类都有与之关联的隐式对象,而不必首先导入它们。
Ordering伴随对象定义了一系列隐式排序,其中包括OptionOrdering和IntOrdering,这有助于解释列表调用
sorted
的能力。要在存在隐式转换时使用运算符,需要导入该对象,例如:
h5qlskok4#
回答你的第二个问题,为什么你不能这样做:
Some(2) > Some(1)
您可以通过导入和使用
Option[Int]
而不是Some[Int]
来实现。实际上,你的类型可能是
Option[Int]
而不是Some[Int]
,所以它不会那么难看,你也不需要显式的向上转换。uhry853o5#
我假设你理解为什么当你没有传入一个Ordering并且在作用域中没有一个可用的时候sorted不起作用。至于为什么当你从Ordered trait扩展你的类的时候sorted函数起作用。答案是当你从Ordered trait扩展的时候,代码类型检查trait包含像〈,〉等。因此不需要进行隐式转换,因此不会抱怨缺少隐式排序。
至于您的第二个问题,
Some(2) > Some(1)
将不起作用,因为Some没有扩展特征Ordered,作用域中似乎也没有任何隐式函数将Some隐式转换为具有函数>
的对象vvppvyoh6#
感谢您提供详细的问题和示例。
我的答案是基于我从一个伟大的文章在这里学习:http://like-a-boss.net/2012/07/30/ordering-and-ordered-in-scala.html
都归功于这里的作者。
引用该文章:
Coming back to our Box example - the scala library defines an implicit conversion between Ordered[T] and Ordering[T] and vice-versa.
https://github.com/scala/scala/blob/2.12.x/src/library/scala/math/Ordered.scala中
Ordered
的伴随对象在此处提供了所需的转换:/** Lens from
Ordering[T]to
Ordered[T]*/ implicit def orderingToOrdered[T](x: T)(implicit ord: Ordering[T]): Ordered[T] = new Ordered[T] { def compare(that: T): Int = ord.compare(x, that) }
然而,反向转换没有定义,我不知道为什么?