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方法