Option и Nullable: когда использовать каждый из них
Сравните тип Option в Arrow с nullable-типами Kotlin и выберите подходящий вариант
«Option и Nullable: когда использовать каждый из них» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.
Два способа представить отсутствие
В Kotlin есть встроенные типы, допускающие null (T?), которые представляют «значение или ничего». Arrow также предоставляет Option<A> — запечатанный тип с вариантами Some(value: A) и None. Оба подхода решают одну и ту же задачу, но подходят для разных контекстов.
Типы Kotlin, допускающие null
В большинстве кода Kotlin тип T? является идиоматичным выбором для представления отсутствия. Компилятор обеспечивает проверку на null, оператор безопасного вызова ?. позволяет удобно объединять вызовы в цепочку, а ?: "default" кратко задаёт значение по умолчанию:
val name: String? = findUser(id)?.name
val display = name ?: "Anonymous"Option<A> в Arrow
Option<A> оборачивает концепцию значения, допускающего null, в полноценный алгебраический тип с операциями map, flatMap, filter, fold и другими. Он естественно вписывается в стиль функционального конвейера Arrow:
import arrow.core.Option
import arrow.core.Some
import arrow.core.None
import arrow.core.toOption
val opt: Option<String> = "hello".toOption() // Some("hello")
val absent: Option<String> = NoneПреобразование между Option и типом, допускающим null
Свободно преобразуйте значения: value?.toOption() оборачивает значение, допускающее null, в Option; option.getOrNull() извлекает значение или null; option.getOrElse { default } предоставляет резервное значение:
val opt: Option<String> = nullableString.toOption()
val back: String? = opt.getOrNull()map и flatMap для Option
map { } преобразует значение Some (а None возвращает без изменений). flatMap { } объединяет в цепочку операции, которые сами возвращают Option:
val length: Option<Int> = "hello".toOption().map { it.length } // Some(5)
val noneLength: Option<Int> = (null as String?).toOption().map { it.length } // Nonefilter для Option
filter { predicate } преобразует Some в None, если предикат ложен:
val positiveAge: Option<Int> = 25.toOption().filter { it > 0 } // Some(25)
val rejectedAge: Option<Int> = (-1).toOption().filter { it > 0 } // Nonefold: обработка Option
fold(ifEmpty, ifSome) обрабатывает оба варианта в одном выражении без сопоставления с образцом:
val result: String = someOption.fold(
ifEmpty = { "Nothing here" },
ifSome = { value -> "Got: $value" }
)Когда предпочесть тип T?, допускающий null
Предпочитайте допускающий null тип Kotlin (T?), если:
- Вы пишете идиоматичный код Kotlin, который будут читать другие разработчики
- Вам нужны цепочки вызовов с безопасной обработкой null (
?.,?:) - Тип используется в API, не использующих Arrow
- Производительность критична (нет накладных расходов на боксирование)
Когда предпочесть Option<A>
Предпочитайте Option, если:
- Вы уже используете функциональный конвейер Arrow (
map,flatMap) - Вы хотите объединять необязательные значения с помощью
EitherилиRaise - Вы хотите явно обозначить отсутствие в общем функциональном контексте
- Вы создаёте библиотеку, вызывающий код которой может быть написан не на Kotlin
Option внутри either { }
Внутри блока either { } Arrow можно вызвать .bind() для Option, предварительно преобразовав его в Either:
fun findUserOpt(id: Long): Option<User> = TODO()
fun getUser(id: Long): Either<UserError, User> = either {
findUserOpt(id)
.toEither { UserError.NotFound }
.bind()
}Антипаттерн Option
Не используйте Option повсюду только потому, что он существует. В Kotlin в большинстве прикладного кода String? понятнее, чем Option. Используйте Option только тогда, когда его функциональные операции действительно дают преимущество.
Быстрая проверка
Что возвращает None.map { it.length } в Option из Arrow?
Итоги: Option и nullable-типы
Главное:
- Kotlin
T?: идиоматичный вариант для большей части кода; проверяется компилятором; использует?.и?: - Arrow
Option: алгебраический тип с функциональными операциями (map,flatMap,fold,filter) - Преобразуйте значения с помощью
.toOption()и.getOrNull() - Предпочитайте
T?в идиоматичном Kotlin; выбирайтеOptionпри составлении функциональных конвейеров с Arrow
Часто задаваемые вопросы
Урок «Option и Nullable: когда использовать каждый из них» бесплатный?
Да — полный текст урока «Option и Nullable: когда использовать каждый из них» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.
Чему я научусь в уроке «Option и Nullable: когда использовать каждый из них»?
Сравните тип Option в Arrow с nullable-типами Kotlin и выберите подходящий вариант Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Kotlin Academy?
Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Option и Nullable: когда использовать каждый из них»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Kotlin Academy?
Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Either : типизированная обработка ошибок без исключений
- DSL Arrow Raise: объединение типизированных ошибок
- Option и Nullable: когда использовать каждый из них
- Функциональное моделирование предметной области с базовыми типами Arrow