Scala中Nothing作为所有类型子类型的适配可行性问询
Great question—this gets to a really interesting corner of Scala's type system, so let's unpack it step by step.
First, let's recap the basics you mentioned:
- By definition,
Nothingis the bottom type in Scala's hierarchy—it's a subtype of every other type, includingInt. - The substitution principle says that if
T'is a subtype ofT, you can use an instance ofT'anywhere an instance ofTis expected.
So why does this seem counterintuitive when it comes to Nothing? The key detail here is: Nothing has no instances. There is no value in Scala that is of type Nothing—it's a type that represents the absence of any value.
Let's look at two concrete scenarios to clarify:
1. Trying to pass a Nothing instance directly
Suppose you have a method that takes an Int:
def printInt(i: Int): Unit = println(i)
You can't write something like printInt(Nothing) or create a standalone value of type Nothing to pass in—because no such value exists. The compiler will even throw an error if you try to declare a variable of type Nothing without assigning it to an expression that never returns:
val nope: Nothing = ??? // This works only because `???` returns Nothing (it throws an exception) val nope2: Nothing = 42 // Compile error: type mismatch
2. Using expressions that return Nothing
Where you do see Nothing's subtype behavior in action is with expressions that never complete normally. For example:
- A method that always throws an exception:
def fail(message: String): Nothing = throw new IllegalArgumentException(message) - The
???placeholder (a shortcut for throwing aNotImplementedError)
In these cases, you can use such an expression anywhere a value is expected—including where an Int is required:
val myInt: Int = fail("Something went wrong") // This compiles!
Wait, why does this compile? Because the compiler knows that fail never returns a valid value—it either throws an exception or loops forever. So even though Nothing is a subtype of Int, this code never actually provides an Int value. The subtype relationship lets the compiler accept the code, but the program will crash before it ever needs to use myInt as an actual Int.
To sum up
- Syntactically, the compiler allows expressions of type
Nothingto be used in contexts expectingInt(or any other type) because of the subtype relationship. - Practically, you can never pass a real instance of
Nothingto a method expectingInt—because no such instance exists. - The main use of
Nothing's subtype behavior is to model code paths that never complete normally, which helps the compiler validate your code without unnecessary errors.
内容的提问来源于stack exchange,提问作者Mandroid

