trait LowPriorityOrderingImplicits {
/** This would conflict with all the nice implicit Orderings
* available, but thanks to the magic of prioritized implicits
* via subclassing we can make `Ordered[A] => Ordering[A]` only
* turn up if nothing else works. Since `Ordered[A]` extends
* `Comparable[A]` anyway, we can throw in some Java interop too.
*/
implicit def ordered[A <% Comparable[A]]: Ordering[A] = new Ordering[A] {
def compare(x: A, y: A): Int = x compareTo y
}
implicit def comparatorToOrdering[A](implicit cmp: Comparator[A]): Ordering[A] = new Ordering[A] {
def compare(x: A, y: A) = cmp.compare(x, y)
}
}
那里,两个隐式函数(ordered [A]和comparatorToOrdering [A])都返回Ordering [A],它应该发生冲突,但为什么它在那里工作呢?
答案 0 :(得分:2)
仅如果某种类型A
存在隐式转化A => Comparable[A]
和隐式Comparator[A]
。这些含义导致某些含糊不清的唯一方法是它们自己的隐含参数是否都能解决。在这种情况下,它会失败:
class Foo
implicit val fooComp = new java.util.Comparator[Foo] { def compare(a: Foo, b: Foo): Int = 0 }
val fooComparable = new java.lang.Comparable[Foo] { def compareTo(foo: Foo): Int = 0 }
implicit def foo2Comp(foo: Foo): Comparable[Foo] = fooComparable
scala> implicitly[Ordering[Foo]]
<console>:16: error: ambiguous implicit values:
both method ordered in trait LowPriorityOrderingImplicits of type [A](implicit evidence$1: A => Comparable[A])scala.math.Ordering[A]
and method comparatorToOrdering in trait LowPriorityOrderingImplicits of type [A](implicit cmp: java.util.Comparator[A])scala.math.Ordering[A]
match expected type Ordering[Foo]
implicitly[Ordering[Foo]]
^
因此,在技术上可能会产生模糊的隐含错误,但它应该非常罕见。如果某些内容已经Comparable
,则无需隐式Comparator
。