Ответ 1
Одно отличие состоит в том, что версия 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
является строгой.