Почему Nothing можно использовать как любой класс

Ответ

Nothing в Kotlin — это тип, который не имеет значений и используется для обозначения невозможного состояния или завершения функции (например, при выбрасывании исключения).

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

Поскольку Nothing является подтипом всех других типов (включая nullable), его можно использовать везде:

  • В T? (Nothing? == null)
  • В generic-параметрах (List<Nothing> — пустой список)
  • В ветвях when/if, которые не возвращают значение

Это полезно для:

  • Функций, которые всегда падают (throw)
  • Пустых коллекций (emptyList() возвращает List<Nothing>)
  • Завершения корутин (suspendCoroutine<Nothing>)

Ответ 18+ 🔞

А, слушай, вот эта штука Nothing в Kotlin — это вообще отдельная история, ёпта. Представь себе тип, который в принципе не может иметь никаких значений. Вообще. Ноль. Пустота. Полный пиздец. Он как чёрная дыра для данных — туда можно только упасть и нихуя не вернуться.

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

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

Вызываешь её — и всё, приехали. Дальше по коду выполнение не пойдёт, потому что здесь путь заканчивается. Nothing — это как табличка «тупик» или «обрыв».

А самое охуенное, что из-за этой его «невозможной» природы, Nothing считается подтипом всех других типов в системе. Да-да, любого. Как будто он всем детям приходится папой. Это звучит как бред, но на практике даёт офигенные возможности.

Например:

  • T? (Nullable типы). Nothing? — это по сути null. Самый базовый, самый нихуёвый null из всех возможных.
  • Дженерики. Вот объяви List<Nothing> — и получишь идеально типобезопасный пустой список. В него нихуя нельзя положить (потому что значения типа Nothing не существует), и из него нихуя нельзя достать (потому что компилятор знает, что там пусто). Удобно, блядь, для тех же emptyList().
  • Ветвления. В when или if можно написать ветку, которая возвращает Nothing (например, кидает исключение или зацикливается нахуй), и компилятор будет понимать, что после этой ветки ход исполнения прервётся. Это помогает с анализом покрытия.

Короче, Nothing — это не про данные, это про намерения. Это способ сказать компилятору: «чувак, тут путь заканчивается, дальше не ищи». Используют его для функций-самоубийц (всегда throw), для описания пустых коллекций, или, там, для суспенд-функций в корутинах, которые никогда не возобновятся (suspendCoroutine<Nothing>).

Гениальная, блядь, концепция. Сначала кажется, что это какая-то мудя, абстракция для умников, а потом начинаешь использовать — и понимаешь, что это пизда рулю. Компилятор начинает сам за тебя думать и ловить ошибки, которые иначе проскочили бы. Красота, ядрёна вошь!