Scala隐式对象与隐式val

Scala隐式对象与隐式val,scala,implicit,Scala,Implicit,我见过两种方法(一种比另一种少)在Scala中为类型类模式声明隐式 implicit val instance1 = new Typeclass { def do = ??? } implicit object instance2 extends Typeclass { def do = ??? } 它们有何不同?在某些时候,一个人是否应该选择一个而不是另一个?我发现隐式val比隐式对象更常用,而且我还没有找到很多关于隐式对象的参考资料。一个区别是对象版本将被延迟初始化,也就是说,直到第一次使

我见过两种方法(一种比另一种少)在Scala中为类型类模式声明
隐式

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

它们有何不同?在某些时候,一个人是否应该选择一个而不是另一个?我发现
隐式val
隐式对象
更常用,而且我还没有找到很多关于
隐式对象

的参考资料。一个区别是
对象
版本将被延迟初始化,也就是说,直到第一次使用它时才会调用它的构造函数。例如:

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
}
请注意,在使用之前,您不会看到来自增量器的消息,例如

increment(1)  //this prints "IntIncrementer is being constructed..."

但是,定义时将显示来自双增量器的消息。因此,
隐式对象
的初始化是惰性的,而
隐式val
的初始化是严格的。

因此,使用
隐式对象
val
的决定取决于是喜欢惰性初始化还是严格初始化?这可能是一个考虑因素(虽然您可以始终使用
lazy val
来获得
val
的惰性),但不是唯一的。例如,
val
成员可以在子类中被重写,而
对象
成员则不能。我确信还有很多其他区别。