Scala之旅——隐式转换

从类型S到类型T的隐式转换,由一个拥有函数类型S => T的隐式值,或者一个可转换为指定类型的隐式方法所定义。

隐式转换适用于以下2中场景:

  • 如果一个表达式eS类型的,且S类型不能转换成表达式所期望的T类型。
  • 在一个S类型的e的选择器e.m中,如果m不是S的成员。

第一种场景中,会去查找一个适用于e且其返回类型可以转换为T的转换c

第二种场景中,则会去查找一个适用于e且其返回结果包含了一个名为m的成员的转换c

如果隐式方法List[A] => Ordered[List[A]]Int => Ordered[Int]都在作用域内,那么对于下面两个List[Int]类型的列表的操作是合法的:

1
List(1, 2, 3) <= List(4, 5)

隐式方法Int => Ordered[Int]scala.Predef.intWrapper自动提供。下面提供了一个 List[A] => Ordered[List[A]] 的隐式方法的实现样例:

1
2
3
4
5
6
7
8
import scala.language.implicitConversions

implicit def list2ordered[A](x: List[A])
(implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] =
new Ordered[List[A]] {
//replace with a more useful implementation
def compare(that: List[A]): Int = 1
}

隐式导入的对象scala.Predef声明了几个预定义的类型(比如Pair)和方法(比如assert),以及一些隐式转换。

例如,在调用一个Java方法且需要一个java.lang.Integer时,你可以传入一个scala.Int来代替。这是因为Predef中包含了以下的隐式转换:

1
2
3
4
import scala.language.implicitConversions

implicit def int2Integer(x: Int) =
java.lang.Integer.valueOf(x)

因为随意使用隐式转换可能出现难以预料的问题,所以在编译隐式转换的定义时编译器会发出警告。

可以通过以下任意一种方法来关闭警告:

  • 导入scala.language.implicitConversions到隐式转换定义的作用域中。
  • 给编译器带上参数-language:implicitConversions

这样在做转换时,编译器将不会发生警告。

小鹏 wechat
公众号:数据Man
0%