隐式转换执行过程分析
概念
Java 有很庞大的类库资源,但是 被声明成 final 的类不允许继承 例如 String , 怎样扩展java及第三方类库 Scala提供了很灵活的方式
当 scala 使用 implicit 隐式转化时 , scala 编辑器发现对象的类型不匹配时,不会直接报错,而会在代码中尝试匹配implicit声明的object, 当然,相同方法签名的类必须唯一。
举个小例子,实现在字符串前后 添加 “**” 的操作。如:
|
|
代码的执行过程如下:
- 调用File 的read 方法
- 当编译器发现File类没有read 方法时,不是直接报错,而是执行第三步
- 检查当前作用域中是否有接受File的 implicit 方法,如没有直接报错,如有,执行第4步
- 将File作为参数实例化RichFile,再检查是否有read 方法,如没有直接报错
- 执行read方法
整个执行过程中,需要特别注意的是, 作用域
作用
- 功能增强
隐式参数实例解析
概念
所谓隐式参数,是指方法或者函数中implicit 关键字 修饰的参数
如:
|
|
方法中 language参数,前面有implicit
实例
隐式参数的执行过程,在当前作用域中寻找 implicit 关键字修饰的 类型 相同的参数
|
|
执行过程中,会按照1,2,3的步骤进行。 如果作用域中有多个类型相同的同时都有impplict 限定,会出现什么情况
|
|
执行过程立马报错:
|
|
隐式参数与隐式转换的联合使用解析
函数参数与隐式转换在 Scala 和 Spark 中经常出现,让隐式参数与隐式转换的联合使用,请看一下实例:
|
|
根据上一节 隐式参数的定义,bigger 方法中 参数 order 被 implicit 限定,我们称之为 隐式参数,在这里只不过此参数为 一个 从 T 到ordered[T]的函数。 当调用 bigger(2,3),scala 根据类型推测出 Int 类型,同时检查在当前作用域里,有没有 implict 限定的 从 Int 到 Ordered[Int] 方法。 我们知道,scala 的 predef 中已经提供了这样的函数。这个函数函数其实就是隐式转换的函数
在看看 bigger(new Student(“zhansan”,20),new Student(“lisi”,40) 执行,由于 Student 类,不是系统自带函数,为了实现 Student => Ordered[Student] ,这里继承了 Ordered[Student] 类。
隐式类分析
概念
所谓隐式类: 就是对类增加 implicit 限定的类,其作用主要是对类的加强!
如:
|
|
class 前面的 implicit ,通过这个隐式类,就可以让 Int 型数据具有 add 方法。
实例
|
|
执行过程分析
- 当 1.add(2) 时,scala 编译器不会立马报错,而检查当前作用域有没有 用 implicit 修饰的,同时可以将 Int 作为参数的构造器,并且具有方法 add 的类,经过查找 发现 ImpInt 符合要求
- 利用隐式类 ImpInt 执行add 方法
隐式对象分析
what is 隐式对象
所谓隐式对象 : 就是用 implicit object 定义的对象,其作用主要表现在 运行时 被调用
如:
|
|
StringAdd 前面的 implicit object
when 使用隐式对象
对于一些根据类型推断的计算,形如:净价+{利息} = 全价,或者是一些 表达式语句的计算,如${净价 + 利息}等,更加复杂一点的是, 计算数据的类型不同的场景
how 使用隐式对象
|
|
过程解析
执行过程检查当前作用是否有 implicit object 限定的 类型为 SubTemplate 的对象,如有,则选取此对象。
伴生对象的隐式转换
代码如下:
|
|
过程解析
当 new File_Implicit2 对象 执行read 过程中,并没有import 导入隐式转换相关方法,而是 通过 File_Implicit2 的伴生对象来完成。
当代码改为如下语句时:
|
|
代码执行的 不是伴生对象File_Implicit2 中的隐式转换,而是 File_Implicit3 中的。