在做视图界定的时候,希望比较两个参数的"大小",代码如下:
class VBPair2[T <% Ordering[T]](val first:T,val second:T){ def bigger = if(first > second) first else second}object ViewBoundsTest { def main(args: Array[String]): Unit = { val pair2 = new VBPair2(2,3) println(pair2.bigger) }}
(上面代码主要是想通过隐式转换,将2,3转换成RichInt再将RichInt隐式转换成Ordered[T]/Ordering[T],从而具有>函数,进而比较大小)
发现提示有错误:
Cannot resolve symbol >
也就是说Ordering[T]中没有>函数,当我将Ordering[T]换成Ordered[T]则代码成功。
查看Ordered[T]的源代码:
trait Ordered[A] extends Any with java.lang.Comparable[A] { /** Result of comparing `this` with operand `that`. * * Implement this method to determine how instances of A will be sorted. * * Returns `x` where: * * - `x < 0` when `this < that` * * - `x == 0` when `this == that` * * - `x > 0` when `this > that` * */ def compare(that: A): Int /** Returns true if `this` is less than `that` */ def < (that: A): Boolean = (this compare that) < 0 /** Returns true if `this` is greater than `that`. */ def > (that: A): Boolean = (this compare that) > 0 /** Returns true if `this` is less than or equal to `that`. */ def <= (that: A): Boolean = (this compare that) <= 0 /** Returns true if `this` is greater than or equal to `that`. */ def >= (that: A): Boolean = (this compare that) >= 0 /** Result of comparing `this` with operand `that`. */ def compareTo(that: A): Int = compare(that)}object 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) }}
说明Ordered有一个伴生对象(我以前一直以为只有class才能有伴生object对象,现在通过scala源码知道trait也可以有伴生对象),而这个伴生对象中有一个隐式操作,implicit def orderingToOrdered[T](x: T)(implicit ord: Ordering[T]): Ordered[T],看到这个代码,使我想起implicit在函数参数中使用时,不只是对一个参数起作用,而是对所有参数都起作用,比如有下面一个函数:
def somfun(implicit arg1:Int,arg2:String,arg3:Double) 它说明不只是arg1是隐式参数,arg2和arg3也是隐式参数。
implicit def orderingToOrdered[T](x: T)(implicit ord: Ordering[T]): Ordered[T]
说明隐式转换函数orderingToOrdered是一个柯里化函数,第二个参数是一个隐式参数,它的类型是Ordering[T],本例中调用的是int类型参数2,3,说明有一个隐式参数,类型为Ordering[int],当调用的时候会找到Ordered伴生对象的orderingToOrdered隐式转换函数,参数类型为int,返回一个Ordered对象。Ordered类中有>函数,所以在本例中用Ordered则可以正常运行。
scala的Ordering[T]代码框架如下:
trait Ordering[T] extends Comparator[T] with PartialOrdering[T] with Serializable{。。。。。def compare(x: T, y: T): Int。。。。}
只有一个抽象方法compare。Ordering的父类Comparator(在ava包中)中也有一个抽象方法compare:
int compare(T o1, T o2);
也就是说:Scala提供两个特质(trait)Ordered
与Ordering
用于比较。其中,Ordered混入(mix)Java的Comparable接口,而Ordering则混入Comparator接口。众所周知,在Java中
- 实现Comparable接口的类,其对象具有了可比较性;
- 实现comparator接口的类,则提供一个外部比较器,用于比较两个对象。
Ordered与Ordering的区别与之相类似:
- Ordered特质定义了相同类型间的比较方式,但这种内部比较方式是单一的;
- Ordered则是提供比较器模板,可以自定义多种比较方式。