Оба типа Unit
и Nothing
указывают функцию, которая ничего не возвращает. Какая разница между ними?
Какая разница между Единицей и Ничем?
Ответ 1
Unit
- тип, который имеет ровно одно значение - см. Тип устройства. С другой стороны, Nothing
не имеет возможного значения - см. Нижний тип.
Функция, которая ничего не возвращает, должна иметь тип возврата Unit
. Если это было Nothing
, тогда функция не смогла вернуть результат. Единственный способ выйти из функции - это исключение.
Nothing
используется по-другому. Он характеризуется двумя свойствами:
-
Nothing
является подтипом любого другого типа (включаяNull
). - Не существует экземпляров этого типа.
Когда это полезно? Рассмотрим None
:
object None extends Option[Nothing]
Поскольку Option
является ковариантным в своем параметре типа, а Nothing
является подтипом всего, Option[Nothing]
является подтипом Option[A]
для каждого типа A
. Таким образом, мы можем сделать один объект None
, который является подтипом Option[A]
для каждого A
. Это разумно, так как Nothing
не может быть создан, поэтому Option[Nothing]
всегда будет иметь значение. Аналогично
object Nil extends List[Nothing]
Unit
соответствует логической истине, а Nothing
соответствует логическому false в изоморфизме Карри-Говарда, где мы рассматриваем типы как предложения и функции как доказательства,.
Ответ 2
Unit
означает, что (а) функция имеет побочные эффекты, такие как ввод и вывод, (б) эти побочные эффекты являются основной целью функции. Конечно, функция может иметь побочные эффекты, даже если ее тип отличается от Unit
.
Nothing
является особым типом в Scala, потому что (а) у него нет значений (единица имеет ровно одно значение - ()
), поэтому вы не можете вернуть значение типа Nothing
и (б) это подтип всех остальных типов. Это означает, что если что-то имеет тип Nothing
, его можно использовать в любом месте, где требуется другой тип, но это не даст никакого результата. Это используется для работы с исключениями - выражение throw
имеет тип Nothing
, поэтому его можно использовать практически везде в программе.
Просто Nothing
означает, что произошла ошибка и ничего не было возвращено, а Unit
означает, что имелись побочные эффекты.
Программирование в Scala имеет хорошее объяснение этого.
Ответ 3
Чтобы добавить один аспект в ответ Петра: Nothing
играет важную роль в иерархии типов. Это нижний тип. Это означает, что это подтип любого другого типа, который похож на противоположность Any
, который является супертипом всего. Вы можете найти приятное объяснение здесь.
Ответ 4
Раздел
Единица такая же как void Java. void в java - это ключевое слово, а Unit - это объект в Kotlin.
Теперь, если функция возвращает Unit в Kotlin, это означает, что она не возвращает ничего значимого, эта функция просто выполняет кучу кода и возвращает поток выполнения.
Ничего
Ничто не совсем другой вид. Вы не можете связать это с чем-либо в Java. Нет ничего такого, как Ничто в Java.
Ничто не означает конец выполнения. Если функция ничего не возвращает, значит буквально ничего не возвращает. Даже поток выполнения.
Ничто не похоже на черную дыру, все, что входит, не выходит, даже свет (свет - это "поток исполнения" здесь). В случае юнита наименьшее количество света выходит.
Таким образом, если функция возвращает Nothing, поток кода заканчивается там, и все, что написано после этого, является недоступным.
Теперь посмотрите код ниже,
fun main() {
unitFun()
println("after unit")
nothingFun()
println("after nothing") //you get warning here saying "unreachable code"
}
fun nothingFun(): Nothing {
println("inside nothing")
throw Exception()
}
fun unitFun(): Unit {
println("inside unit")
}
Вывод будет
inside unit
after unit
inside nothing
Exception in thread "main" java.lang.Exception
ПРИМЕЧАНИЕ. вы получите предупреждение, как только напишите
println("after nothing") UnReachable Code
И вы знаете причину, это потому, что nothingFun даже не отправляет обратно поток выполнения.
Еще одна вещь, чтобы завершить это здесь, любая функция, которая возвращает Nothing, должна генерировать исключение любого вида.
ПРИЧИНА: Если вы напишете какое-то общее утверждение (а не выбросите исключение), то функция будет соответствовать возвращаемому типу, и у нас нет ничего, что возвращает ничего, значит, у нас нет ничего, что сосет поток выполнения и никогда не вернет его обратно. Все что-то возвращает, даже Unit это что-то.
Теперь можно сказать, что Nothing - это класс, поэтому мы можем сделать его объектом и вернуть его сам. Nohhhhhhh? Большой нохххх?
Ни у одного класса нет одного конструктора, но он является закрытым, поэтому вы даже не можете сделать из него объект.
Последний бит
За кулисами Unit преобразуется в void (small v) в декомпилированном байт-коде, в то время как ничего не преобразуется в Void (заглавная V).
см. приведенный ниже код,
var user = null //First
var user : User? =null //Second
Здесь второе утверждение показывает, что пользователь типа Nullable-User. Какого типа пользователь первого оператора?
есть предположение?
Это Nullable-ничего типа.
попытаться увидеть первое утверждение как
var user : Nothing? = null
Теперь, что происходит под капотом,
Void user = (Void)null; //First
User user = (User)null; //Second