Scala 中 implicit 的使用

Suraj P 2023年1月30日
  1. implicit 作為 Scala 中的引數值注入器
  2. implicit 作為 Scala 中的型別轉換器
  3. implicit 作為 Scala 中的擴充套件方法
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 具有相同型別 intimplicit 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 作為引數並返回 intimplicit 函式。

這是另一個簡單的例子。

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

這會匯入我們想要從上面的程式碼中使用的定義的隱式類

作者: Suraj P
Suraj P avatar Suraj P avatar

A technophile and a Big Data developer by passion. Loves developing advance C++ and Java applications in free time works as SME at Chegg where I help students with there doubts and assignments in the field of Computer Science.

LinkedIn GitHub