隱式轉換函數是以implicit關鍵字聲明的帶有單個參數的函數。這種函數將會自動應用,將值從一種類型轉換爲另外一種類型oracle
首先看下面的代碼函數
若是想要轉換成功,就須要藉助隱式轉換函數spa
爲了更好的理解,咱們看看反編譯後的字節碼文件,底層編譯器是如何隱式轉換函數的scala
根據需求咱們能夠將任意數據類型的對象轉換爲咱們想要的數據類型,以及進行處理3d
implicit def func2(num: Long): Int = {
(num - 1).toInt
}
val num2: Int = 10L
println(num2) // 9
複製代碼
隱式轉換函數的函數名能夠是任意的,隱式轉換與函數名稱無關,只與函數簽名(函數參數類型和返回值類型)有關。code
隱式函數能夠有多個(即:隱式函數列表),可是須要保證在當前環境下,只有一個隱式函數能被識別cdn
若是須要爲一個類增長一個方法,能夠經過隱式轉換來實現。(動態增長功能)好比想爲 Oracle
類增長一個 delete
方法對象
看看底層編譯器的魔術
blog
細節ci
在當前程序中,若是想要給 Oracle
類增長功能是很是簡單的,可是在實際項目中,若是想要增長新的功能就會須要改變源代碼,這是很難接受的。並且違背了軟件開發的 OCP
開發原則
在這種狀況下,能夠經過隱式轉換函數給類動態添加功能
隱式值也叫隱式變量,將某個形參變量標記爲implicit,因此編譯器會在方法省略隱式參數的狀況下去搜索做用域內的隱式值做爲缺省參數
示例代碼
細節練習
看看底層編譯器的字節碼文件
隱式值細節
總結
隱式值的優先級高於默認值
當匹配到多個隱式值就會報錯
在 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")
}
}
複製代碼
隱式類的特色
其所帶的構造參數有且只能有一個
隱式類必須被定義在 類
或 伴生對象
或 包對象
裏,即隱式類不能是 頂級的(top-level objects
)
隱式類不能是 case class
(類型匹配)
做用域內不能有與之相同名稱的標示符
當方法中的參數的類型與目標類型不一致時
當對象調用所在類中不存在的方法或成員時,編譯器會自動將對象進行隱式轉換(根據類型)
隱式轉換解析規則(瞭解)
隱式轉換前提
不能存在二義性
隱式操做不能嵌套