使用implicit 修饰的内容是隐式内容, 隐式的特点就是遇到适应的类型会自动的应用
意义:
- 使得静态类型动态化
- 为现有类库添加功能
- 隐式的代理增强一个类或者一个方法
分类:
- 隐式参数
- 隐式函数
- 隐式类
隐式变量
定义隐式变量
object MyValue {
implicit val age:Int = 19
implicit val name:String = "lisi"
}
定义隐式变量
/**
* 这个方法的所有的参数是隐式参数
* 可以使用柯里化来定义个别的隐式参数
* add(x:Int)(implicit y:Int , z:Int)
* 上面的例子中x为正常参数 y z都为隐式参数
* @param name
* @param age
*/
def myShow(implicit name: String, age: Int): Unit = {
println(name + " " + age)
}
演示现象
def main(args: Array[String]): Unit = {
new Show().myShow("reba",12)
// 导入了隐式参数 就会从context中寻找隐式数据
// context中只能有一个匹配类型的数据
// 如果找到多个匹配类型的数据就会报错
import MyValue._
//lisi 19
new Show().myShow
}
应用示例
class A[T] {
def mymax1(x:T ,y:T): T ={
if(x > y) x else y// T类型中没有定义>方法 报错
}
// T类型必须是可以隐式的转换成Ordered的类型 , 这个隐式转换要事先定义
def mymax2(x:T ,y:T)(implicit order:T=>Ordered[T]): T ={
if(x > y) x else y
}
}
object A{
def main(args: Array[String]): Unit = {
// Int已经默认的实现了 Orderd的实时转换
val res: Int = new A[Int]().mymax2(12,34)
println(res)
}
}
隐式函数
函数处理的数据类型 => 返回的数据类型 , 当遇到对应的类型=>类型处理的时候隐式函数会自动的应用
增强一个类
添加不存在的函数,implicit作用于函数,称之为隐式函数
定义一个类只有add的方法
* 2019/11/12
* 定义一个类 类中定义一个方法
*
* @author Hangge.z WX:17710299606
* 想对类增强一些方法
*
*/
class Demo {
val add = (x: Int, y: Int) => {
x + y
}
}
定义一个增强的类
/**
* 增强类
* 定义一个减法方法
* @param demo
*/
class Advice(val demo: Demo) {
val substract = (x: Int, y: Int) => {
x - y
}
}
编写一个隐式转换的方法类
/**
* 将Demo类隐式转换成增强的类
这样我们被增强的类既有自己的方法也有增强类的方法
这样就实现的了隐式函数对一个类增强的目的
*/
object ImplicitAdvice {
//将Demo类隐式转换成增强类 实现对Demo类增强的目的
implicit def advice(demo: Demo) = {
new Advice(demo)
}
}
演示
object Test2 {
def main(args: Array[String]): Unit = {
val demo = new Demo
//在这里调用没有substract方法
val sum: Int = demo.add(1,2)
import ImplicitAdvice._
val res2: Int = demo.substract(33,20)
println(sum)
println(res2)
}
}
隐式类
增强一个类型
隐式类约束
隐式类必须有一个带一个参数的主构造函数
必须定义在另一个class/object/trait里面(不能独立定义)
隐式类构造器只能带一个不是implicit修饰的参数
作用域中不能有与隐式类类型相同的成员变量,函数以及object名称
定义一个类
class B {
val add = (x: Int, y: Int) => {
x + y
}
}
定义一个隐式类
/**
* 隐式主题类
*/
object ImplicitContext{
//隐式类只能对一种类型的类进行增强 B类或者子类增强
implicit class RichB(b:B){
def multiply(x: Int, y: Int) = {
x * y
}
}
}
演示增强效果
def main(args: Array[String]): Unit = {
val b = new B // B类 以及他的子类
println(b.add(12, 12))
import ImplicitContext._
println(b.multiply(12, 12))
}
注意
如果代码无需隐式转换即可通过编译,则不会引入隐式转换
隐式转换只会匹配一次,即隐式转换至多发生一次
存在二义性的隐式转换报错,