• scala隐式转换


    Scala提供的隐式转换的特性的作用,简单说就是:当Scala编译器进行类型匹配时,如果找不到合适的类型,那么隐式转换会让编译器在作用范围内自动推导出合适的类型,在代码重构设计上,可以避免冗余的代码,使得代码非常优雅。

        使用场景一:隐式参数

    scala>  def sayHello(age: Int)(implicit name: String) = println("my name is:" + name + ",my age is:" + age)
    sayHello: (age: Int)(implicit name: String)Unit
    
    scala> implicit val name = "cyony"
    name: String = cyony
    
    scala> sayHello(25)
    my name is:cyony,my age is:25

        sayHello函数有两个参数,其中name为隐式参数,在实际调用中不需要显示传入这个参数,但是在作用域范围内必须声明一个String类型的隐式变量,这样在调用的时候,会自动传入这个变量。PS:如果在同一个作用域内定义了两个同类型的隐式变量,则会有冲突。

        隐式参数的作用域范围有两个:一种是当前作用域内可见的val或者var定义的隐式变量;一种是隐式参数类型的伴生对象内的隐式值。

    scala> implicit val name1 = "cyony1"
    name1: String = cyony1
    
    scala> sayHello(25)
    <console>:16: error: ambiguous implicit values:
     both value name of type => String
     and value name2 of type => String
     match expected type String
           sayHello(25)
                   ^

        使用场景二:类型匹配

    scala> import scala.language.implicitConversions
    import scala.language.implicitConversions
     
    scala> implicit def int2Range(num : Int): Range = 1 to num
    int2Range: (num: Int)Range
     
    scala> def spreadNum(range: Range): String = range.mkString(",")
    spreadNum: (range: Range)String
     
    scala> spreadNum(5)
    res0: String = 1,2,3,4,5

      上面所示,spreadNum函数签名是个Range类型的参数,但是传入的值是一个Int类型的,所以编译器在作用域内找到了int2Range隐式转换函数,自动将int转换为range对象来适配。

      隐式转换的函数叫什么名字无所谓,因为实际调用中不会手动调用,但是如果需要使用隐式转换函数,需要import方式手动导入,才能被编译器寻找到。

        使用场景三:类型增强

    scala> class Man(val name: String)
    defined class Man
     
    scala> class SuperMan(val name: String) {
         |     def fly = println("you can fly")
         |   }
    defined class SuperMan
     
    scala>  implicit def man2SuperMan(man: Man): SuperMan = new SuperMan(man.name)
    man2SuperMan: (man: Man)SuperMan
     
    scala> val cyony = new Man("cyony")
    cyony: Man = Man@63d3c9dc
     
    scala> cyony.fly
    you can fly

      编译器在调用fly方法时,发现Man对象并没有这个函数,然后通过man2SuperMan隐式函数转换成SuperMan对象,进而调用他的fly函数,来实现类型增强功能。

           或者可以通过隐式类的方式来实现相同的功能,代码如下:

    scala> class Man(name: String)
    defined class Man
     
    scala> implicit class MyImplicitTypeConversion(val man: Man) {
         |     def fly = println("you can fly")
         |   }
    defined class MyImplicitTypeConversion
     
    scala> val cyony = new Man("cyony")
    cyony: Man = Man@7412a438
     
    scala> cyony.fly
    you can fly

        隐式转换的发生时机:

        1、调用某个函数,但是给函数传入的参数类型,与函数定义的签名不匹配。

        2、使用某个类型对象,调用某个方法,而这个方法并不存在于该类型时。

        3、使用某个类型对象,调用某个方法,虽然该类型有这个方法,但是给方法传入的参数类型与签名并不一致的时候。

    转载博客:https://blog.csdn.net/cyony/article/details/79616013

  • 相关阅读:
    c#9
    Jmeter--自己写并发压测脚本一定会遇到的类
    Jmeter从数据库获取测试数据, 作为下一个接口参数方法
    Jmeter-从数据库中获取数据并作为变量传输
    Java文件操作
    Java读取文件
    Java字符串处理——String类常用方法
    Eclipse导出可执行jar包步骤
    批处理常用DOS命令之for简单 002
    批处理常用DOS命令之for简单 001
  • 原文地址:https://www.cnblogs.com/guoyu1/p/12309856.html
Copyright © 2020-2023  润新知