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?>
Дополнительная литература