Scala之Implicit的用法

     Scala在面對編譯出現類型錯誤時,提供了一個由編譯器自我修復的機制,編譯器試圖去尋找一個隱式implicit的轉換方法,轉換出正確的類型,完成編譯。這就是implicit 的意義。

一、 隱式轉換到某個期望類型

  • 用在方法上
class ImplicitToMethod

object ImplicitToMethod {

  //排除implicit的警告
  import scala.language.implicitConversions

  implicit def stringToInt(s: String): Int = Integer.parseInt(s)

  implicit def typeConversion(input: Int): String = input.toString

  implicit def typeConversion(input: Boolean): String = if (input) "true" else "false"

  def plus(x: Int, y: Int): Int = x + y

  def display(input: String): Unit = println(input)

  def apply: ImplicitToMethod = new ImplicitToMethod()
}
  • 測試
object ImplicitTest {
  def main(args: Array[String]): Unit = {
    //必須import隱式轉換的方法,否則出錯
    import ImplicitToMethod.typeConversion
    ImplicitToMethod.display("1212")
    //編譯時調用了隱式轉換
    ImplicitToMethod.display(12)
    ImplicitToMethod.display(true)

    import ImplicitToMethod.stringToInt
    //編譯時調用了隱式轉換
    val result = ImplicitToMethod.plus("3", "2")
    println(result)
  }
}

二、 隱式參數和隱式值形式

  • 隱式參數

              在函數中,將參數標誌出implicit,形式爲:

def func(implicit x: Int)
def func2(x: Int)(implicit y: Int)
def func3(implicit x: Int, y: Int)

             這三種形式是有區別的,在參數中implicit只能出現一次,而在此之後,所有的參數都會變爲implicit

  • 隱式值
implicit object Test
implicit val x = 5
implicit var y
  • 作用

        這種用法的作用主要是兩種用法搭配起來來達到一個效果,隱式參數表明這個參數是可以缺少的,也就是說在調用的時候這個參數可以不用出現,那麼這個值由什麼填充呢? 那就是用隱式的值。

object ImplicitToValue {
  
  def funImplicit1(implicit age: Int): Unit = {
    println("funImplicit1: age: " + age)
  }

  def funImplicit2(implicit age: Int, name: String): Unit = {
    println("funImplicit2: age: " + age + ", name:" + name)
  }

  def funImplicit3(age: Int)(implicit name: String): Unit = {
    println("funImplicit3: age: " + age + ", name:" + name)
  }
}
  • 測試
object ImplicitTest {
  def main(args: Array[String]): Unit = {
    implicit val impAge = 30
    implicit val implName = "Jack"

    funImplicit1
    funImplicit2
    funImplicit3(31)

  }
}

三、 隱式類

  • 形式
implicit class MyClass(x: Int)
  • 作用

       這裏的作用主要是其主構造函數可以作爲隱式轉換的參數,相當於其主構造函數可以用來當做一個implicit的function

class ImplicitToClass

object ImplicitToClass {

  implicit class MyName(x: Int) {
    val y = x
    println("Test implicit class")
  }

  def say(x: MyName): Unit = {
    println(x.y)
  }
}
  •  測試
object ImplicitTest {
  def main(args: Array[String]): Unit = {
   say(5)
  }
}

 這裏的MyName是一個隱式類,其主構造函數可以用作隱式轉換,所以say需要一個MyName類型的參數,但是調用的時候給的是一個Int,這裏就會調用MyName的主構造函數轉換爲一個MyName的對象,然後再println其y的值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章