scalabook

Форк
0
/
case-class.md 
120 строк · 6.7 Кб

Кейс классы и объекты

Case classes

Scala case class

позволяет моделировать концепции с неизменяемыми структурами данных. case class
обладает всеми функциональными возможностями класса, а также имеет встроенные дополнительные функции, которые делают их полезными для функционального программирования.

case class

имеет следующие эффекты и преимущества:

  • Параметры конструктора case class
    по умолчанию являются общедоступными полями val
    , поэтому поля являются неизменяемыми, а методы доступа генерируются для каждого параметра.
  • Генерируется метод unapply
    , который позволяет использовать case class
    в match
    выражениях.
  • В классе создается метод copy
    , который позволяет создавать копии объекта без изменения исходного объекта.
  • генерируются методы equals
    и hashCode
    для проверки структурного равенства, что позволяет использовать экземпляры case class
    в Map
    .
  • генерируется метод toString
    , который полезен для отладки.

Этот код демонстрирует несколько функций case class

:

case class Person(name: String, vocation: String)
val person = Person("Reginald Kenneth Dwight", "Singer")
// person: Person = Person(
// name = "Reginald Kenneth Dwight",
// vocation = "Singer"
// )
person.name
// res0: String = "Reginald Kenneth Dwight"

Необходимо помнить, что поля в case class

-е неизменяемые:

person.name = "Joe" // error: Reassignment to val name

Остальные возможности продемонстрированы в коде:

println(person)
// Person(Reginald Kenneth Dwight,Singer)
person match
case Person(n, r) => println("name is " + n)
// name is Reginald Kenneth Dwight
val elton = Person("Elton John", "Singer")
// elton: Person = Person(name = "Elton John", vocation = "Singer")
person == elton
// res3: Boolean = false
case class BaseballTeam(name: String, lastWorldSeriesWin: Int)
val cubs1908 = BaseballTeam("Chicago Cubs", 1908)
// cubs1908: BaseballTeam = BaseballTeam(
// name = "Chicago Cubs",
// lastWorldSeriesWin = 1908
// )
val cubs2016 = cubs1908.copy(lastWorldSeriesWin = 2016)
// cubs2016: BaseballTeam = BaseballTeam(
// name = "Chicago Cubs",
// lastWorldSeriesWin = 2016
// )

Поддержка функционального программирования

Как уже упоминалось ранее, case class

-ы поддерживают функциональное программирование (ФП):

  • ФП избегает изменения структур данных. Поэтому поля конструктора по умолчанию имеют значение val
    . Поскольку экземпляры case class
    не могут быть изменены, ими можно легко делиться, не опасаясь мутаций или условий гонки.
  • вместо изменения экземпляра можно использовать метод copy
    в качестве шаблона для создания нового (потенциально измененного) экземпляра. Этот процесс можно назвать "обновлением по мере копирования".
  • наличие автоматически сгенерированного метода unapply
    позволяет использовать case class
    в сопоставлении шаблонов.

Case objects

Case object

-ы относятся к объектам так же, как case class
-ы относятся к классам: они предоставляют ряд автоматически генерируемых методов, чтобы сделать их более мощными. Case object
-ы особенно полезны тогда, когда необходим одноэлементный объект, который нуждается в небольшой дополнительной функциональности, например, для использования с сопоставлением шаблонов в выражениях match.

Case object

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

sealed trait Message
case class PlaySong(name: String) extends Message
case class IncreaseVolume(amount: Int) extends Message
case class DecreaseVolume(amount: Int) extends Message
case object StopPlaying extends Message

Затем в других частях кода можно написать методы, которые используют сопоставление с образцом для обработки входящего сообщения (при условии, что методы playSong

, changeVolume
и stopPlayingSong
определены где-то еще):

def handleMessages(message: Message): Unit = message match
case PlaySong(name) => playSong(name)
case IncreaseVolume(amount) => changeVolume(amount)
case DecreaseVolume(amount) => changeVolume(-amount)
case StopPlaying => stopPlayingSong()

Ссылки:

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.