Перечисления в 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 — локальная установка не требуется.
Все уроки этого курса
- Значимые отступы
- Перечисления в Scala 3
- Непрозрачные типы
- Типы объединения и пересечения