美文网首页
spark(二) scala復雜語法之隱士轉換

spark(二) scala復雜語法之隱士轉換

作者: 文子轩 | 来源:发表于2018-08-20 22:34 被阅读25次

    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> 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(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
    

    隐式转换的发生时机:

    1、调用某个函数,但是给函数传入的参数类型,与函数定义的签名不匹配。
    
    2、使用某个类型对象,调用某个方法,而这个方法并不存在于该类型时。
    
    3、使用某个类型对象,调用某个方法,虽然该类型有这个方法,但是给方法传入的参数类型与签名并不一致的时候。
    

    相关文章

      网友评论

          本文标题:spark(二) scala復雜語法之隱士轉換

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