Урок 19: ENUM в Kotlin (классы перечислений), TODO() и тип Nothing

Урок 19: ENUM в Kotlin (классы перечислений), TODO() и тип Nothing

Что такое enum?

Разбираем классы перечислений enum и выясняем чем они полезнее обычных строковых констант. Также затронем функцию TODO(), которая возвращает тип “ничего”.

enum – это сокращение от enumeration. Перечисления с помощью enum классов используются, когда нужно перечислить какие-либо объекты. Такими объектами как правило являются константы, их значение нам известно заранее. enum полезен там, где сущность может принимать одно из заранее известных вариантов значений. Чтобы потом обращаться к ним по названию этого класса, чтобы использовать далее. enum упрощает код, ограничивая количество возможных состояний.

Понятие — статус

Хранить можно как просто какой-то объект, так и объект с присвоенным ему конкретным свойством. Это могут быть дни недели. Или цвета, когда нам нужно сопоставлять название цвета и его (и только его) HEX-код. Это может быть хранение статусов какого-нибудь состояния или процесса. Например, enum класс хранит название статуса готовки блюда в приложении с доставкой еды и идентификатор. Когда сервер присылает заранее известный id статуса, мы в приложении сопоставляем его с имеющимися данными. И, определив актуальный статус, передаем его в методы по отрисовке данных процесса приготовления. Где уже определяется какую информацию для какого статуса отображать пользователю.

Создание класса перечислений

Посмотрим, как это выглядит в коде. Чтобы написать класс-перечисление нужно указать при создании enum class. Затем название класса с заглавной буквы, как и классический класс. В теле перечисляем наши значения через запятую, пишутся они как и другие константы стилем uppercase. Статусы пусть будут такими: NEW, COOKING, COMPLETED.

enum class Status {
	NEW,
	COOKING,
	COMPLETED,
}

Далее нам нужен механизм, имитирующий отправку какого нибудь кода статуса готовки с сервера. Теоретически сервер может отправлять такие названия строками и мы бы сравнивали их с названиями статусов. Но предположим, что сервер вместо строковых констант кодирует статусы целыми числами и отправляет их. Это будет целочисленный список statusesFromServer. Пусть они будут такими для наших трех статусов соответственно: 101, 102, 103.

Далее организуем имитацию того, что новый код статуса будет присылаться каждую секунду. Понадобится цикл for с итерациями по списку статусов и метод sleep(). Выведем коды пока что в консоль в исходном виде. Отлично, подготовка завершена.

fun main() {

val statusesFromServer = listOf(101,102,103)

for (i in statusesFromServer) {
			println(statusesFromServer(i))
      Thread.sleep(1000)
   }
}

enum class Status {
		NEW,
		COOKING,
		COMPLETED,
}

Создание функции для поиска статусов

Теперь вспоминаем, что нам нужно сделать. При получении определенного статуса, нужно найти его в enum классе и запустить последующую его обработку. Подготовим специальную функцию для этого setStatus(). Она будет принимать тип класса-перечисления. А внутри с помощью when печатать соответствующее статусу сообщение. Чтобы выбрать какой-то объект обращаемся к нему по имени класса. Или с помощью контекстного меню добавить импорт этого класса в файл, тогда можно будет просто писать название объекта. Но обратите внимание, среда разработки сама может предложить дозаполнить when.

экрана 2026 01 17 в 14.15.44 - Android [Kotlin] для начинающих

И это еще одно преимущество использования enum в виде его качества ограничивать возможные состояния приложения. Про TODO() расскажу в последней части урока. И я бы ввел еще один статус – ERROR. Будем обрабатывать ошибку на случай, если что-то пойдет не так.

fun setStatus(status: Status) {
   when (status) {
      Status.NEW -> println("Заказ принят")
      Status.COOKING -> println("Заказ готовится")
      Status.COMPLETED -> println("Заказ готов")
      Status.ERROR -> println("Статус неизвестен")
   }
}

Осталось только в методе main() парсить id статуса с гипотетического сервера и отправлять в эту функцию соответствующий объект. Убираем распечатку кода и снова воспользуемся when. Сопоставлять будем соответственно код и вызов функции вывода статуса из enum класса. ERROR положим в ветвление else. Ошибка будет отправляться, если придет код отличный от заранее известных.

for (i in statusesFromServer) {
   when (i) {
      101 -> setStatus(Status.NEW)
      102 -> setStatus(Status.COOKING)
      103 -> setStatus(Status.COMPLETED)
      else -> setStatus(Status.ERROR)
   }
   Thread.sleep(1000)
}

Что можно хранить в enum?

Вроде бы все работает неплохо, но голые коды статусов выглядят не очень. И мы можем хранить их прямо в enum. Мы можем хранить какие угодно свойства в enum. Для этого у класса добавляем конструктор с объявлением целочисленного свойства id. И для перечислений в скобках появляется необходимость заполнить это свойство, там и пропишем коды статусов. Для ERROR просто проставим 0. Или можно сделать свойство в id в конструкторе нуллабельным со значением по умолчанию null. В этом случае инициализировать свойство для ERROR не придется. Таким образом в main() вместо целочисленных значений выводим свойства этих объектов. Запускаем и наслаждаемся.

fun main() {

for (i in statusesFromServer) {
    when (i) {
       Status.NEW.id -> setStatus(Status.NEW)
	   Status.COOKING.id -> setStatus(Status.COOKING)
       Status.COMPLETED.id -> setStatus(Status.COMPLETED)
       else -> setStatus(Status.ERROR)
    }
    Thread.sleep(1000)
   }
}

enum class Status(val id: Int) {
		NEW(101),
		COOKING(102),
		COMPLETED(103),
		ERROR(0),
}

fun setStatus(status: Status) {
   when (status) {
      Status.NEW -> println("Заказ принят")
      Status.COOKING -> println("Заказ готовится")
      Status.COMPLETED -> println("Заказ готов")
      Status.ERROR -> println("Статус неизвестен")
   }
}

Окей. У объектов enum читать можно не только свойства. У класса есть поле name, возвращающее имя задекларированной константы. Еще при необходимости можно получить порядковый номер константы из поля ordinal. И, наконец, можно воспользоваться вспомогательной функцией values(), чтобы получить массив “енамов”. Их выведем через for.

println(Status.NEW.name)
println(Status.COOKING.ordinal)
for (i in Status.values()) println(i)

Кроме того в классах-перечислениях можно создавать функции. Сначала список констант необходимо отделить точкой с запятой. Напишем простую функцию, которая будет возвращать развернутое описание статуса. Так как для каждого enum объекта описание индивидуальное, поэтому делаем метод абстрактным и имплементируем в объекты перечисления. В реализованных методах пропишем сообщения для каждого статуса.

enum class Status(val id: Int) {
	NEW(101) {
		override fun getStatusDescription(): String {
			return "Заказ создан и ожидает оплаты"
		}
	},
	COOKING(102) {
		override fun getStatusDescription(): String {
			return "Заказ оплачен и начал готовиться"
		}
	},
	COMPLETED(103) {
		override fun getStatusDescription(): String {
			return "Заказ готов, можете забирать"
		}
	},
	ERROR(0) {
		override fun getStatusDescription(): String {
			return "Что-то пошло не так, мы уже разбираемся"
		}
	};

	abstract fun getStatusDescription(): String

}

Теперь проверим на примере нескольких статусов.

println(Status.NEW.getStatusDescription())
println(Status.COOKING.getStatusDescription())
println(Status.COMPLETED.getStatusDescription())

Все работает.

Функция TODO()

Вернемся к TODO(). Для справки. В Kotlin для функций без возвращаемого значения (когда не используем return) тоже существует специальный тип – Unit. Наведите курсор, например, на main и этот тип будет подсвечен в сигнатуре, как если бы эта функция возвращала какой-то базовый тип с данными.

экрана 2026 01 17 в 14.19.39 - Android [Kotlin] для начинающих

Есть еще один тип, который не возвращает ничего – Nothing. И этот тип возвращается функцией TODO(). Но Nothing отличается от Unit своей функциональностью. Nothing говорит компилятору, что функция гарантированно не выполнится успешно.

Давайте провалимся внутрь TODO() и посмотрим на сигнатуру. Возвращаемый тип Nothing, при вызове этой функции выбросится исключение (ошибка) NotImplementedError. Запустим проект с присутствием TODO() в каком-нибудь методе и программа упадет с ошибкой.

экрана 2026 01 17 в 14.22.14 - Android [Kotlin] для начинающих

TODO() обычно прописывается в качестве заглушки в процессе разработки. Дословный перевод понятен – ”надо сделать”. То есть мы можем объявить ряд функций, но временно с отсутствием внутренней логики. И проставить “тудушки”, чтобы обязательно реализовать их позже. Либо это делает среда разработки, как в данном случае. В аргументах TODO() можно еще указать развернутое пояснение, что нужно сделать. Тогда это сообщение выведется в исключении.

экрана 2026 01 17 в 14.24.00 - Android [Kotlin] для начинающих

TODO можно использовать и в обычном комментарии, тогда изменится оформление комментария, можно использовать в качестве заметок. IntelliJ IDEA (как и Android Studio) распознает семантику TODO и все прописанные в проекте “тудушки” можно увидеть в специальной вкладке с инструментами.

Бесплатные Telegram-боты для обучения

Практика с проверкой кода и помощью ИИ-ментора

AndroidSprint AI Mentor

Проверяет Pull Request'ы в GitHub, проводит тестовые собеседования с голосом и таймером, помогает разбираться с кодом 24/7

Попробовать ИИ-ментора →

KotlinSprint Bot

22 урока Kotlin, 220 тестов, 120 практических задач с код-ревью

Начать обучение Kotlin →

AndroidSprint Bot

Тесты по Android SDK, Jetpack Compose, архитектуре приложений

Тесты по Android →

Бесплатная диагностика с сениор разработчиком

Запишитесь на консультацию — перезвоним в рабочие часы

Или свяжитесь удобным способом

Вам также может быть интересно

Узнать подробнее
Курс AndroidSprint

Глубокое обучение Android разработке с 0 до получения оффера. Только персональная практика с гарантией получения продуктового опыта.

Курс AndroidSprint - Глубокое <strong>обучение Android разработке с 0 до получения оффера</strong>. Только персональная практика с гарантией получения продуктового опыта.
Узнать подробнее
Узнать подробнее
Практикум по Kotlin

Изучение Котлин с 0 для профессиональной разработки. Личный ментор и разбор кода задач через git-flow.

Практикум по Kotlin - Изучение Котлин <strong>с 0 для профессиональной разработки</strong>. Личный ментор и разбор кода задач через git-flow.
Узнать подробнее
Узнать подробнее
Бесплатные уроки по Kotlin разработке

Самостоятельное освоение базы по языку для дальнейшего развития в Android/back-end разработке или в автотестах.

Бесплатные уроки по Kotlin разработке - <span>Самостоятельное освоение базы по языку для дальнейшего развития в Android/back-end разработке или в автотестах.</span>
Узнать подробнее
Узнать подробнее
Onboarding в разработку

Полное обучение Android разработке с нуля до получения оффера. Делаем упор на практику и обратную связь

Onboarding в разработку - <span>Полное обучение Android разработке с нуля до получения оффера. Делаем упор на практику и обратную связь</span>
Узнать подробнее
Узнать подробнее
Обучающий Kotlin телеграм бот (с тестами)

Ваш основной инструмент для изучения основ языка. Бесплатные тесты и практика внутри.

Обучающий Kotlin телеграм бот (с тестами) - Ваш основной <span>инструмент для изучения основ языка.</span> Бесплатные тесты и практика внутри.
Узнать подробнее
Узнать подробнее
Бесплатные уроки по Android разработке

Самостоятельное обучение разработке Андроид приложений. Понятные видеоуроки с разжеванными примерами.

Бесплатные уроки  по Android разработке - Самостоятельное <span>обучение разработке Андроид приложений.</span> Понятные видеоуроки с разжеванными примерами.
Узнать подробнее
Узнать подробнее
Курс по UI/Unit тестированию

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

Курс по UI/Unit тестированию - Для ручных тестировщиков, которые <span>готовы осваивать автотесты</span> с использованием актуального стека технологий. [в разработке]
Узнать подробнее
Узнать подробнее
Обучающий Android телеграм бот (с тестами)

Бесплатные теоретические тесты для самопроверки. А также информер на практических спринтах по Android.

Обучающий Android телеграм бот (с тестами) - Бесплатные <span>теоретические тесты для самопроверки.</span> А также информер на практических спринтах по Android.
Узнать подробнее
ИИ-ментор код-ревью и голосовые собесы
Открыть