1、概述
\quad \quad Scala提供的隐式转换和隐式参数功能,是非常有特色的功能。是Java等编程语言所没有的功能。它可以允许你手动指定,将某种类型的对象转换成其他类型的对象或者是给一个类增加方法。通过这些功能,可以实现非常强大、特殊的功能。
2、隐式转换
\quad \quad
Scala的隐式转换,其实最核心的就是定义隐式转换方法,即implicit conversion function
。定义的隐式转换方法,只要在编写的程序内引入,就会被Scala自动使用。Scala会根据隐式转换方法的签名,在程序中使用到隐式转换方法接收的参数类型定义的对象时,会自动将其传入隐式转换方法,转换为另外一种类型的对象并返回。这就是“隐式转换”。其中所有的隐式值和隐式方法必须放到object中。
2.1 隐式转换方法
\quad \quad Scala默认已经帮我们实现了大量的隐式转换函数,在特定情况下会自动调用相应的隐式转换方法完成隐式转换,从而保证程序的顺利执行。但Scala提供的隐式转换方法数量毕竟是有限的,不可能满足应有的所有场景,此时需要自己定义自己的隐式转换方法。
// 由于Scalay已经实现了Int类型到Float类型的隐式转换,故可以直接将整型值赋值给Float类型变量
scala> var x:Float=1
x: Float = 1.0
// 而Float类型无法转换到Int类型,要想达到目的,必须定义隐式转换方法
scala> val y:Int=2.55f
<console>:11: error: type mismatch;
found : Float(2.55)
required: Int
val y:Int=2.55f
案例一:类型的转换
//定义一个隐式转换方法,该隐式函数将Float类型转换成Int类型(注意函数的输入参数)
scala> implicit def float2Int(x:Float)=x.toInt
warning: there was one feature warning; re-run with -feature for details
float2Int: (x: Float)Int
// 再此执行,成功
scala> val y:Int=2.55f
y: Int = 2
案例二: 为一个已存在的类添加一个新的方法
- 如今已经创建两个类:普通man类(方法:吃),超人 Superman类(方法:飞)
- 需求:在普通man类中添加超人 Superman类中的飞方法
object Implicit extends App {
// 定义隐式转换函数
implicit def man2superman(man:Man):Superman= new Superman(man.name)
val man = new Man("PK")
man.fly()
man.eat()
}
class Man(val name:String){
def eat():Unit={
println(s"man[$name] eat ...")
}
}
class Superman(val name:String){
def fly():Unit={
println(s"man[$name] fly ...")
}
}
结果:
- 注意隐式转换函数必须在object中
然而使用Scala的隐式转换是有一定的限制的,总结如下:
- implicit关键字只能用来修饰方法、变量(参数)。
- 隐式转换的方法在当前范围内才有效。如果隐式转换不在当前范围内定义(比如定义在另一个类中或包含在某个对象中),那么必须通过import语句将其导入。
- 如果所涉及程序中有太多隐式函数,可将所用的隐式函数封装到一个类中,到时候import即可
2.2 隐式转换方法名称
\quad \quad 隐式转换方法(函数)implicit def float2Int(x:Float)=x.toInt中的函数名可以是任意的,只与函数签名即函数定义有关,如果在当前作用域范围存在函数签名相同但函数名称不同的两个隐式转换函数,则在进行隐式转换时会报错。
3、隐式参数
\quad \quad
隐式参数,指的是在函数或者方法中,定义一个用implicit
修饰的参数,此时Scala会尝试找到一个指定类型的,用implicit修饰的对象,即隐式值,并注入参数。
- Scala会在两个范围内查找:
- 当前作用域内可见的val或var定义的隐式变量;
- 一种是隐式参数类型的伴生对象内的隐式值;
4、隐式类
\quad \quad
隐式类就是对类增加implicit
限定的类,其作用主要是对类的加强。
例子:
object Implicit extends App {
//定义隐式类,输入参数类型为整数
implicit class Calculator(x:Int){
def add(a:Int)=a+x
}
println(1.add(3))
}