scala implicit关键字详解(隐式转换函数、隐式类、隐式参数、隐式值)
一、Overview
implicit
是scala中的一个关键字,关于它有着丰富的用法,使得scala更灵活和容易扩展。截止目前,scala已经来到了2.12.3版本,本篇文章把目前scala支持的implicit
用法作了较为全面的整理,以方便在阅读scala源码的时候稍作参考。文中全部的代码和测试结果均以scala2.12.3为准。
闲话不多讲,目前可以见到的implict
用法有如下几种:
1.隐式转换函数
implicit def int2str(x:Int):String = x.toString
2.隐式类
implicit class Box(x: Int) {
}
3.隐式参数
def compare[T](x:T,y:T)(implicit ordered: Ordering[T]):Int = {
ordered.compare(x,y)
}
4.隐式值
implicit val x: Int = 0
5.隐式对象
implicit object obj {
}
6.context bound
def compare2[T: Ordering](x: T, y: T) = {
val ord = implicitly[Ordering[T]]
ord.compare(x, y)
}
先不用着急理解这些代码的含义,下面会逐一讲解。
二、隐式转换函数
首先来看隐式转换函数。
implicit def int2str(x:Int):String = x.toString
这段代码声明了一个函数int2str
,它与正常函数唯一的区别在于前面多出的implicit
关键字。这里的implicit
就是它字面的含义——隐式,它告诉编译器,这个函数是一个隐式转换函数,能够把Int
类型的值转换成String
类型的值。
这种隐式转换的意义在于,如果在进行一个对Int
类型的操作时不合法,编译器会在当前作用域寻找合适的隐式转换,来尝试使这种操作合法。隐式转换发生在这两种情景:
e
是一个S
类型的表达式,而需要的却是T
类型,编译器会寻找S=>T
的隐式转换e
是一个S
类型的表达式,使用点号访问e.m
时,m
不是类型S
的成员,编译器会寻找合适的隐式转换使e.m
合法
隐式转换最常用的用途就是扩展已有的类,在不修改原有类的基础上为其添加新的方法、成员。
例如上面的这个函数,在为Int
类型定义好到String
类型的隐式转换后,所有String
类型支持的操作都可以直接在Int
类型的值上使用:
10.concat(