Для чего можно использовать «Ничто»? - PullRequest
3 голосов
/ 17 июня 2019

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

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

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

Ответы [ 2 ]

5 голосов
/ 17 июня 2019

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

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

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

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

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

Если бы мы использовали 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?>

Дополнительная литература

0 голосов
/ 18 июня 2019

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
   }
}
...