隱式類別

語言
此文件頁面特定於 Scala 2 中發布的功能,這些功能已在 Scala 3 中移除或由替代方案取代。除非另有說明,否則此頁面中的所有程式碼範例都假設您使用的是 Scala 2。

在 Scala 3 中,隱式類別仍受支援以維持相容性,但建議使用 擴充方法 來達成相同的結果。


Josh Suereth

簡介

Scala 2.10 引入了稱為隱式類別的新功能。隱式類別是一個標示有 implicit 關鍵字的類別。此關鍵字讓類別的主建構函式在類別在範圍內時可供隱式轉換使用。

隱式類別在 SIP-13 中提出。

用法

若要建立隱式類別,只需在適當的類別前面加上 implicit 關鍵字。以下是範例

object Helpers {
  implicit class IntWithTimes(x: Int) {
    def times[A](f: => A): Unit = {
      def loop(current: Int): Unit =
        if(current > 0) {
          f
          loop(current - 1)
        }
      loop(x)
    }
  }
}

此範例建立隱式類別 IntWithTimes。此類別封裝 Int 值,並提供一個新方法 times。若要使用此類別,只需將其匯入範圍並呼叫 times 方法。以下是範例

scala> import Helpers._
import Helpers._

scala> 5 times println("HI")
HI
HI
HI
HI
HI

若要讓隱式類別運作,其名稱必須在範圍內且明確,就像任何其他隱式值或轉換一樣。

限制

隱含類別有以下限制

1. 它們必須定義在另一個 特質/類別/物件 內。

object Helpers {
   implicit class RichInt(x: Int) // OK!
}
implicit class RichDouble(x: Double) // BAD!

2. 它們在建構函式中只能接受一個非隱含引數。

implicit class RichDate(date: java.util.Date) // OK!
implicit class Indexer[T](collection: Seq[T], index: Int) // BAD!
implicit class Indexer[T](collection: Seq[T])(implicit index: Index) // OK!

雖然有可能建立一個有多個非隱含引數的隱含類別,但這些類別不會在隱含查詢期間使用。

3. 隱含類別 引進的 隱含 def 對於其他術語成員而言,不得產生歧義。

注意:這表示隱含類別不能是案例類別,因為 隱含 def 會與伴隨的 apply 產生歧義.

object Bar
implicit class Bar(x: Int) // BAD!

val x = 5
implicit class x(y: Int) // BAD!

implicit case class Baz(x: Int) // BAD!

此頁面的貢獻者