我已经看到了两种在Scala中为类型类模式声明implicit的方法(一种比另一种少)。

implicit val instance1 = new Typeclass { def do = ??? }
implicit object instance2 extends Typeclass { def do = ??? }

它们有何不同?一个人在某些时候是否应该偏爱另一个?我发现implicit valimplicit object更加常用,并且我尚未找到有关implicit object的许多资源。

最佳答案

一个区别是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
}

请注意,只有使用了IntIncrementer后,您才会看到该消息,例如
increment(1)  //this prints "IntIncrementer is being constructed..."

但是,定义后将显示DoubleIncrementer中的消息。因此,implicit object的初始化是延迟的,而implicit val的初始化是严格的。

10-02 23:15