Scala隐式对象vs隐式val

Dan*_*hin 20 scala implicit

我已经看到有两种方法(其中一个比另一个更小)的声明implicit类型类模式在Scala中.

implicit val instance1 = new Typeclass { def do = ??? }
implicit object instance2 extends Typeclass { def do = ??? }
Run Code Online (Sandbox Code Playgroud)

他们有什么不同?在某些时候,人们应该更喜欢一个吗?我找到implicit val了比implicit object我更常用的东西,而且我还没有找到很多资源implicit object.

Jas*_*man 15

一个区别是object版本将被懒惰地初始化,即它的构造函数在第一次使用之前不会被调用.例如:

trait Incrementer[T] {
  def inc(x: T)
}

def increment[T](x: T)(implicit ev: Incrementer[T]) = ev.inc(x)

implicit object IntIncrementer extends Incrementer[Int] {
  println("IntIncrementer is being constructed...")

  def inc(x: Int) = x + 1
}

implicit val DoubleIncrementer extends Incrementer[Double] {
  println("DoubleIncrementer is being constructed...")

  def inc(x: Double) = x + 1D
}
Run Code Online (Sandbox Code Playgroud)

请注意,在IntIncrementer使用之前您不会看到消息,例如

increment(1)  //this prints "IntIncrementer is being constructed..."
Run Code Online (Sandbox Code Playgroud)

DoubleIncrementer但是,定义时将显示来自的消息.所以初始化implicit object是懒惰的,而初始化implicit val是严格的.

  • 这可能是一个考虑因素(尽管你总是可以使用`lazy val`来使用'val`来获得懒惰),但不是唯一的.例如,`val`成员可以在子类中重写,而`object`成员则不能.我确信还有很多其他的差异. (5认同)