美文网首页
第28课:Scala隐式转换内幕实践解密

第28课:Scala隐式转换内幕实践解密

作者: fatj | 来源:发表于2016-08-21 17:17 被阅读0次

    其实隐式转换有几种类型:隐式参数,隐式转换,隐式对象,和隐式类

    首先看一下Scala的作用域

    隐式参数冲突的情况:

    object Implicits {
      implicit val content="Scala"
    }
    
    object ImplicitsMsg {
      implicit val content="ScalaMsg"
    }
    
    object ImplicitAdance extends App {
    
      def printContent(implicit content:String)=println(content)
    //  implicit val msg="Spark" //有两个隐式参数的时候,就会出现冲突
      import Implicits.content //当你导入一个类的时候,连伴生对象的成员也会导入进来,
      //当明确指定需要导入哪个属性的时候,优先级会更高(当然不是隐式参数的情况)
      import ImplicitsMsg._
      printContent
    
    }
    
    

    非隐式参数不冲突,明确指定的导入方式优先级更高

    object Implicits {
      val content="Scala"
    }
    
    object ImplicitsMsg {
      val content="ScalaMsg"
    }
    
    object ImplicitAdance extends App {
    
      def printContent(implicit content:String)=println(content)
    //  implicit val msg="Spark" //有两个隐式参数的时候,就会出现冲突
      import Implicits.content //当你导入一个类的时候,连伴生对象的成员也会导入进来,
      //当明确指定需要导入哪个属性的时候,优先级会更高(当然不是隐式参数的情况)
      import ImplicitsMsg._
      printContent(content)
    
    }
    
    

    当然,当前作用域的优先级还是最高的:

    object Implicits {
      val content="Scala"
    }
    
    object ImplicitsMsg {
      val content="ScalaMsg"
    }
    
    object ImplicitAdance extends App {
    
      def printContent(implicit content:String)=println(content)
      val content="Spark" //有两个隐式参数的时候,就会出现冲突
      import Implicits.content //当你导入一个类的时候,连伴生对象的成员也会导入进来,
      //当明确指定需要导入哪个属性的时候,优先级会更高(当然不是隐式参数的情况)
      import ImplicitsMsg._
      printContent(content)
    
    }
    
    

    另外一个例子说明:

    object Implicits {
      implicit val content="Scala"
    }
    
    //object ImplicitsMsg {
    //  val content="ScalaMsg"
    //}
    
    object ImplicitAdance extends App {
    
      def printContent(implicit content:String)=println(content)
      val content="Spark" //有两个隐式参数的时候,就会出现冲突
      import Implicits.content //当你导入一个类的时候,连伴生对象的成员也会导入进来,
      //当明确指定需要导入哪个属性的时候,优先级会更高(当然不是隐式参数的情况)
    //  import ImplicitsMsg._
      printContent(content)
    
    }
    
    

    隐式转换能起到增强功能的作用

    class RichFile(val file:File) {
      def dtSpark=println("dySpark:"+file.getName)
    }
    
    object Implicits {
      implicit val content="Scala"
      implicit def int2String(x:Int)=x.toString()
      implicit def fileToRichFile(file:File)=new RichFile(file)
      implicit def richFileToFile(richFile:RichFile)=richFile.file //一般还会重新转换回来
    }
    
    object ImplicitAdance extends App {
    
      def printContent(implicit content:String)=println(content)
      val content="Spark" //有两个隐式参数的时候,就会出现冲突
      import Implicits._ //当你导入一个类的时候,连伴生对象的成员也会导入进来,
      //当明确指定需要导入哪个属性的时候,优先级会更高(当然不是隐式参数的情况)
    //  import ImplicitsMsg._
      printContent(content)
    
      printContent(100)
    
      (new File(".")).dtSpark
    
    }
    
    

    这是很有用的,例如我们只想在某一时刻用到一个类的功能,但不是一直都在使用,这时候使用隐式转换是非常有用的
    一般来说,隐式转换都会放到伴生对象中,这样有利于组织代码,例如Spark的RDD就是一个很好的例子
    在设计隐式转换的时候必须注意冲突的问题
    找出当前作用域中隐式参数的值

    println(implicitly[String])
    
    

    总结隐式转换的顺序:1.上下文 2.伴生对象 3.相关类型的伴生对象 4.导入

    归纳总结:1.隐式转换的几种类型
    2.隐式转换查找的顺序
    3.几个例子
    4.隐式转换的巨大作用和最佳实践
    5.implicitly[String]的作用


    cccc.png

    相关文章

      网友评论

          本文标题:第28课:Scala隐式转换内幕实践解密

          本文链接:https://www.haomeiwen.com/subject/zqkwsttx.html