介绍
本文介绍 scala 2.10版之前的方式:隐式函数
隐式函数:用 implicit 修饰 的函数,且该函数 只有一个参数。
scala编译失败时,会在当前的环境中查找能让代码编译通过的方法,实现 二次编译,此时,这个函数会 自动调用
案例
将 浮点型数字 赋值给 Int型的 常量 或 变量,正常情况下会报错,见下面代码:
object Test {
def main(args: Array[String]): Unit = {
val i:Int=3.5 //此处报错,3.5浮点型,不能赋值给Int型的i
println(i)
}
}
可通过 隐式函数 实现 隐式转换,将 浮点型数字 转换成 整数,再赋值给 Int型的 常量 或 变量,修改如下:
object 隐式转换 {
def main(args: Array[String]): Unit = {
/*不需要额外处理。
*scala编译失败时,会在当前的环境中查找能让代码编译通过的方法,实现二次编译
*/
val i:Int=3.5
println(i)
}
//隐式函数,形参为double,表示可以接受浮点型数字
// 必须有返回值类型,否则报错
implicit def to(a:Double):Int ={
a.toInt //转换成整数,并返回
}
}
或者
object 隐式转换 {
def main(args: Array[String]): Unit = {
//定义在 main() 方法内
implicit def to(a:Double):Int ={
a.toInt
}
val i:Int=3.5
println(i)
}
}
注意
隐式转换 与 隐式函数的名称 无关,与隐式函数的 形参类型 和 返回值类型 有关
当前环境中,隐式函数 可以有多个,但 只能有一个隐式函数被识别
不能嵌套使用
隐式函数 名字相同 时,形参列表必须不同
隐式函数 名字不同 时, 参数列表 或 返回值类型,必须有一个不同,否则报错
可以有 多个 隐式函数
object 隐式转换 {
def main(args: Array[String]): Unit = {
implicit def to(a:Double):Int ={
a.toInt
}
implicit def to2(a:String):Int ={
a.toInt
}
val i:Int=3.5
val i2:Int="3"
println(i)
}
}
只能有一个隐式函数被识别
object 隐式转换 {
def main(args: Array[String]): Unit = {
implicit def to(a:Double):Int ={
a.toInt
}
implicit def to2(a:Double):Int ={
a.toInt
}
//2个隐式函数 形参类型、返回类型完全相同,不知道调用哪个,下面代码会报错(没有下面代码不会报错)
val i:Int=3.5
}
}
不能嵌套使用
def main(args: Array[String]): Unit = {
implicit def to(a:Double):Int ={
val x:Int=3.1//隐式函数还未生效,无法使用
}
val i:Int=3.5
}
隐式函数名字相同时,形参列表必须不同
object s37implicit {
def main(args: Array[String]): Unit = {
val i:Int = 3.5
println(s"i=$i")
}
implicit def to(d:Double) : Int ={
println(s"调用隐式函数,参数d=$d")
d.toInt
}
implicit def to(d:Double,i:Int) : Double ={
println(s"调用隐式函数,参数d=$d")
d.toInt
}
}
隐式函数 名字不同 时, 参数列表 或 返回值类型,必须有一个不同,否则报错
案例:不改源码,扩展类库功能
不改变源码的情况下,给 Student 类增加 play方法
class Student{
def study(lession:String):Unit={
println("学习 "+lession)
}
}
实现
object 隐式转换_增加方法 {
def main(args: Array[String]): Unit = {
val std:Student = new Student()
std.study("scala")
// 隐式转换 ,底层实现:to(std).play("篮球")
std.play("篮球")
}
implicit def to(std:Student):StudentEx={
new StudentEx()
}
}
class StudentEx{
def play(str:String):Unit = {
println("玩 "+str)
}
}
class Student{
def study(str:String):Unit={
println("学 "+str)
}
}
执行流程:


