При реализации классов типов для наших типов мы можем использовать разные синтаксисы (например, implicit val или implicit object). В качестве примера:

Определение Typeclass:

  trait Increment[A] {
    def increment(value: A): A
  }

И, насколько мне известно, мы могли бы реализовать это для Int двумя следующими способами:

  implicit val fooInstance: Increment[Int] = new Increment[Int] {
    override def increment(value: Int): Int = value + 1
  }

// or

  implicit object fooInstance extends Increment[Int] {
    override def increment(value: Int): Int = value + 1
  }

Я всегда использую первый, так как для Scala 2.13 он имеет синтаксис сокращения, который выглядит следующим образом:

implicit val fooInstance: Increment[Int] = (value: Int) => value + 1

Но есть ли между ними реальная разница? или есть какие-то рекомендации или стандарты для этого?

Существует вопрос, связанный с неявными defs и неявными классы для преобразований, но я буду больше говорить о том, как создавать (лучшие практики) экземпляры классов типов, а не о неявных преобразованиях

0
Javier Montón 24 Ноя 2021 в 13:29
1
 – 
Johny T Koshy
24 Ноя 2021 в 13:37
2
Я не уверен, что implicit object можно отнести к случаю implicit class, поскольку он не подразумевает неявное преобразование. Он останавливается на определении object и позволяет рассматривать его как значение implicit. implicit class имеет этот дополнительный шаг, на котором конструктор класса превращается в неявную функцию (которая может использоваться для выполнения преобразования).
 – 
Mateusz Kubuszok
24 Ноя 2021 в 14:12
1
 – 
Luis Miguel Mejía Suárez
24 Ноя 2021 в 17:23

1 ответ

Лучший ответ

Насколько я знаю, различия будут следующими:

  • object имеют разные правила инициализации - довольно часто они инициализируются лениво (неважно, если вы не выполняете побочные эффекты в конструкторе)
  • он также будет отличаться от Java (но опять же, вы, вероятно, не заметите этой разницы в Scala)
  • object X будет иметь тип X.type, который является подтипом того, что X расширяет или реализует (но неявное разрешение обнаружит, что оно расширяет ваш класс типов, хотя, возможно, с немного большими усилиями)

Итак, я не заметил бы никакой разницы в фактическом использовании, НО версия implicit val могла бы генерировать меньше мусора JVM (я говорю «мусор», поскольку вы не будете использовать какие-либо дополнительные усилия компилятора в данном конкретном случае).

1
Mateusz Kubuszok 24 Ноя 2021 в 14:26
Привет, я однажды создал вики-вопрос / ответ именно для этого: stackoverflow.com/questions/65258339/… - я подумал, стоит ли закрыть этот и перенести свой ответ на эту вики? (или как отдельный ответ, как хотите) - Дайте мне знать WDYT :)
 – 
Luis Miguel Mejía Suárez
24 Ноя 2021 в 17:24