-
Notifications
You must be signed in to change notification settings - Fork 9
Implicit Class
Song Kun edited this page Dec 31, 2017
·
1 revision
Scala 2.10 引入的特性,使用 implicit class
声明的类即为隐式类,在隐式类所在的作用域中,该类的 主构造函数 可以用于隐式转换。
例如,有如下隐式类:
implicit class IntWithTimes(x: Int) {
def times[A](f: => A): Unit = {
def loop(current: Int): Unit =
if (current > 0) {
f
loop(current - 1)
}
loop(x)
}
}
如上,定义了隐式类 IntWithTimes
,该类有方法 times
,该方法接受一个函数,并执行该函数 current
次,可以如下使用:
5 times {
val x = 10;
println("Hi " + x)
}
- 因为
IntWithTimes
隐式类在当前作用域中,所以Int
值 5 会按照IntWithTimes
的主构造函数,隐式转为IntWithTimes
类的实例,然后使用case
函数调用其times
方法 - 输出 5 个
Hi 10
隐式类的使用有如下限制:
-
必须在
trait/class/object
内部定义:object Helpers { implicit class RichInt(x: Int) // OK! } implicit class RichDouble(x: Double) // BAD!
-
其构造函数只能接受一个
non-implicit
参数(其实可以创建有多个non-implicit
参数的隐式类,但这些类无法用于):implicit class RichDate(date: java.util.Date) // OK! implicit class Indexer[T](collecton: Seq[T], index: Int) // BAD! 无法用于隐式转换 implicit class Indexer[T](collecton: Seq[T])(implicit index: Index) // OK!
-
同一作用域中,不能有任何与隐式类同名的
method
member
或者object
,这意味着隐式类不能是case class
(因为case class
会自动创建同名的case object
):object Bar implicit class Bar(x: Int) // 不能与 object 同名 val x = 5 implicit class x(y: Int) // 不能与 member 同名 implicit case class Baz(x: Int) // 不能是 case class