隐式类

语言
此文档页面特定于 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!

此页面的贡献者