Классы перечисления
#
Васильев Андрей Михайлович, 2024
Версии презентации
Описание классов-перечислений
#
Наиболее базовый пример использования классов-перечислений — это реализация
типобезопасных перечислений
enum class Direction {
NORTH, SOUTH, WEST, EAST
;
}
- Каждая константа перечисления является объектом
- При объявлении константы разделяются запятыми
- Перечисление констант завершается точкой с запятой
- После точки с запятой идёт описание функций-членов и объектов-компаньонов
Данные констант
#
Так как константы являются экземплярами enum-класса, они могут быть инициализированы
enum class Color(val rgb: Int, val description: String) {
RED(0xFF0000, "Красный"),
GREEN(0x00FF00, "Зелёный"),
BLUE(0x0000FF, "Синий"),
;
}
К полям объекта можно обращаться как к обычным полям
val color = Color.GREEN
println(color.description)
Стандартные данные констант
#
Каждая enum-константа имеет поля, в которых содержатся её имя и порядковый номер
в объявлении enum-класса
Вы не можете переопределить данные поля
val name: String
val ordinal: Int
Также enum-константы реализуют интерфейс Comparable
. Порядок сортировки
соответствует порядку объявления
println(RGB.RED.name) // prints RED
println(RGB.RED.ordinal) // prints 0
Работа с enum-константами
#
Enum-классы в Kotlin имеют синтетические методы для вывода списка объявленных
enum-констант и для получения enum-константы по её имени
enum class RGB { RED, GREEN, BLUE }
RGB.valueOf(value: String): RGB
RGB.entries: EnumEntries<RGB>
Метод valueOf()
выбрасывает исключение IllegalArgumentException
, если
указанное имя не соответствует ни одной enum-константе, объявленной в классе
fun main() {
for (color in RGB.entries) println(color.toString())
println("The first color is: ${RGB.valueOf("RED")}")
}
В Kotlin до 1.8 вместо entries
предоставлялся метод values()
, который
возвращал новый массив из констант
Обобщённый доступ к константам
#
К константам в enum-классе можно получить доступ универсальным способом,
используя функции enumEntries() и enumValueOf():
inline fun <reified T : Enum<T>> printAllValues() {
print(enumEntries<T>().joinToString { it.name })
}
printAllValues<RGB>() // выведет RED, GREEN, BLUE
В Kotlin до 1.8 вместо enumEntries<T>()
предоставлялся метод
enumValues<T>()
, который также возвращает новый массив из констант
Условное выражение when
#
when
определяет условное выражение с несколькими «ветвями». Оно похоже на
оператор switch, присутствующий в C-подобных языках.
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // обратите внимание на блок
print("x не равен ни 1, ни 2")
}
}
when
последовательно сравнивает свой аргумент со всеми указанными значениями,
пока не выполнится какое-либо из условий ветвей.
Полнота вычислений
#
Если when
используется как выражение, то ветка else
является обязательной, за
исключением случаев, в которых компилятор может убедиться, что ветки покрывают
все возможные значения
Так происходит, например с записями классов-перечислений
enum class Bit {
ZERO, ONE
}
val numericValue = when (getRandomBit()) {
Bit.ZERO -> 0
Bit.ONE -> 1
// 'else' не требуется, потому что все случаи учтены
}
В операторах when
ветка else
является обязательной в следующих условиях:
- when имеет объект типа
Boolean
, enum
, sealed
или их nullable
-аналоги
- ветки when не охватывают все возможные случаи для этого объекта