隐式(implicit)是scala中最重要的内容同时也是最难懂的概念。
在scala中隐式的概念主要包括三个方面的内容:
1隐式参数
2隐式转换
3隐式调用
首先隐式implicit 是什么意思? 在scala中implicit是在编译器需要修复类型匹配时,可以用来自动插入的定义。比如举个例子,我要把2.33赋值给一个int类型的a肯定会报错,但是通过隐式转换就可以不报错了。还有例如 x是整数类型,y是浮点类型
x+y 编译器可能会尝试使用一个转换函数convert函数这个concert就是使用implicit定义的,结果就是convert(x)+y
使用implicat的规则:
1 标记规则
只有使用implicit关键字修饰的定义才是可以使用隐式定义。关键字implicit用来标记一个隐式定义。编译器可以选择它作为隐式变化的候选项。你可以使用implicit标记任意变量,函数或对象。
2 范围规则
编译器在选择备选implicit定义时,只会选择当前作用域的定义。例如编译器不会调取 otherpackge.convert。如果需要使用其他包的方法的话需要把该方法引入到当前域中。也就是说,编译器在选择备选implicit时,只有当convert是当前作用域下的单个标志符时,它才会作为备选的implicit。引用其他包方法可以通过“import otherpackge._”
3 一次规则
编译器在需要使用implicit定义时,只会试图尝试转换一次,编译器不会把x+y转换成 convert1(convert2(x)+y)
4 优先规则
编译器不会再x+y已经合法的情况下再去调用implicit
5 命名规则
可以为implicit定义任务的名称。implicit通常只在两种情况下有作用:第一是你想在一个方法中明确指明;另外一个是把一个引入到当前作用域
什么情况下编译器会使用implicit:
1 转换成预期的数据类型 ,比如一个方法的参数类型是string类型的,但在参数传入的时候是一个Int类型的,编译器会发现类型不匹配,就会从当前作用域中检查是否有从int转String类型的隐式转换
2 * 转换 selection的receiver* //
3 隐含参数 隐含参数类似于缺省参数。如果调用方法时没有提供某个参数,编译器会查找当前作用域中是否有合法的符合条件的implicit对象作为参数传入