首页 > 代码库 > scala implicit 学习简记

scala implicit 学习简记

1 什么情况下会发生隐式转化

总的来说就是定义了,用到了。详细情况用下面几个例子来演示。

1.1 第一种情况

package com.cma.implicits


import java.io.File


object ImplicitsWhen {


  def main(args: Array[String]): Unit = {
    //定义并导入两个隐式转化函数,如果需要,扩展的方法可以直接被file对象使用
    implicit def file2FirstRichFile(file: File) = new FirstRichFile(file)
    implicit def file2SecondRichFile(file: File) = new SecondRichFile(file)
    val file = new File("E:\\hosts.txt")
    //调用第一个隐式转化
    println(file.readAllLine)
    //调用第二个隐式转化,然后再调用第一个隐式转化
    println(file.showAllLine.readAllLine)
  }
  class FirstRichFile(file: File) {
    println("进入FirstRichFile ... ")
    def readAllLine = scala.io.Source.fromFile(file).mkString
  }
  class SecondRichFile(file: File) {
    println("进入SecondRichFile ...")
    def showAllLine = {
      println(scala.io.Source.fromFile(file).mkString)
      //SecondRichFile object 隐式转化后的对象
      //this
      //File object,隐式转化之前的对象。目的是进行链式操作
      file
    }
  }


}

1.2 第二种情况

package com.cma.implicits


object ImplicitWhenSecond {


  def main(args: Array[String]): Unit = {
    /*
     * sqrt求平方根这个方法的输入是Double类型,
     * 下面的代码会把整形4先转化为Double
     */
    val sqrt = scala.math.sqrt(4)
    println(sqrt)
  }


}

1.3 第三种情况

package com.cma.implicits


object DefaultValue {


  def main(args: Array[String]): Unit = {
    implicit val from : String = "unknown"
    val content : String = "hello,baby!"
    readLetter(content)
  }
  def readLetter(content : String)(implicit from : String) = {
    println(content)
    println(from)
  }


}

package com.cma.implicits


object ClassAsDefaultValue {


  def main(args: Array[String]): Unit = {
    val user = User(1 , "flankwang")
    implicit val livingCost = new LivingCost(850 , 300 , 1500)
    implicit val xxx = "QQ"
    showLivingCost(user)
  }
  def showLivingCost(user : User)(implicit livingCost : LivingCost , xxx : String) = {
    println("用户 : " + user.name + user.id + "月预算清单 : ")
    println("rent :" + livingCost.rent + ", traffic : " + livingCost.traffic +",food : " +livingCost.food)
    println(xxx)
  }
  case class User(id : Int , name : String)
  
  case class LivingCost(rent : Int , traffic : Int , food : Int)
  
}

1.4 第四种情况(context bond使用)

package com.cma.implicits


object ContextBound {


  def main(args: Array[String]): Unit = {
    println(smaller(1)(2))
    println(smaller(new User(1))(new User(2)))
  }
  /**
   * first : 第一个参数
   * second : 第二个参数
   * order : 一个隐式转化函数,输入是T,输出是Ordered[T]
   * 这也是ContextBound的概念。
   * first second 需要比较大小,但是二者中都没有"<"这样的操作。怎么办呢?,T是没有,
   * 但是Ordered[T]中有,只要我们把T =>Ordered[T]不就可以了吗。
   * 对,我们这里就是这样干的。
   * 还有一点很重要 Ordered[T]是一个trait,集成了JAVA的Comparable,重写compareTo
   * (def compareTo(that: A): Int = compare(that)),这里compare是一个抽象方法
   * 。<   > 等等方法的定义中使用到了compare.这就要求我们的T实现compare抽象方法
   */
  def smaller[T](first : T)(second : T)(implicit order : T => Ordered[T]) = {
    if(first < second) first else second
  }


  /**
   * id : 用户ID编号
   * val id : Int,这里之所以用val ,是为了让that也可以访问id
   */
  class User(val id : Int ) extends Ordered[User]{
    def compare(that: User): Int = {
      if (this.id < that.id)  1 else if(this.id == that.id) 0 else -1
    }
    override def toString() = {
      "userId : "+ id
    }
  }
  
}

scala implicit 学习简记