问题
Although it is not explicitly stated that Nothing is the subtype of all types, this (among others) suggests it:
fun f(x:Float) { }
fun g(x:Char) { }
fun dead(q: Nothing) {
f(q)
g(q)
}
However, this fails with “unresolved reference”:
fun dead(q: Nothing) {
q.not()
}
Is this a bug or a feature?
Notes:
- First piece of code compiles (with warnings), second does not
- It's possible to use a
Nothingtyped receiver, for instance callingtoString() - This is legal:
{b:Boolean -> b.not()}(q) - Upcast too:
(q as Boolean).not() - Equivalent question for Scala
回答1:
Nothing is Nothing for a reason. You can't call any functions on it. Besides not() is only applicable for Boolean so it is not present on Nothing. In fact there are no methods on Nothing:
/**
* Nothing has no instances. You can use Nothing to represent "a value that never exists": for example,
* if a function has the return type of Nothing, it means that it never returns (always throws an exception).
*/
public class Nothing private constructor()
The documentation pretty much explains its existence.
There is one loophole though. What happens if you return Nothing? from a function?
fun dead(): Nothing? {
return null
}
That's right. It can only return null:
@JvmStatic
fun main(args: Array<String>) {
dead() // will be null
}
I wouldn't say that there is a valid use case to do this but it is possible.
An example for Nothing to indicate nothingness in trees:
sealed class Tree<out T>() {
data class Node<out T>(val value: T,
val left: Tree<T> = None,
val right: Tree<T> = None): Tree<T>()
object None: Tree<Nothing>()
}
Here Nothing denotes a leaf node with no children.
回答2:
The premise itself doesn't make sense. Nothing is a class which can not be instantiated. You'll never have a variable that holds a Nothing instance.
This means that a function that takes Nothing as a parameter can never be invoked, because you can't get a Nothing instance to pass to it. Anything you write inside it is irrelevant, as is a function like this existing in the first place.
Nothing is made to act like a subtype to all types so that certain uses of language features like throw and return work nicely with the type system. In essence, the compiler lets you pass a Nothing in places where some other type is required, because it knows that you'll never actually reach that code (because again, you can't get a Nothing instance), so it doesn't matter what you're passing in.
来源:https://stackoverflow.com/questions/51039255/calling-any-method-on-nothing