Cris 的 Scala 筆記整理(十):隱式轉換

10. 隱式轉換

隱式轉換函數是以implicit關鍵字聲明的帶有單個參數的函數。這種函數將會自動應用,將值從一種類型轉換爲另外一種類型oracle

① 隱式轉換最佳入門案例

首先看下面的代碼函數

若是想要轉換成功,就須要藉助隱式轉換函數spa

爲了更好的理解,咱們看看反編譯後的字節碼文件,底層編譯器是如何隱式轉換函數的scala

根據需求咱們能夠將任意數據類型的對象轉換爲咱們想要的數據類型,以及進行處理3d

implicit def func2(num: Long): Int = {
  (num - 1).toInt
}

val num2: Int = 10L
println(num2) // 9
複製代碼

② 隱式轉換的細節

  1. 隱式轉換函數的函數名能夠是任意的,隱式轉換與函數名稱無關,只與函數簽名(函數參數類型和返回值類型)有關。code

  2. 隱式函數能夠有多個(即:隱式函數列表),可是須要保證在當前環境下,只有一個隱式函數能被識別cdn

③ 強悍的隱式轉換豐富類庫功能

若是須要爲一個類增長一個方法,能夠經過隱式轉換來實現。(動態增長功能)好比想爲 Oracle 類增長一個 delete 方法對象

看看底層編譯器的魔術blog

細節ci

在當前程序中,若是想要給 Oracle 類增長功能是很是簡單的,可是在實際項目中,若是想要增長新的功能就會須要改變源代碼,這是很難接受的。並且違背了軟件開發的 OCP 開發原則

在這種狀況下,能夠經過隱式轉換函數給類動態添加功能

④ 隱式值

隱式值也叫隱式變量,將某個形參變量標記爲implicit,因此編譯器會在方法省略隱式參數的狀況下去搜索做用域內的隱式值做爲缺省參數

示例代碼

細節練習

  • 如下代碼的函數命名編譯器如何定義

看看底層編譯器的字節碼文件

  • 隱式值細節

    總結

    1. 隱式值的優先級高於默認值

    2. 當匹配到多個隱式值就會報錯

⑤ 隱式類

Scala2.10 後提供了隱式類,可使用 implicit 聲明類,隱式類的很是強大,一樣能夠擴展類的功能,比前面使用隱式轉換豐富類庫功能更加的方便,在集合中隱式類會發揮重要的做用

示例代碼

object Main {
  def main(args: Array[String]): Unit = {

    // 隱式類會獨立生成一個 .class 文件,還會在當前 Main 類生成一個轉換函數
    implicit class Driver(oracle: Oracle) {
      def add(): Unit = {
        println("Driver add")
      }
    }
    val oracle = new Oracle
    // 實質上是調用了轉換函數生成一個隱式類對象來調用 add 方法
    oracle.add() // Driver add
    oracle.func() // Oracle func
  }
}

class Oracle {
  def func(): Unit = {
    println("Oracle func")
  }
}
複製代碼

隱式類的特色

  1. 其所帶的構造參數有且只能有一個

  2. 隱式類必須被定義在 伴生對象包對象 裏,即隱式類不能是 頂級的(top-level objects)

  3. 隱式類不能是 case class(類型匹配)

  4. 做用域內不能有與之相同名稱的標示符

⑥ 隱式轉換時機

  1. 當方法中的參數的類型與目標類型不一致時

  2. 當對象調用所在類中不存在的方法或成員時,編譯器會自動將對象進行隱式轉換(根據類型)

隱式轉換解析規則(瞭解)

隱式轉換前提

  1. 不能存在二義性

  2. 隱式操做不能嵌套

相關文章
相關標籤/搜索