Что означают типы данных Nothing и Unit?

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

🔷 Unit — аналог void в Java

Unit означает, что функция возвращает ничего значимого, но при этом она завершает выполнение.

fun printMessage(message: String): Unit {
println(message)
}

Однако в Kotlin : Unit можно не писать явно, потому что он подставляется автоматически:

fun printMessage(message: String) {
println(message)
}

📌 Особенности Unit

  • Это тип с единственным значением — Unit (аналог void в Java, но объект).

  • Используется в лямбдах, функциях обратного вызова и интерфейсах, где функция ничего не возвращает:

val callback: () -> Unit = { println("Done") }
  • Можно вернуть Unit явно:
return Unit

Но обычно это делать не нужно — достаточно return или вообще пропустить return.

🔴 Nothing — тип, указывающий, что функция никогда не завершится

Nothing означает, что функция не возвращает никакого значения и даже не завершает выполнение — либо выбрасывает исключение, либо бесконечно работает.

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

📌 Особенности Nothing

  • Указывает, что функция прерывает выполнение (через throw, exitProcess, бесконечный цикл).

  • Очень полезен при контрольных выражениях, особенно в when, ?:, elvis и т.д.

  • Используется для маркировки невозможных веток или невозвратных сценариев.

🔄 Примеры использования

Nothing в when

sealed class Result
object Success : Result()
object Failure : Result()
fun handle(result: Result): String = when (result) {
is Success -> "OK"
is Failure -> "Fail"
else -> throw IllegalStateException("Impossible") // тип Nothing
}

Компилятор видит, что throw возвращает Nothing, и не требует String от этой ветки.

Nothing с elvis

val name: String? = null
val safeName = name ?: throw IllegalArgumentException("Name required")

Тип выражения справа — Nothing, но весь ?:-блок в итоге — String.

📌 Разница между Unit и Nothing

Особенность Unit Nothing
Возвращается из функции? ✅ Да ❌ Нет (функция не завершает выполнение)
--- --- ---
Тип значения Один объект Unit Не имеет значений
--- --- ---
Используется Когда нужно "ничего вернуть" Когда выполнение прерывается
--- --- ---
Аналог в Java void нет прямого аналога
--- --- ---
Пример fun log(): Unit fun fail(): Nothing
--- --- ---

🧠 Итого

  • Unit — это "ничего значимого", функция завершается, но не возвращает полезного результата.

  • Nothing — это "вообще ничего", функция никогда не завершится нормально: она выбросит исключение или зациклится.

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