Kotlin Academy · Урок

Функциональная обработка ошибок

Преобразуйте и восстанавливайте значения

Урок 4 из 413 шагов

«Функциональная обработка ошибок» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.

Ошибки как потоки данных

Функциональная обработка ошибок рассматривает failure как значения, которые можно преобразовывать, объединять в цепочки и из которых можно восстанавливаться, — так же, как успешные значения. Встроенный Result предоставляет для этого специальные операции.

map

map преобразует успешное значение, а failure оставляет без изменений, передавая его дальше в исходном виде.

fun main() {
    val r = Result.success(5).map { it * 2 }
    println(r.getOrNull())
    val f = Result.failure<Int>(Exception("x")).map { it * 2 }
    println(f.getOrNull())
}

mapCatching

Если само преобразование может выбросить исключение, mapCatching сохраняет это исключение в результате, не позволяя ему выйти наружу.

fun main() {
    val r = Result.success("10").mapCatching { it.toInt() }
    println(r.getOrNull())
    val bad = Result.success("oops").mapCatching { it.toInt() }
    println(bad.isFailure)
}

recover

recover превращает failure обратно в success, вычисляя значение на основе исключения. Success проходит без изменений.

fun main() {
    val r = Result.failure<Int>(Exception("down")).recover { 0 }
    println(r.getOrNull())
    val ok = Result.success(7).recover { 0 }
    println(ok.getOrNull())
}

recoverCatching

Если логика восстановления также может завершиться ошибкой, recoverCatching оборачивает эту попытку, сохраняя всё в виде результата.

fun main() {
    val r = Result.failure<Int>(Exception()).recoverCatching {
        "5".toInt()
    }
    println(r.getOrNull())
}

onSuccess и onFailure

Они выполняют побочные эффекты, не изменяя результат, и возвращают его для дальнейшего объединения в цепочку. Это особенно удобно для ведения журнала.

fun main() {
    runCatching { "3".toInt() }
        .onSuccess { println("ok " + it) }
        .onFailure { println("fail " + it.message) }
        .also { println("done") }
}

Объединение в конвейер

Операторы объединяются в аккуратный конвейер: получение, преобразование и восстановление — и всё это без вложенных блоков обработки исключений.

fun main() {
    val result = runCatching { "21".toInt() }
        .map { it * 2 }
        .recover { -1 }
        .getOrThrow()
    println(result)
}

Сведение к итоговому значению

Завершите конвейер с помощью fold, сведя обе ветви к одному конкретному значению, например к сообщению для пользователя.

fun main() {
    val msg = runCatching { "x".toInt() }
        .map { it + 1 }
        .fold(
            onSuccess = { "result: " + it },
            onFailure = { "failed: " + it.message }
        )
    println(msg)
}

Преобразование пользовательского типа

Вы можете обеспечить такую же удобную работу со своим типом результата с фиксированным набором вариантов, написав функции расширения, например map.

sealed class Res<out T> {
    data class Ok<T>(val v: T) : Res<T>()
    data class Err(val msg: String) : Res<Nothing>()
}

fun <T, R> Res<T>.map(f: (T) -> R): Res<R> = when (this) {
    is Res.Ok -> Res.Ok(f(v))
    is Res.Err -> this
}

fun main() {
    val r = Res.Ok(4).map { it * 3 }
    println(r)
}

Зачем нужен функциональный стиль

Функциональная обработка ошибок сохраняет основной сценарий понятным, а ошибки проходят через него декларативно. Нет разрозненных блоков обработки исключений, а система типов отслеживает сбои от начала до конца.

Собираем всё вместе

Теперь у Вас есть полный набор инструментов:

  • map / mapCatching для преобразования
  • recover / recoverCatching для восстановления
  • onSuccess / onFailure для выполнения эффектов
  • fold для завершения

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

Проверьте своё понимание функциональной обработки ошибок.

Итоги

Вы изучили функциональную обработку ошибок:

  • Преобразование с помощью map / mapCatching
  • Восстановление с помощью recover / recoverCatching
  • Наблюдение с помощью onSuccess / onFailure
  • Завершение с помощью fold

На этом курс по типу результата и моделированию ошибок завершён.

Можно начать бесплатно

Изучай Kotlin с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
51
Уроки
203

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

Урок «Функциональная обработка ошибок» бесплатный?

Да — полный текст урока «Функциональная обработка ошибок» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.

Чему я научусь в уроке «Функциональная обработка ошибок»?

Преобразуйте и восстанавливайте значения Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Kotlin Academy?

Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Функциональная обработка ошибок»?

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

Можно ли писать и запускать код в этом уроке Kotlin Academy?

Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

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

  1. Тип Result
  2. runCatching
  3. Иерархии Result с запечатанными классами
  4. Функциональная обработка ошибок
← Назад к Kotlin Academy