Scala 中 implicit 的使用
本文將討論 Scala 中 implicit
的不同用法。
implicit
作為 Scala 中的引數值注入器
在 Scala 中,隱式引數被傳遞給帶有 implicit
關鍵字的方法。
這些值取自呼叫它們的上下文(範圍)。簡單來說,如果沒有值或引數被傳遞給函式,那麼編譯器會尋找一個隱式
值並將其作為引數傳遞。
示例 1:
object MyClass {
def test(a:Int) = a
def main(args: Array[String]) {
test //calling the function but this gives error as no value is passed
}
}
這裡我們呼叫了一個函式,沒有傳遞任何引數值。這會導致錯誤。Scala 首先編譯它;它試圖傳遞一個值,但它不會得到引數的直接值。
示例 2:
object MyClass {
def test(implicit a:Int) = a
def main(args: Array[String]):Unit= {
test
}
}
這裡我們呼叫了一個帶有 implicit
關鍵字引數的函式。Scala 編譯器將在同一範圍內查詢具有相同值型別的任何 val
。
如果找到,則編譯成功;否則,我們會得到一個錯誤。因此,由於在同一型別的範圍內沒有值,因此上述程式會出錯。
示例 3:
object MyClass {
def test(implicit a:Int) = a
implicit val b:Int =789
def main(args: Array[String]):Unit= {
println(test)
}
}
輸出:
789
上面的程式碼執行成功是因為編譯器找到了一個與函式中的隱式引數 a
具有相同型別 int
的 implicit val
。
implicit
作為 Scala 中的型別轉換器
我們也可以使用 implicit
關鍵字來轉換一種資料型別。
我們在下面的程式碼中將 string
轉換為 int
型別。
object MyClass {
def main(args: Array[String]):Unit= {
val str :String = "hero"
val x:Int = str //we get error here
}
}
由於 string
不是 int
的子型別,它會出錯。Scala 編譯器在作用域中尋找一個以 string
作為引數並返回 int
的 implicit
函式。
這是另一個簡單的例子。
object MyClass {
implicit def myfunc(a:String):Int = 500
def main(args: Array[String]):Unit= {
val str :String = "hero"
val x:Int = str // the compiler treats this as myfunc(str) and return 500
println(x)
}
}
輸出:
500
上面的程式碼完美執行,因為當 Scala 編譯器查詢 implicit
函式時,它會找到 val x:Int = str
並將其視為 myfunc(str)
並返回 500。
implicit
作為 Scala 中的擴充套件方法
假設我們向整數物件新增一個新方法,將米轉換為釐米。我們在物件內部建立一個隱式類
來實現這一點。
這個隱式類將只有一個建構函式引數。
下面是一個完整的程式碼示例,可以更好地理解它是如何工作的。
object MyObject {
implicit class mtoCm(m:Int){
def mToCm={
m*100
}
}
}
我們可以使用下面的程式碼來實現它。
import MyObject._
object workspace {
def main(args: Array[String]):Unit= {
println(3.mToCm) //calling the mtoCm from MyObject
}
}
輸出:
300
這會匯入我們想要從上面的程式碼中使用的定義的隱式類
。