Почему нельзя создать экземпляр класса Nothing в Kotlin
Что проверяют
Понимаете ли вы систему типов Kotlin или пересказываете определение. Nothing это не «тип для исключений», а нижний тип, и хороший ответ строится именно на этом, а дальше выводит из одного свойства все практические следствия.
Как отвечать
Nothing объявлен с приватным конструктором и не имеет ни одного значения. Экземпляр создать нельзя не из-за запрета компилятора, а по смыслу типа: существование такого значения сломало бы всю конструкцию. При этом Nothing является подтипом любого другого типа, и отсюда следует всё остальное:
throwэто выражение типаNothing, поэтому компилируетсяval user = repo.find(id) ?: throw NotFound(). Правая ветка подходит под тип левой, каким бы он ни был;- функция с возвращаемым типом
Nothingсообщает компилятору, что управление не вернётся, и код после вызова помечается недостижимым. Так устроеныTODO()иerror(); Nothing?имеет ровно одно значение,null, и именно такой тип выводится уval x = null;- за счёт ковариантности
List<Nothing>подходит под любойList<T>, поэтомуemptyList()встаёт куда угодно. В Android это удобно в состояниях экрана:object Loading : UiState<Nothing>()сочетается с любым типом данных.
fun fail(message: String): Nothing = throw IllegalStateException(message)Где спотыкаются
Объясняют Nothing через исключения и на этом останавливаются. Тип исключения это Throwable, а Nothing это тип выражения throw. Разница видна сразу, как только спросят, почему Nothing подставляется в дженерик.
Путают Nothing, Unit и Void. Функция с типом Unit возвращается нормально и отдаёт единственное значение этого типа, функция с типом Nothing не возвращается вовсе. Void это вообще про совместимость с Java.
Не воспринимают выведенный Nothing как сигнал ошибки. Если среда показала переменной или результату лямбды тип Nothing, это почти всегда значит, что компилятору не из чего было выводить тип, и код собирается не так, как задумано.