Приведи пример функции использующей Nothing

Ответ

fun fail(message: String): Nothing {
    throw IllegalArgumentException(message)
}

// Пример использования
fun getUser(id: Int): User {
    return userRepository.findById(id) ?: fail("User not found")
}

Функция с возвращаемым типом Nothing всегда выбрасывает исключение или приводит к завершению программы. Это полезно для:

  1. Явного указания, что функция не возвращает нормального результата
  2. Улучшения вывода типов в Kotlin (компилятор понимает, что после вызова функция код не продолжится)
  3. Создания элегантных fail-fast проверок

Ответ 18+ 🔞

А, ну это же про Nothing в Kotlin, ёпта! Слушай, вот представь себе ситуацию: ты пишешь функцию, которая должна вернуть какого-нибудь юзера. И ты такой: "ладно, сейчас найду его по id, и если найду — верну, а если нет — ну, наверное, верну null или что-то такое".

Но Kotlin — он же умный, блядь. Он тебе говорит: "чувак, а давай сделаем красиво и понятно?". И вот появляется эта самая функция fail. Смотри, что она делает:

fun fail(message: String): Nothing {
    throw IllegalArgumentException(message)
}

Видишь возвращаемый тип? Nothing. Это не просто так, это пиздец какой важный тип! Он буквально кричит компилятору: "Э, бошка думай! После того как ты зайдёшь сюда, ты уже НИКОГДА НЕ ВЕРНЁШЬСЯ НОРМАЛЬНО!". Функция либо выбросит исключение, либо программу накроет медным тазом, либо она вообще в бесконечный цикл уйдёт. То есть это тупик, конец света, ядрёна вошь!

И вот зачем это нужно, спросишь ты? А вот зачем, чувак:

Первое — это просто кристально ясно. Когда другой разработчик видит Nothing в сигнатуре, он сразу понимает: "ага, тут всё, приехали, дальше код не пойдёт". Никаких сюрпризов, доверия ебать ноль к тому, что после вызова этой функции жизнь продолжится.

Второе — магия вывода типов. Компилятор Kotlin — он не дурак, он видит этот Nothing и такой: "О, так после вызова fail поток управления прервётся! Значит, в выражении userRepository.findById(id) ?: fail("User not found") общий тип всего этого выражения — это User, а не какой-нибудь User?!". Потому что если слева от ?: будет null, то справа выполнится fail, которая никогда не вернёт управление, а значит, и null оттуда не вылезет. Гениально же, блядь!

Третье — для fail-fast проверок. Это когда ты в начале функции проверяешь аргументы, и если они кривые — сразу впендюриваешь исключение через require() или check(), которые внутри как раз используют подобный механизм. Не надо писать кучу вложенных if'ов, просто сказал "нет" — и всё, поезд ушёл.

Короче, Nothing — это как красная кнопка "НИХУЯ НЕ ДЕЛАЙ ДАЛЬШЕ". Очень удобная штука, чтобы код был чистым и предсказуемым. Без неё пришлось бы городить огород с nullable-типами или писать неочевидные конструкции. А так — всё прозрачно, как слёзы ребёнка, которого только что отлучили от титьки.