隐式转换
1. 隐式函数基本介绍
隐式转换函数是以implicit关键字声明的带有单个参数的函数。这种函数将会自动应用,将值从一种类型转换为另一种类型
2. 入门案例
implicit def f1(d: Double): Int = {
d.toInt
}
//Double 是输入类型, Int 是转换后的类型
val a: Int = 3.5 // 不用调用toInt方法,就可自动转换
3. 隐式转换的注意事项和细节
- 隐式转换函数的函数名可以是任意的,隐式转换与函数名称无关,只与函数签名(函数参数类型和返回值类型)有关。
- 隐式函数可以有多个(即:隐式函数列表),但是需要保证在当前环境下,只有一个隐式函数能被识别
4. 隐式转换丰富类库功能
- 基本介绍
如果需要为一个类增加一个方法,可以通过隐式转换来实现。(动态增加功能)比如想为MySQL类增加一个delete方法 - 快速入门案例
object MySQL{
def main(args: Array[String]): Unit = {
implicit def addDelete(mysql:MySQL): DB = {
new DB
}
val mysql = new MySQL
mysql.insert()
mysql.delete() // 调用隐式函数,动态增加delete方法
}
}
class MySQL{
def insert(): Unit = {
println("insert")
}
}
class DB {
def delete(): Unit = {
println("delete")
}
}
5. 隐式值
- 基本介绍
隐式值也叫隐式变量,将某个形参变量标记为implicit,所以编译器会在方法省略隐式参数的情况下去搜索作用域内的隐式值作为缺省参数 - 应用案例
implicit val str1: String = "jack"
def hello(implicit name: String): Unit = {
println(name + " hello")
}
6. 隐式类
- 基本介绍
在scala2.10后提供了隐式类,可以使用implicit声明类,隐式类的非常强大,同样可以扩展类的功能,比前面使用隐式转换丰富类库功能更加的方便,在集合中隐式类会发挥重要的作用。 - 隐式类使用有如下几个特点:
- 其所带的构造参数有且只能有一个
- 隐式类必须被定义在“类”或“伴生对象”或“包对象”里,即隐式类不能是 顶级的(top-level objects)。
- 隐式类不能是case class(case class 样例类)
- 作用域内不能有与之相同名称的标识符
- 应用案例
def main(args: Array[String]): Unit = {
//DB1会对应生成隐式类
implicit class DB1(val m: MySQL1) {
def addSuffix(): String = {
m + " scala"
}
}
val mysql1 = new MySQL1
mysql1.sayOk()
//mysql1.addSuffix() ==> DB1$1(mysql1).addSuffix()
//DB1$1(mysql1)返回的类型是 ImplicitClass$DB1$2
println(mysql1.addSuffix())
}
class MySQL1 {
def sayOk(): Unit = {
println("sayOk")
}
}
7. 隐式转换的前提
- 不能存在二义性
- 隐式操作不能嵌套使用