此文档页面特定于 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. 它们必须在另一个 trait
/class
/object
内定义。
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. implicit class
引入的 implicit def
对于其他项成员来说不能模棱两可。
注意:这意味着隐式类不能是 case 类,因为 implicit 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!