在Ordering trait中,我们可以找到这个隐式方法:
/** This implicit method augments `T` with the comparison operators defined
* in `scala.math.Ordering.Ops`.
*/
implicit def mkOrderingOps(lhs: T): Ops = new Ops(lhs)
在伴侣对象Ordering.Implicits中可以找到:
/** This implicit creates a conversion from any value for which an
* implicit `Ordering` exists to the class which creates infix operations.
* With it imported, you can write methods as follows:
*
* {{{
* def lessThan[T: Ordering](x: T, y: T) = x < y
* }}}
*/
implicit def infixOrderingOps[T](x: T)(implicit ord: Ordering[T]): Ordering[T]#Ops = new ord.Ops(x)
这第二个隐含真的有必要吗?在什么情况下,应该使用第一个隐式,在什么情况下应该使用第二个?
感谢。
答案 0 :(得分:4)
第一个隐式只能在Ordering
范围内使用(它不是*),在扩展Ordering
的任何类型的范围内,或直接导入:
def foo[A](x: A, y: A)(implicit ord: Ordering[A]) = {
import ord.mkOrderingOps
x < y
}
请注意:1)要导入它,您需要首先为排序命名(与def lessThan[T: Ordering](x: T, y: T) = ...
不同); 2)如果您在范围内有两种不同类型的排序,则无法重命名mkOrderingOps
而不重命名它:import ord1.mkOrderingOps; import ord2.{mkOrderingOps => mkOrderingOps2}
。
第二种方法既没有这些问题。
我不知道的是1)为什么你会使用第一个隐含的(也许它是在第二个之前引入的?); 2)为什么第二个没有在scala.Predef
中定义,这样你就可以在不导入任何内容的情况下使用运算符。