Scala中的隐式转换是一种非常强大的代码查找机制。当函数、构造器调用缺少参数或者某一实例调用了其他类型的方法导致编译不通过时,编译器会尝试搜索一些特定的区域,尝试使编译通过。
// ctrl +shift+q 查看隐式转换 1 to 10 foreach println
@inline implicit def intWrapper(x: Int) = new runtime.RichInt(x)RichInt中的to方法
def to(end: Int): Range.Inclusive = Range.inclusive(self, end)
可见,编译器尝试 编译 to 方法时,从scala自带的Predf中找到了int2RichInt的方法,从而编译成功。
在scala中大量使用了隐式转换。如scala集合中的
trait TraversableLike[+A, +Repr] extends Any
其中
map的签名为
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = { def builder = { // extracted to keep method size under 35 bytes, so that it can be JIT-inlined val b = bf(repr) b.sizeHint(this) b } val b = builder for (x <- this) b += f(x) b.result }+A表示Trversablelik的实例是协变的。比如B是A的子类,那么TraversableLike[B]也是TraversableLike[A]的子类。
集合的map方法用于构造一个同样长度的集合,其中的bf表示为构造这些集合的容器。
再来看看一个简单的例子
val a = Array(2, 4, 5, 7, 1, 5) sortBy[Int] (x => x) val b = Array(2, 4, 5, 7, 1, 5) sortWith ((a, b) => a - b > 0) val c = Array(2, 4, 5, 7, 1, 5).sorted[Int] println(a.mkString("[", ",", "]")) println(b.mkString("[", ",", "]")) println(c.mkString("[", ",", "]"))
其中sortby和sorted都使用了
protected def ord = scala.math.Ordering.Int
implicit object Int extends IntOrdering
trait IntOrdering extends Ordering[Int] { def compare(x: Int, y: Int) = if (x < y) -1 else if (x == y) 0 else 1 }其中RichInt定义了隐式方法ord,intOrdering混入了Ordering特质,所以RichInt中隐式引入了intOrdering。Ordering混入了Java的Comprator接口。隐式值与curry结合,大大的提高了我们的编程效率,而一定程度上也加大了编程难度。