Being the subtype of every other type allows a hypothetical Nothing
typed value to be passed to any function. However, although such a value can serve as receiver for toString()
it can't for unary_!
(among others).
object Foo {
def dead(q: Nothing): Unit = {
println(q);
q.toString();
((b: Boolean) => !b)(q);
!q; // value unary_! is not a member of Nothing
}
}
Is this a bug or a feature?
Note:
!(q.asInstanceOf[Boolean])
You don't need upcasting. You only have to ascribe some type which has a method unary_!
:
def dead(q: Nothing): Unit = {
!(q: Boolean)
}
Without an explicit type ascription, the method unary_!
simply cannot be resolved, because even though Nothing
is a subtype of Boolean
, it's not a subclass of Boolean
, therefore the compiler can not find a method unary_!
in the inheritance hierarchy of Nothing
.
The fact that you can define such methods and functions is not a bug either. The following is a completely valid program that uses a function with input type Nothing
to produce a perfectly meaningful result 0
, without throwing any errors or anything like it:
def foo[X](xs: List[X], f: (Int, X) => Int) = {
xs.foldLeft(0)(f)
}
foo(Nil, (i: Int, n: Nothing) => 42)
The presence of Nothing
in the type system is a Really Good Idea, because it's an initial object (for each other type A
, there is exactly one function Nothing => A
), and it simplifies lot of things, because it does not force you to deal with all kind of strange corner cases.
Nothing is a subtype of every other type (including scala.Null); there exist no instances of this type
In other words, there are no values of type Nothing
. So contrary to the statement in your question, you can't pass a Nothing
typed value to any function (even hypothetically) because it doesn't exist, by definition. Neither can it be a receiver for any method because, again, it doesn't exist.
So the bug, if there is one, is that the compiler does not warn you that you have created a function that can never be called.
In this case, println(q)
works because Nothing
is a subtype of Any
, and q.toString
works because of an implicit conversion of AnyRef
to Object
which supports toString
. The inline function converts q
to Boolean
which is also OK, but Object
does not support unary_!
so !q
fails to compile.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.