What's the difference between Unit and Nothing?
Both types Unit
and Nothing
indicate a function that does not return anything. What's the difference between them?
Solution 1:
Unit
is a type that has exactly one value ‒ see Unit type. On the other hand, Nothing
has no possible value - see Bottom type.
A function that doesn't return anything must have the return type Unit
. If it were Nothing
then the function could not return a result. The only way to exit the function would be by an exception.
Nothing
is used in a different way. It is characterized by two properties:
-
Nothing
is a subtype of every other type (includingNull
). - There exist no instances of this type.
When is this useful? Consider None
:
object None extends Option[Nothing]
Because Option
is covariant in its type parameter and Nothing
is a subtype of everything, Option[Nothing]
is a subtype of Option[A]
for every type A
. So, we can make one object None
which is a subtype of Option[A]
for every A
. This is reasonable, since Nothing
cannot be instantiated so Option[Nothing]
will always be without a value. Similarly
object Nil extends List[Nothing]
Unit
corresponds to logical true and Nothing
corresponds to logical false under the Curry-Howard isomorphism, where we view types as propositions and functions as proofs, .
Solution 2:
Unit
means that (a) function has side effects like input and output, (b) these side effects are the main goal of the function. Of course, a function can have side effects even if its type is different from Unit
.
Nothing
is a special type in Scala, because (a) it has no values (Unit has exactly one value - ()
), so you cannot return a value of type Nothing
, and (b) it is a subtype of every other type. That means that if something has the type Nothing
, it can be used instead of any other type (via subtyping), but it won't produce any result. This is useful for dealing with exceptions - the throw
expression has a type of Nothing
, so it can be used everywhere in a program.
Simply, Nothing
means that there was an error or termination of a program and nothing was returned, while Unit
means there were side effects, but execution ended normally with no result.
Programming in Scala has a nice explanation of that.
Solution 3:
To add one aspect to Petr's reply: Nothing
plays an important role in the type hierarchy. It is a bottom type. That means that it is a subtype of every other type, which is like the opposite of Any
, which is a supertype of everything. You can find a nice explanation here.
Solution 4:
Unit
Unit is same as void of Java. void in java is a keyword but Unit is an Object in Kotlin.
Now if a function returns Unit in Kotlin, it means that it doesn't return anything meaningful, that function just executes a bunch of code and gives back the execution flow.
Nothing
Nothing is a different kind altogether. You can't relate it with anything in Java. There is nothing as such as Nothing in java.
Nothing means the end of execution. If a function returns Nothing, means literally nothing it returns. Not even the execution flow.
Nothing is like a black hole, anything that goes in doesn't come out, Not even the light (light is "execution flow" here). In the case of Unit, least light comes out.
So, if a function returns Nothing, the flow of code ends there and anything written after that is Unreachable.
Now see the code below,
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")
}
Output will be
inside unit
after unit
inside nothing
Exception in thread "main" java.lang.Exception
NOTE: you get warning as soon as you write
println("after nothing") UnReachable Code
And you know the reason, it's because nothingFun doesn't even send back the execution flow.
One more thing to complete this here is, any function that returns Nothing has to throw an exception of any kind.
REASON: If you write some general statement (and not throw an exception) then the function will match the return type and we don't have anything that returns Nothing, means we don't have anything that sucks the execution flow and never returns it back. Everything returns something, even Unit is something.
Now, one can say that Nothing is a class so we can make object of it and return that itself. Nohhhhhhh? A big nohhhh?
Nothing class has one constructor but it is private, so you can't even make an object of it.
Last Bit
Behind the scene, Unit is converted into void(small v) in the decompiled byte code while Nothing is converted into Void(capital V).
see the below code,
var user = null //First
var user : User? =null //Second
Here, the Second statement shows, user of Nullable-User type. What is the type of user of the first statement?
any guess?
It's Nullable-Nothing type.
try to see the first statement as
var user : Nothing? = null
Now what's happening under the hood,
Void user = (Void)null; //First
User user = (User)null; //Second