zoukankan      html  css  js  c++  java
  • 有趣的隐式转换【scala】

    写在前面

    好久没有更新文章了,今天简单写写源于scala中比较有意思的隐式转换。
    在java中,我们如果需要为某个特定的类新增一个方法,即:功能增强,大致有几种方式:

    1. 继承
    2. 装饰器
    3. 代理(静态动态)

    那么,在scala中,这个就可以使用隐式转换来达到。

    隐式转换:

    大致就是为类添加新方法,大致流程:
        为某一个特定的类Dog,
        写一个增强类RichDog(里面添加新方法),
        写一个隐式声明 implicit def dogToRichDog(dog:Dog):RichDog = new RichDog(dog.name),
        在特定的类需要使用到新方法之前,import 这个隐式声明之后就可以get到
    
    
    对类功能进行增强,表面看不出来
    
    比如:RDD.scala 源文件中就有大量的隐式转换,常见的reduceByKey方法 算子 其实本身不是自己定义的,而是增强而来
    

    两个案例

    案例一:增强自己定义的类

    简单说明:Dog本身没有speak方法,但是这里的话,需要隐式声明一下 :

           implicit def dogToRichDog(dog:Dog):RichDog = new RichDog(dog.name)
    

    这样Dog就能使用RichDog里面的方法,scala中其实RichDog本不是Dog的子类,但是import 这个隐式声明之后就可以get到

    相当于父类调用子类对象,java可以直接用,这里需要手动import 隐式声明
    /**
      * Description:
      * 隐式转换:
      *   偷偷的增强,为类添加新的方法,表面看不出来
      *
      *
      * @Author: 留歌36
      * @Date: 2019/9/16 11:58
      */
    object ImplicitDogApp {
      def main(args:Array[String]): Unit = {
    
        implicit def dogToRichDog(dog:Dog):RichDog = new RichDog(dog)
    
        val dog = new Dog("小奶狗")
        dog.speak()
    
      }
    
    }
    class Dog(val name:String){
    
    }
    class RichDog(val dog:Dog){
    
    
     def speak() = {
        println(s"你好,我的名字是:${dog.name}")
      }
    }
    
    

    案例二 增强java.io.File

    简单说明:java.io.File 这个类本身没有read这个方法,通过自己编写一个RichFile 增强File的功能

    import java.io.File
    
    import scala.io.Source
    
    
    /**
      * Description: TODO
      *
      * @Author: 留歌36
      * @Date: 2019/9/16 12:04
      */
    object ImplicitFileApp {
      def main(args:Array[String]): Unit ={
        import ImplicitAspect.fileToRichFile
    
        val file = new File("f:/hello.txt")
        val context = file.read()
        println(context)
    
      }
    
    }
    class RichFile(val file:File) {
    
      def read(): String ={
        Source.fromFile(file.getPath).mkString
      }
    
    }
    

    注意上面的是: import ImplicitAspect.fileToRichFile ,其实这里是写了一个隐式转换的切面类 的意思,当你的隐式声明变多之后,这样方便统一管理。定义的切面类:ImplicitAspect 如下:

    import java.io.File
    
    /**
      * Description: TODO
      *
      * @Author: 留歌36
      * @Date: 2019/9/16 12:11
      */
    object ImplicitAspect {
       implicit def fileToRichFile(file:File):RichFile = new RichFile(file)
       implicit def dogToRichDog(dog:Dog):RichDog = new RichDog(dog)
    }
    
    

    拓展一:隐式参数

    /**
      * Description:
      * 隐式参数: 生产上不建议使用
      * 指的是在函数或者方法中,定义一个用implicit修饰的参数
      * 此时:scala会尝试找到一个指定类型的,用implicit 修饰的
      * 对象,即 隐式值,并注入参数
      *
      * @Author: 留歌36
      * @Date: 2019/9/16 15:26
      */
    object ImplicitParamApp {
      def main(args: Array[String]): Unit = {
       def  testParam(implicit name:String): Unit = {
         println(name + "~~~~~~~~~~~~")
       }
        // 测试1. 在没有定义  implicit val name 之前,需要显示的进行传参
    //    testParam("留歌36")
    
        // 测试2.定义一个用implicit修饰的参数
    //    implicit val name1 = "留歌36"
        // 这时,不用传递参数,测试OK
        testParam
    
        // 测试3:定义多个String类型的implicit修饰的参数
        implicit val name2 = "留歌36"
        implicit val name3 = "留歌37"
        // 测试不Ok,因为编译器不知道该使用哪一个
        testParam
        
      }
    
    }
    

    拓展二:隐式类

    /**
      * Description: 隐式类
      *   是指对类增加 implicit 关键字
      *   作用:对类的增强
      *
      * @Author: 留歌36
      * @Date: 2019/9/16 15:34
      */
    object ImplicitClassApp {
      def main(args: Array[String]) : Unit = {
    
        // class Calculator(x:Int)这个类中 对于Int 类型的值,我们都是可以拥有 本个类中定义的方法的
        implicit  class Calculator(x:Int){
            def add(a:Int)={
               a + x
            }
        }
    
        println(1.add(3))
    
      }
    
    
    }
    
    

    ok,到这里就结束啦。有任何问题,可以留言告诉我~

  • 相关阅读:
    单片机I/O口推挽与开漏输出详解(力荐)
    wifi
    SDIO总线协议
    [hi3521] nand flash 的 boot 启动模式的区别?
    常见SOC启动流程分析
    PWM通过RC低通滤波器模拟DAC
    海思 core 电压动态调整
    USB线上/串口/I2C引脚串联电阻的作用
    几种flash存储芯片的用途和分类
    示波器分析I2C时序波形图
  • 原文地址:https://www.cnblogs.com/liuge36/p/12614721.html
Copyright © 2011-2022 走看看