我创建两个scala文件,Impliciteg用来定义隐式,ImplicitDemo用来做隐式转换
ImplicitDemo中需要导入Impliciteg这个包:import com.wang.scala2.Impliciteg._
一、隐式参数
原则:
1.在使用隐式参数是需要先定义一个隐式参数,否则会报错
2.相同类型的隐式参数只能定义一个,否则会产生异义,会报错
3.隐式参数如果不重新赋值他会默认用声明的
//定义隐式参数
implicit val num1:Int=10
def fun(implicit num1:Int):Int = num1
println(s"fun:$fun")//10
二、隐式方法
//定义隐式方法
implicit def Double2ToInt2(a:Double):Int = a.toInt
//隐式转换
val a:Int = 3.14
println(a)//3
三、隐式类
能调用所有接收ImplicitDemo的隐式类中的所有方法
class ImplicitDemo{}
object ImplicitDemo{var implicitDemo = new ImplicitDemoimplicitDemo.shang(2, 1)//2implicitDemo.ji(3, 5)//15
}
implicit class JiandShang(obj:ImplicitDemo) {def ji(num:Int,num2:Int):Int={num*num2}def shang(num:Int,num2:Int):Int={num/num2}}
四、Scala 隐私注意事项
4.1 转换时机
1.当方法中的参数的类型与目标类型不一致时
2.当对象调用类中不存在的方法或成员时,编译器会自动将对象进行隐式转换
4.2 解析机制
即编译器是如何查找到缺失信息的,解析具有以下两种规则:
1.首先会在当前代码作用域下查找隐式实体(隐式方法 隐式类 隐式对象)
2.如果第一条规则查找隐式实体失败,会继续在隐式参数的类型的作用域里查找
类型的作用域是指与该类型相关联的全部伴生模块,一个隐式实体的类型T它的查找范围如下:
(1)如果T被定义为T with A with B with C,那么A,B,C都是T的部分,在T的隐式解析过程中,它们的伴生对象都会被搜索
(2)如果T是参数化类型,那么类型参数和与类型参数相关联的部分都算作T的部分,比如List[String]的隐式搜索会搜索List的
伴生对象和String的伴生对象
(3) 如果T是一个单例类型p.T,即T是属于某个p对象内,那么这个p对象也会被搜索
(4) 如果T是个类型注入S#T,那么S和T都会被搜索
4.3 转换前提
1.不存在二义性(如例1)
2.隐式操作不能嵌套使用,即一次编译只隐式转换一次(One-at-a-time Rule)
Scala不会把 x + y 转换成 convert1(convert2(x)) + y
3.代码能够在不使用隐式转换的前提下能编译通过,就不会进行隐式转换。