1 Scala内置的各种隐式

Scala 2.11版库源代码中定义了超过300个隐式方法、隐式值和隐式类型。它们当中大多数都是隐式方法,而隐式方法中的多数则被用于将某一类型转换成另一类型。

1.1 AnyVal类型的隐式转换

AnyVal类型的所有伴生对象均提供了丰富的隐式转换方法,例如将Int值转换为Long值,可以使用int2long方法。

取自Byte的伴生对象:

implicit def byte2short(x: Byte): Short = x.toShort
implicit def byte2int(x: Byte): Int = x.toInt
implicit def byte2long(x: Byte): Long = x.toLong
implicit def byte2float(x: Byte): Float = x.toFloat
implicit def byte2double(x: Byte): Double = x.toDouble

取自Char的伴生对象:

// From the scala.Char companion object:
implicit def char2int(x: Char): Int = x.toInt
implicit def char2long(x: Char): Long = x.toLong
implicit def char2float(x: Char): Float = x.toFloat
implicit def char2double(x: Char): Double = x.toDouble

取自Short的伴生对象:

implicit def short2int(x: Short): Int = x.toInt
implicit def short2long(x: Short): Long = x.toLong
implicit def short2float(x: Short): Float = x.toFloat
implicit def short2double(x: Short): Double = x.toDouble

取自Int的伴生对象:

implicit def int2long(x: Int): Long = x.toLong
implicit def int2float(x: Int): Float = x.toFloat
implicit def int2double(x: Int): Double = x.toDouble

取自Long的伴生对象:

implicit def long2float(x: Long): Float = x.toFloat
implicit def long2double(x: Long): Double = x.toDouble

取自Float的伴生对象:

implicit def float2double(x: Float): Double = x.toDouble

BigInt和BigDecimal类定义在scala.math包中,他们可以转换来自AnyVal类型和Java中对应的实现类型。 取自BigDecimal的伴生对象:

implicit def int2bigDecimal(i: Int): BigDecimal = apply(i)
implicit def long2bigDecimal(l: Long): BigDecimal = apply(l)
implicit def double2bigDecimal(d: Double): BigDecimal = ...
implicit def javaBigDecimal2bigDecimal(x: BigDec): BigDecimal = apply(x)

其中调用apply方法时,调用了BigDecimal伴生对象的apply工厂方法。

取自BigInt的伴生对象:

implicit def int2bigInt(i: Int): BigInt = apply(i)
implicit def long2bigInt(l: Long): BigInt = apply(l)
implicit def javaBigInteger2bigInt(x: BigInteger): BigInt = apply(x)

1.2 转换自Java中的类型

Scala使用了一些Java中的类型,像Array[T]和String类型,和它们对应的ArrayOps[T]和StringOps类型向所有Scala集合提供常用的方法。

其他的转换函数则定义在名称中包含Wrapper单词的类型中。

1.3 @inline注解

Predef中定义了大多数的隐式定义。其中一些隐式定义包含了@inline标注,这一标注鼓励编译器努力尝试将函数调用内联,以减少栈帧开销。与之对应的是@oninline标注,该标注阻止编译器将方法内联化。

2 CanBuildFrom隐式解读


In [ ]:

3 FileWrapper隐式解读


In [ ]:

合理使用隐式

隐式转换机制为构建DSL和简化代码提供了强大的工具。不过由于传递隐式参数和隐式值几乎不可见,这增加了理解代码的难度。

为了提高隐式可见性,推荐的方法是将隐式值统一放到名为implicits的特殊包或名为Implicits的对象中。这种方式使得读者一旦遇到导入语句中的implicit字样时,便会刘怡到除了Scala内置的隐式之外,还存在一些其他的隐式。