Scala - 隱式轉換

有時候咱們看scala代碼的時候,會發現明明沒有這個類的類型或者函數,甚至是沒有這個類,編譯器不只沒有報錯,程序還能夠正常運行,其實這裏就用到了scala的隱式轉換。函數

隱式函數

當咱們調用一個對象的方法的時候,可是這個對象並無這個方法,此時就會觸發隱式轉換,會把這個對象偷偷的轉換爲具備這個方法的對象。
好比下面的例子,小雞能夠走路也能夠跑,可是它也想像小鳥同樣飛,可是它有沒有這個功能。咱們能夠在不對小雞整改的基礎上,引入ChickenImplicit,讓小雞能夠隱式的調用Bird的fly方法,讓它能夠像小鳥同樣飛。scala

object ImplicitDemo1 {
  def main(args: Array[String]): Unit = {
    import ChickenImplicit._
    val chicken = new Chicken()
    chicken.work()
    chicken.run()
    // 隱式轉爲Bird,並調用Bird的fly方法
    chicken.fly()
  }
}

class Chicken() {
  def work(): Unit = {
    println("小雞在走")
  }

  def run(): Unit = {
    println("小雞在跑")
  }
}

class Bird {
  def fly(): Unit = {
    println("小鳥在飛")
  }
}

object ChickenImplicit {
  implicit def chicken2Bird(c: Chicken): Bird = new Bird()
}

上面是額外的定義ChickenImplicit,可是有時候咱們能夠直接在同一個類裏定義,這樣局不用加import,具體用哪一種仍是要看實際場景。code

object ImplicitDemo2 {
  def main(args: Array[String]): Unit = {
    val chicken = new Chicken2()
    chicken.work()
    chicken.run()
    // 隱式轉爲Bird,並調用Bird的fly方法
    chicken.fly()
  }

  implicit def chicken2Bird(c: Chicken2): Bird2 = new Bird2()
}

class Chicken2() {
  def work(): Unit = {
    println("小雞在走")
  }

  def run(): Unit = {
    println("小雞在跑")
  }
}

class Bird2 {
  def fly(): Unit = {
    println("小鳥在飛")
  }
}

隱式參數

好比咱們要調用方法,打印咱們傳遞的參數,咱們是這樣寫的:對象

def main(args: Array[String]): Unit = {
    printInfo1("aaa") // aaa
}

def printInfo1(str: String): Unit = {
    println(str)
}

若是咱們調用方法的時候,若是不想傳遞參數,咱們能夠這樣:
在方法裏指定默認值ci

def main(args: Array[String]): Unit = {
    printInfo2("bbb") // bbb
    printInfo2() // default
}

def printInfo2(str: String = "default"): Unit = {
    println(str)
}

若是經過隱式參數,那咱們就能夠這樣:
這裏的方法不加括號也是能夠的。因爲是經過類型來匹配隱式值的,因此在一個做用域中,同一個類型只能有一次,而且他的優先級高於默認的,因此沒有傳遞參數的時候,打印的implicit。作用域

def main(args: Array[String]): Unit = {
    implicit val str: String = "implicit"
    printInfo3("ccc") // ccc
    printInfo3() // default
    printInfo3 // implicit
}

def printInfo3(implicit str: String = "default"): Unit = {
    println(str)
}

總結

當咱們須要隱式轉換的時候,咱們就須要用implicit關鍵字。
隱式轉換的時候,他會先全局的查找是否有匹配的方法或者參數,若是沒有再考慮隱式轉換。
因爲隱式參數是根據類型的,因此同一做用域不能定義多個同一個類型的,而且默認值是優先於默認的。編譯器

相關文章
相關標籤/搜索