使用隱含轉(zhuǎn)換將變量轉(zhuǎn)換成預(yù)期的類型是編譯器最先使用 implicit 的地方。這個規(guī)則非常簡單,當編譯器看到類型X而卻需要類型Y,它就在當前作用域查找是否定義了從類型X到類型Y的隱式定義。
比如,通常情況下,雙精度實數(shù)不能直接當整數(shù)使用,因為會損失精度:
scala> val i:Int = 3.5
<console>:7: error: type mismatch;
found : Double(3.5)
required: Int
val i:Int = 3.5
^
當然你可以直接調(diào)用 3.5.toInt。
這里我們定義一個從 Double 到 Int 的隱含類型轉(zhuǎn)換的定義,然后再把 3.5 賦值給整數(shù),就不會報錯。
scala> implicit def doubleToInt(x:Double) = x toInt
doubleToInt: (x: Double)Int
scala> val i:Int = 3.5
i: Int = 3
此時編譯器看到一個浮點數(shù) 3.5,而當前賦值語句需要一個整數(shù),此時按照一般情況,編譯器會報錯,但在報錯之前,編譯器會搜尋是否定義了從 Double 到 Int 的隱含類型轉(zhuǎn)換,本例,它找到了一個 doubleToInt。 因此編譯器將把
val i:Int = 3.5
轉(zhuǎn)換成
val i:Int = doubleToInt(3.5)
這就是一個隱含轉(zhuǎn)換的例子,但是從浮點數(shù)自動轉(zhuǎn)換成整數(shù)并不是一個好的例子,因為會損失精度。 Scala 在需要時會自動把整數(shù)轉(zhuǎn)換成雙精度實數(shù),這是因為在 Scala.Predef 對象中定義了一個
implicit def int2double(x:Int) :Double = x.toDouble
而 Scala.Predef 是自動引入到當前作用域的,因此編譯器在需要時會自動把整數(shù)轉(zhuǎn)換成 Double 類型。