Scala进阶之隐式转换作用域等问题
2016-08-20 13:24
197 查看
1.隐式转换作用域
关于隐式转换查找的顺序问题:1. 简单查找
class Implicits { implicit val content = "Java Hadoop" } object Implicits { implicit val content = "Scala Spark" } object ImplicitsAdvanced { def main(args: Array[String]): Unit = { def printContent(implicit content: String) = println(content) implicit val content = "I love spark" import Implicits._ printContent } printContent 的隐式参数是String类型,所以会找String类型的隐式参数, 上面例子上有三个可能,"Java Hadoop", "Scala Spark", "I love spark" 结果是 I love spark 即它会先在main这个大括号里找满足要求的String类型隐式参数,找到就用,优先级最高。 只有找不到了才会去导入的类里找,把implicit val content = "I love spark"注释掉后 结果是 Scala Spark 说明它要找的是伴生对象里的隐式参数,而非类里面的隐式参数! 如果再加上一个隐式参数如下 object ImplicitsMsg { implicit val content = "Kafak Zookeeper" } 导入时这样导入 import ImplicitsMsg.content 结果是 Kafak Zookeeper 说明都是导入的情况下,优先选择具体的,通配符导入的优化级较低。
2.复杂查找
查找时如果在main方法里找不到,在导入的类的伴生对象里也找不到怎么办呢?
class ImplicitsMsg{ val content = "ImplicitsMsg class" } object ImplicitsMsg { val content = "ImplicitsMsg object" } class ImplicitsChild extends ImplicitsMsg{ override implicit val content = "ImplicitsChild class" } object ImplicitsChild extends ImplicitsMsg{ override implicit val content = "ImplicitsChild object" } object ImplicitsAdvanced { def main(args: Array[String]): Unit = { def printContent(implicit content: String) = println(content) // implicit val content = "I love spark" import ImplicitsMsg._ println("=========") printContent } }
输出的结果是报错,这与王老师讲的不一样,老师说:
“如果当前类的伴生对象无法找到相关的功能,则会到该类相关的所有类和接口的伴生对象中去查找”
我发现如果导入的类的伴生对象里没有相应的隐式参数的话,在IDEA中导入的语句
import ImplicitsMsg._就是灰色的,说明根本不可能导入其子类的隐式参数content
也就意味着查找时只是查找导入的那一层的伴生对象,不会去查找其子类或者接口的隐式类型。
2.最佳实践
在Spark源码中隐式转换在伴生对象里面到处可见,没见过使用import导入的方式,这是要学习的地方,以后写隐式转换就写在类的伴生对象里面。
业界实践,如果你要改变一个类的功能,那就写在伴生对象里面。
这对以后代码升级有好处。(现在理解还不深 -_-! )
3.蘑菇云代码
package com.dt.scala.moguyun /** * 1,当我们使用一个类型的使用如果当前类型无法直接找到合适的方法,则会到其伴生对象中查找隐式功能; * 2,如果当前类的伴生对象无法找到相关的功能,则会到该类相关的所有类和接口的伴生对象中去查找 */ class Implicits(x: Int) { implicit val content = "Java Hadoop" def printValue = { val x = 100 println(x) Map } } object Implicits { implicit val content = "Scala Spark" implicit def int2String(x: Int) = x.toString() //命名时为了方便2是to的意思 implicit def file2RicherFile(file: java.io.File) = new RicherFile(file) //有时还需转换回来 implicit def richerFile2File(richerFile: RicherFile) = richerFile.file } class ImplicitsMsg { val content = "ImplicitsMsg class" } object ImplicitsMsg { val content = "ImplicitsMsg object" } class ImplicitsChild extends ImplicitsMsg { override implicit val content = "ImplicitsChild class" } object ImplicitsChild extends ImplicitsMsg { override implicit val content = "ImplicitsChild object" } class RicherFile(val file: java.io.File) { def dtspark = println("Welcome to dtspark World ") } object ImplicitsAdvanced { def main(args: Array[String]): Unit = { def printContent(implicit content: String) = println(content) // implicit val content = "I love spark" import Implicits._ // import ImplicitsMsg._ println("=========") printContent val file = new java.io.File(".") file.dtspark //implicitly是判断隐式类型的值,如下是求出String的隐式值 println(implicitly[String]) } } 结果 Scala Spark Welcome to dtspark World Scala Spark
以上内容来自[DT大数据梦工厂]首席专家Spark专家王家林老师的课程分享。感谢王老师的分享,更多精彩内容请扫描关注[DT大数据梦工厂]微信公众号DT_Spark
相关文章推荐
- Scala深入浅出进阶经典 第65讲:Scala中隐式转换内幕操作规则揭秘、最佳实践及其在Spark中的应用源码解析
- scala进阶19-隐式转换内幕
- Scala进阶源码实战之八——隐式转换和隐式参数
- scala进阶19-隐式参数+隐式转换
- Scala深入浅出进阶经典 第59讲:Scala中隐式转换初体验实战详解以及隐式转换在Spark中的应用源码解析
- scala进阶20-隐式转换至Ordered与Ordering
- scala进阶18-隐式转换-隐式参数
- Scala隐式转换类遇到的问题
- Scala深入浅出进阶经典 第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析
- 隐式类型转换的一些问题
- C# Mobile远程调用WebService时,返回DataTable出现隐式转换出问题的解决方案
- mysql字符串的隐式转换导致查询异常的问题
- 关于mysql 隐式转换的一个小问题
- clob加||隐式转换造成的性能问题
- 无符号数运算问题——C语言隐式类型转换
- Scala 中的隐式转换 implicit
- C语言学习4: 函数返回值与传入参数,关于函数值传递和类型隐性转换,变量不同的作用域,static变量,多文件编译例如两个C文件,显示函数调用语句跳转,递归,斐波那契数列,多文件编译相同变量的问题。
- scala implicit 隐式转换
- 对Scala隐式转换的总结