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

Где классы случаев НЕ должны использоваться в Scala?

Классы классов в Scala являются стандартными классами, расширенными с помощью сопоставления с образцом, equals,... (или я ошибаюсь?). Более того, они не требуют "нового" ключевого слова для их instanciation. Мне кажется, что их проще определить, чем обычные классы (или я снова ошибаюсь?).

Существует множество веб-страниц, в которых рассказывается, где их следует использовать (в основном, для сопоставления шаблонов). Но где их следует избегать? Почему мы не используем их везде?

4b9b3361

Ответ 1

Есть много мест, где классы классов не являются адекватными:

  • Если вы хотите скрыть структуру данных.
  • Как часть иерархии типов более двух-трех уровней.
  • Когда конструктор требует особых соображений.
  • Когда экстрактор требует особых соображений.
  • Если для равенства и хеш-кода требуются особые соображения.

Иногда эти требования появляются позже в дизайне и требуют преобразования класса case в обычный класс. Поскольку преимущества класса case действительно не так уж и велики - кроме нескольких особых случаев, которые они специально сделали для меня, моя собственная рекомендация - не делать что-либо классом case, если нет ясного использования для него.

Или, другими словами, не переоценивайте.

Ответ 2

Наследование из классов case проблематично. Предположим, что у вас есть такой код:

case class Person(name: String) { }

case class Homeowner(address: String,override val name: String)
  extends Person(name) { }

scala> Person("John") == Homeowner("1 Main St","John")
res0:  Boolean = true

scala> Homeowner("1 Main St","John") == Person("John")
res1: Boolean = false

Возможно, это то, что вы хотите, но обычно вы хотите, чтобы == b тогда и только тогда, когда b == a. К сожалению, компилятор не может разумно исправить это для вас автоматически.

Это становится еще хуже, потому что hashCode из Person("John") не совпадает с хэш-кодом Homeowner("1 Main St","John"), поэтому теперь он действует как странный, а hashCode действует странно.

До тех пор, пока вы знаете, чего ожидать, наследование от классов case может дать приемлемые результаты, но оно стало восприниматься как плохая форма (и, таким образом, оно устарело в 2.8).

Ответ 3

Один недостаток, упомянутый в Программирование в Scala, заключается в том, что из-за вещей, автоматически генерируемых для классов case, объекты становятся больше, чем для нормальных классов, поэтому, если важна эффективность памяти, вы можете использовать обычные классы.

Ответ 4

Может возникнуть соблазн использовать классы case, потому что вы хотите бесплатно toString/equals/hashCode. Это может вызвать проблемы, поэтому не делайте этого.

Я бы хотел, чтобы была аннотация, позволяющая вам получать эти удобные вещи без создания класса case, но, возможно, это сложнее, чем кажется.