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

Когда использовать класс case или обычный класс

У меня есть недоразумение, в каких случаях я должен использовать класс case или обычный класс, следуя передовым методам. Я уже читал о различиях обоих классов, но не могу представить себе реальные примеры, в которых рекомендуется использовать случай или обычный класс.

Может ли кто-нибудь показать мне реальные примеры с объяснением, почему это рекомендуется для этого, а не иначе?

4b9b3361

Ответ 1

Если вы собираетесь писать чисто функциональный код с неизменяемыми объектами, лучше избегать использования обычных классов. Основная идея функциональной парадигмы - разделение структур данных и операций над ними. Классы классов представляют собой представление структуры данных с необходимыми методами. Функции на данных должны быть описаны в разных объектах программного обеспечения (например, чертах, объектах).

Регулярные классы, напротив, связывают данные и операции, чтобы обеспечить изменчивость. Этот подход ближе к объектно-ориентированной парадигме.


В результате не используйте классы Case, если:

  • Ваш класс несет изменчивое состояние.
  • В ваш класс входит некоторая логика.
  • Ваш класс не является представлением данных, и вам не требуется структурное равенство.

Однако в этих случаях вы должны действительно думать о стиле своего кода, потому что он, вероятно, недостаточно функциональен.

Ответ 2

  • Когда ваш класс переносит переменное состояние, не используйте классы case.
  • Если вы хотите структурное равенство, используйте класс case, так как он дает вам правильные hashCode и equals. Например, вы хотите использовать их как ключи в Set или Map

Вот еще одно личное предпочтение:

  • Когда вы просто хотите использовать автоматические геттеры, а вы помещаете экземпляры в Set или Map, но у вас только один экземпляр и не требуется структурное равенство, предпочитайте class Foo(val i: Int) над case class Foo(i: Int), потому что вы не имеют более дорогих проверок равенства.

Если 1. и 2. collide, вы можете реализовать определенные функции класса case вручную. Например, предоставите метод apply сопутствующей программы или экстрактор соответствия шаблону для изменяемого класса, отличного от случая.

Ответ 3

Класс case дает вам "бесплатные" (т.е. вам не нужно писать) реализации equals, hashcode и toString, а также apply и unapply в сопутствующем объекте, В принципе, вы можете рассматривать класс case как named tuple, поля которого также называются.

Для чего-нибудь еще, вам, вероятно, лучше использовать обычный класс.

Ответ 4

Классы классов являются нормальными классами с синтаксическим сахаром. Таким образом, нет большой разницы, вы можете делать все с классом case, который вы можете сделать с классом, и наоборот.

Классы классов просто сэкономит вам много кода плиты котла для записи.

Идеальная подгонка, как следует из названия, - это использование классов case в сопоставлении шаблонов с case.

case class MyCase(name: String, age: Int)

data : List[MyCase] = ...

data foreach { 
    case MyCase(_, age) if age > 21 => println("old enough")
    case MyCase("fred", _ ) => println("Got you")
    case _ => ...
}

Ответ 5

Нормальные классы - это классы как классы в Java. Он может содержать как состояние, так и функциональность.
Классы классов похожи на данные POJO в Java. классы, которые содержат состояние, которое может использоваться функциями (обычно в других классах).

Когда вы внедряете данные POJO в Java, вы должны установить переменную, которую она удерживает, добавить для них getter и setter, реализовать hashcode и equals и, возможно, реализовать toString.
Обычно это не так уж плохо, поскольку после определения переменных среда IDE может генерировать все для вас, но если вы меняете/добавляете переменные, вам следует помнить о том, чтобы обновить все методы.
в случае классов вы определяете переменные (или лучшие значения), а компилятор генерирует все методы для вас. Таким образом, вы получаете оба, без шаблонов и обновленных функций.
Для классов case компилятор также генерирует больше функциональных возможностей, которых вы не можете и не можете иметь в Java, функции копирования и применять/не использовать в объекте compaion.

Ответ 6

классы case являются центрами данных.

Мы получаем следующие преимущества, используя класс case над регулярными классами.

(1) Значение эквивалентности: это означает, что два случая могут сравниваться с значениями внутри них.

scala> case class Time(hours: Int = 0, mins: Int = 0)
defined class Time

scala> val time1 = Time(12, 13)
time1: Time = Time(12,13)

scala> val time2 = Time(11, 12)
time2: Time = Time(11,12)

scala> time1 == time2
res6: Boolean = false

scala> val time3 = Time(10, 11)
time3: Time = Time(10,11)

scala> time1 == time2
res7: Boolean = false

Но другие операторы сравнения ( > , >= <, и т.д.) не определены.

(2) Неизменяемые поля: потокобезопасные

(3) Автоматическое создание поля: часы и минуты являются неизменяемыми полями, автоматически создаваемыми Scala.

scala> time1.hours
res9: Int = 12

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