0Pricing
Scala for Backend Engineering & Functional Programming · Урок

Перечисления в Scala 3

Новый синтаксис перечислений

«Перечисления в Scala 3» — бесплатный урок Scala for Backend Engineering & Functional Programming на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Scala for Backend Engineering & Functional Programming, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.

Новое ключевое слово enum

В Scala 3 появилась полноценная конструкция enum. Она заменяет громоздкий шаблон с запечатанным трейтом и объектами вариантов из Scala 2 лаконичным синтаксисом.

  • Каждый вариант становится значением типа перечисления.
  • Компилятор автоматически создаёт полезные вспомогательные средства.
enum Color:
  case Red, Green, Blue

object Main:
  def main(args: Array[String]): Unit =
    println(Color.Red)

Перечисление всех значений

Для каждого простого перечисления создаётся объект-компаньон с values (массивом всех вариантов) и valueOf (поиском по имени).

enum Color:
  case Red, Green, Blue

object Main:
  def main(args: Array[String]): Unit =
    Color.values.foreach(println)
    println(Color.valueOf("Green"))

Порядковый номер и имя

У каждого значения перечисления есть ordinal (позиция, отсчитываемая с нуля) и сгенерированный toString, использующий имя варианта.

enum Color:
  case Red, Green, Blue

object Main:
  def main(args: Array[String]): Unit =
    println(Color.Blue.ordinal)
    println(Color.Red.ordinal)

Перечисления с параметрами

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

enum Planet(val mass: Double):
  case Earth extends Planet(5.97e24)
  case Mars  extends Planet(6.42e23)

object Main:
  def main(args: Array[String]): Unit =
    println(Planet.Earth.mass)
    println(Planet.Mars.mass)

Методы перечислений

В теле перечисления можно определить методы. Они доступны каждому значению, как методы класса.

enum Direction:
  case North, South, East, West
  def opposite: Direction = this match
    case North => South
    case South => North
    case East  => West
    case West  => East

object Main:
  def main(args: Array[String]): Unit =
    println(Direction.North.opposite)

Обобщённые перечисления ADT

Перечисления могут быть обобщёнными и параметризованными, что позволяет моделировать алгебраические типы данных. Ниже приведён упрощённый тип Option.

enum Maybe[+A]:
  case Just(value: A)
  case Nothing

object Main:
  def main(args: Array[String]): Unit =
    val a: Maybe[Int] = Maybe.Just(42)
    println(a)

Рекурсивные перечисления ADT

Перечисления особенно удобны для рекурсивных структур. Двоичное дерево или связный список естественно представить как набор вариантов.

enum Tree[+A]:
  case Leaf(value: A)
  case Branch(left: Tree[A], right: Tree[A])

object Main:
  def main(args: Array[String]): Unit =
    val t = Tree.Branch(Tree.Leaf(1), Tree.Leaf(2))
    println(t)

Сопоставление перечислений с образцами

Поскольку перечисления запечатаны, компилятор может проверять полноту конструкции match. Пропущенный вариант вызывает предупреждение.

enum Light:
  case Red, Yellow, Green

object Main:
  def action(l: Light): String = l match
    case Light.Red    => "stop"
    case Light.Yellow => "slow"
    case Light.Green  => "go"

  def main(args: Array[String]): Unit =
    println(action(Light.Green))

Перечисления, совместимые с Java

Добавьте поведение extends java.lang.Enum, автоматически выведя его из scala.reflect.Enum; для настоящего взаимодействия с Java напишите enum X extends Enum[X]… но в большинстве случаев используется обычная форма, которая при необходимости хорошо взаимодействует с Java.

enum Suit:
  case Hearts, Diamonds, Clubs, Spades

object Main:
  def main(args: Array[String]): Unit =
    println(Suit.values.length)
    println(Suit.Spades.ordinal)

Объединение полей и методов

Параметризованные варианты можно сочетать с общими методами для создания выразительных моделей предметной области.

enum Currency(val symbol: String):
  case USD extends Currency("$")
  case EUR extends Currency("\u20ac")
  def format(amount: Double): String = s"$symbol$amount"

object Main:
  def main(args: Array[String]): Unit =
    println(Currency.USD.format(9.99))

Когда использовать enum

Используйте enum, когда у Вас есть фиксированный набор вариантов или алгебраический тип данных.

  • Простые варианты — для обычных перечислений.
  • Параметризованные варианты — для ADT и типов-сумм.
  • Автоматическая проверка полноты делает рефакторинг безопасным.
enum Result[+E, +A]:
  case Ok(value: A)
  case Err(error: E)

object Main:
  def main(args: Array[String]): Unit =
    val r: Result[String, Int] = Result.Ok(7)
    println(r)

Быстрая проверка

Проверьте, насколько хорошо Вы поняли перечисления Scala 3.

Итоги

Вы изучили перечисления Scala 3.

  • Лаконичный enum заменяет шаблонный код запечатанного трейта.
  • Простые перечисления получают values, valueOf и ordinal.
  • Варианты могут принимать параметры для хранения связанных данных.
  • Обобщённые и рекурсивные перечисления моделируют ADT.
  • Запечатанная природа обеспечивает исчерпывающее сопоставление с образцами.
enum Weekday:
  case Mon, Tue, Wed, Thu, Fri
  def isStart: Boolean = this == Mon

object Main:
  def main(args: Array[String]): Unit =
    println(Weekday.Mon.isStart)
    println(Weekday.values.length)

Часто задаваемые вопросы

Урок «Перечисления в Scala 3» бесплатный?

Да — полный текст урока «Перечисления в Scala 3» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Scala for Backend Engineering & Functional Programming, подпишись на CoddyKit PRO. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.

Чему я научусь в уроке «Перечисления в Scala 3»?

Новый синтаксис перечислений Ты практикуешь Scala for Backend Engineering & Functional Programming с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Scala for Backend Engineering & Functional Programming?

Предыдущий опыт не требуется. Scala for Backend Engineering & Functional Programming на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Перечисления в Scala 3»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Scala for Backend Engineering & Functional Programming?

Да. Каждый урок Scala for Backend Engineering & Functional Programming включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Значимые отступы
  2. Перечисления в Scala 3
  3. Непрозрачные типы
  4. Типы объединения и пересечения
← Назад к Scala for Backend Engineering & Functional Programming