此文件頁面特定於 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!