Scala的隐式转化

一、简介

    为现有的类库增加功能的一种方式,用java的话,只能用工具类或者继承的方式来实现,而在scala则采用隐式转化的方式来实现。

● scala隐式转换可以把一个类的实例当作另一个类的实例,这样一来,通过在facade里隐式封装实例,无需修改原来的类,就可以将方法附着于对象上。这种技巧可以用于创建DSL。

● 在Predef对象里,scala定义了一些隐式转换,scala默认导入它们,这样的话,比如写1 to 3时,scala会隐式将1从Int转换为RichInt类型,然后调用to()方法

● scala一次至多应用一个隐式转换,在当前范围内,如果发现通过类型转换有助于操作、方法调用或类型转换的成功完成,就会进行转换,不再继续往外找。


A、位于源或者目标类型的companion object中的隐式函数

B、位于当前作⽤用域可以以单个标识符指代的隐式函数


额外说明:

A、如果代码能在不使用隐式转换的前提下通过编译,则不会使用隐式转换

B、编译器不会同时使用多个隐式转换

C、 存在二义性的隐式转换不被允许


二、使用方式

1、定义转换类,以及隐式转换方法

2、scala 2.10 以后可以直接定义隐式类

     A、必须定义在另外一个class/object/trait里头

     B、构造器中只能带一个不是implicit类型的参数

     C、作用域中不能有与隐式类类名相同的成员变量/函数名/object名

3、隐式参数


三、实例

1、隐式转化方法

package persia.demo

object Implicit {

  def main(args: Array[String]): Unit = {
     import java.util._
     
     class DateHelper(number: Int){
        def days(when: String): Date={
           var date = Calendar.getInstance()
           when match{
             case "ago" => date.add(Calendar.DAY_OF_MONTH,-number)
             case "from_now" => date.add(Calendar.DAY_OF_MONTH,number)
             case _ => date
           }
           date.getTime()
        }
     }
     //只要该方法在当前范围内存在(通过当前import可见或是位于当前文件)
     //scala就会自动调用它,将int转换为DateHelper实例然后调用days方法
     implicit def convertInt2DateHelper(number: Int) = new DateHelper(number) 
     
     val past = 2 days "ago"
     println(past)
     val appointment = 5 days "from_now"
     println(appointment)
  }

}

  或者

class RichFile(val file:File){
   def read = Source.fromFile(file.getPath()).mkString
}

object Context{
    implicit def file2RichFile(f:File)= new RichFile(f)
}

object ImplicitDemo extends App{
   import Context.file2RichFile
   println(new File("f:\\create.sql").read)   
}


2、隐式参数

object Context{
    implicit val ccc:String = "implicit"
}

object Param{
   def print(content:String)(implicit prefix:String){
      println(prefix+":"+content)
   }
}

object ImplicitDemo extends App{
    Param.print("jack")("hello")
    
    import Context._
    Param.print("jack")
}


3、隐式类

object Context{
    implicit def file2RichFile(f:File)= new RichFile(f)
    implicit val ccc:String = "implicit"
    implicit class Op(x:Int){
         def add2 = x+2
    }
}

object ImplicitDemo extends App{
    import Context._
    println(1.add2)
}


四、扩展

1、隐式转化扩展

class RichFile(val file:File){
   def read = Source.fromFile(file.getPath()).mkString
}

object Context{
    implicit def file2RichFile(f:File)= new RichFile(f)
}

object ImplicitDemo extends App{
   import Context.file2RichFile
   println(new File("f:\\create.sql").read)   
}


2、隐式类扩展

import java.io.File
import scala.io.Source

object Helper{  
    implicit class FileEnhancer(f : File){    
        def read(file : File) = Source.fromFile(file.getPath).mkString  
    }
}

object Demo2 extends App{  
    import Helper._  
    val f = new File("your file path")  
    f.read
}


3、隐式参数扩展

import java.io.File

object Demo3 extends App{  
   //RichFile is already defined in Demo1.scala  
   def _read(f : File)(implicit file : File => RichFile){    
      f.read 
   }
}


你可能感兴趣的:(Scala的隐式转化)