本文转自:https://my.oschina.net/u/2963604/blog/2251373
感谢大佬分享!
在做视图界定的时候,希望比较两个参数的"大小",代码如下:
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特质定义了相同类型间的比较方式,但这种内部比较方式是单一的;
Ordereing则是提供比较器模板,可以自定义多种比较方式。