Для чего можно использовать «Ничто»?

Я специально прошу тип необнуляемыйNothing.

Я знаю, что Nothing? позволяет нам, например, фильтровать null, чтобы сделать перегрузку однозначной, но я изо всех сил пытаюсь придумать случаи, когда Nothing было бы полезно.

Nothing? может иметь ровно одно значение, null. Так что Nothing может не иметь абсолютно никакого значения. В чем смысл? Почему бы просто не использовать Unit?

Официальные документы есть, что сказать о нем: kotlinlang.org/docs/reference/exceptions.html#the-nothing-ty ре

chris 17.06.2019 13:45

Ответ Вилли ниже - отличный ответ. Немного математики, если вам интересно: Nothing — это тип, у которого нет значений, это пустой набор. Пустое множество (Nothing) является подмножеством все других множеств (типов). Вот почему тип Nothing присваивается всем другим типам ==> Nothing является подклассом всех других типов. ? означает «или-ноль». Вот почему тип Nothing? имеет одно значение: null (пустое множество + null).

Streets Of Boston 17.06.2019 23:47

@StreetsOfBoston Приятно видеть это с этой точки зрения :)

Willi Mentzel 17.06.2019 23:58
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
3
130
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

1. Nothing является аналогом Any?

Точно так же, как Any? является базовым типом любого другого типа, Nothing является подтипом любого другого типа (даже тех, которые допускают значение NULL).

Зная это, становится ясно, что s будет иметь тип String в следующем примере, данное имя является String?.

val s = name ?: throw IllegalArgumentException("Name required")

Выражение throw возвращает Nothing, а общий базовый тип String и NothingString. Это то, что мы хотим, потому что это тип, с которым мы хотим работать.

Если бы мы использовали Unit вместо Nothing, общим базовым типом был бы Any, что, конечно, не то, что нам нужно, потому что впоследствии потребовалось бы приведение к String.

Это тоже имеет смысл, потому что, если будет выдано исключение, выполнение не может продолжаться там, поэтому s в любом случае больше не будет использоваться.

2. Nothing помечает места кода, которые никогда не будут доступны

fun foo() {
   throw IllegalArgumentException("...")
   println("Hey") // unreachable code
}

3. Вывод типа

Если null используется для инициализации значения предполагаемого типа и нет другой информации для определения более конкретного типа, предполагаемым типом будет Nothing?.

val x = null           // 'x' has type `Nothing?`
val l = listOf(null)   // 'l' has type `List<Nothing?>

дальнейшее чтение

Спасибо. Небольшая поправка: Any? является супертипом ВСЕХ типов, допускающих значение NULL или нет, а Nothing (не Nothing?) является подтипом ВСЕХ типов, допускающих значение NULL или нет. Не имеет смысла рассматривать типы с нулевым и ненулевым значением как две отдельные вещи, как предлагает ваша сноска.

User1291 17.06.2019 21:38

@ User1291 Извините, если мой ответ недостаточно ясен. Вот что я имею в виду: Any является супертипом всех ненулевых типов, а Any? является супертипом ВСЕХ типов. То же самое относится и к Ничто/Ничто? а как подвид. Взгляните сюда: pl.kotl.in/SoUPnvW6E Таким образом, различие имеет смысл.

Willi Mentzel 17.06.2019 23:51

Я понял тебя с первого раза. Вы все еще ошибаетесь, когда говорите, что «Nothing? является подтипом любого другого типа». Nothing? является подтипом всех типов обнуляемый. Nothing является подтипом всех типов, не допускающих значение NULL, И подтипом Nothing? и, следовательно, подтипом всех других типов, допускающих значение NULL или нет.

User1291 18.06.2019 06:21

Nothing используется, чтобы сообщить компилятору, что он никогда не вернется. Например,


fun main() {
   var name: String? = null
   val notNullName = name ?: fail("name was null")
   println(notNullName)
}

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

fun infiniteLoop(): Nothing {
   while (true) {
     // Nothingness
   }
}

И какую ценность дает «сказать компилятору, что он никогда не вернется»? (Очевидно, кроме вывода типа.)

User1291 18.06.2019 11:55

Другие вопросы по теме