Подтвердить что ты не робот

Scala неявный объект vs неявный val

Я видел два пути (один меньше другого) объявления implicit для шаблона типа в Scala.

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

Как они отличаются? Должны ли вы отдать предпочтение одному другому в определенное время? Я нахожу implicit val гораздо чаще, чем implicit object, и мне еще предстоит найти много ресурсов о implicit object.

4b9b3361

Ответ 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 является строгой.