隱式類(Implicit Classes)
Josh Suereth
介紹
Scala 2.10引入了一種叫做隱式類的新特性。隱式類指的是用implicit關鍵字修飾的類。在對應的作用域內,帶有這個關鍵字的類的主構造函數可用於隱式轉換。
隱式類型是在SIP-13中提出的。
用法
創建隱式類時,只需要在對應的類前加上implicit關鍵字。比如:
object Helpers {
implicit class IntWithTimes(x: Int) {
def times[A](/DOC_Scala/chinese_scala_offical_document/file/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
使用隱式類時,類名必須在當前作用域內可見且無歧義,這一要求與隱式值等其他隱式類型轉換方式類似。
限制條件
隱式類有以下限制條件:
- 只能在別的trait/類/對象內部定義。
object Helpers {
implicit class RichInt(x: Int) // 正確!
}
implicit class RichDouble(x: Double) // 錯誤!
- 構造函數只能攜帶一個非隱式參數。
implicit class RichDate(date: java.util.Date) // 正確! implicit class Indexer[T](collecton: Seq[T], index: Int) // 錯誤! implicit class Indexer[T](collecton: Seq[T])(implicit index: Index) // 正確!
雖然我們可以創建帶有多個非隱式參數的隱式類,但這些類無法用於隱式轉換。
- 在同一作用域內,不能有任何方法、成員或對象與隱式類同名。
注意:這意味着隱式類不能是case class。
object Bar
implicit class Bar(x: Int) // 錯誤!
val x = 5
implicit class x(y: Int) // 錯誤!
implicit case class Baz(x: Int) // 錯誤!