scala(4):implicit關鍵字
- 2019 年 10 月 4 日
- 筆記
掌握implicit的用法是閱讀spark源碼的基礎,也是學習scala其它的開源框架的關鍵,implicit 可分為:
- 隱式參數
- 隱式轉換類型
- 隱式調用函數
1.隱式參數
當我們在定義方法時,可以把最後一個參數列表標記為implicit,表示該組參數是隱式參數。一個方法只會有一個隱式參數列表,置於方法的最後一個參數列表。如果方法有多個隱式參數,只需一個implicit修飾即可。 當調用包含隱式參數的方法是,如果當前上下文中有合適的隱式值,則編譯器會自動為改組參數填充合適的值。如果沒有編譯器會拋出異常。當然,標記為隱式參數的我們也可以手動為該參數添加默認值。def foo(n: Int)(implicit t1: String, t2: Double = 3.14)
scala > def calcTax(amount: Float)(implicit rate: Float): Float = amount * rate scala > implicit val currentTaxRate = 0.08F scala > val tax = calcTax(50000F) // 4000.0
123
如果編譯器在上下文沒有找到第二行程式碼會報錯
2.隱式地轉換類型
使用隱含轉換將變數轉換成預期的類型是編譯器最先使用 implicit 的地方。這個規則非常簡單,當編譯器看到類型X而卻需要類型Y,它就在當前作用域查找是否定義了從類型X到類型Y的隱式定義 例子:
scala> val i: Int = 3.5 //直接報錯 加上這句: scala> implicit def double2Int(d: Double) = d.toInt 再運行,沒報錯 scala> val i: Int = 3.5 //i=3
123456
3.隱式調用函數
隱式調用函數可以轉換調用方法的對象,比如但編譯器看到X .method,而類型 X 沒有定義 method(包括基類)方法,那麼編譯器就查找作用域內定義的從 X 到其它對象的類型轉換,比如 Y,而類型Y定義了 method 方法,編譯器就首先使用隱含類型轉換把 X 轉換成 Y,然後調用 Y 的 method。 例子:
class SwingType{ def wantLearned(sw : String) = println("兔子已經學會了"+sw) } object swimming{ implicit def learningType(s : AminalType) = new SwingType } class AminalTypeobject AminalType extends App{ import com.mobin.scala.Scalaimplicit.swimming._ val rabbit = new AminalType rabbit.wantLearned("breaststroke") //蛙泳 }
123456789101112
上例中編譯器在rabbit對象調用時發現對象上並沒有wantLearning方法,此時編譯器就會在作用域範圍內查找能使其編譯通過的隱式視圖,找到learningType方法後,編譯器通過隱式轉換將對象轉換成具有這個方法的對象,之後調用wantLearning方法