English 中文(简体)
If the Nothing type is at the bottom of the class hierarchy, why can I not call any conceivable method on it?
原标题:

The scala type Nothing represents (as I understand it) the bottom of the type hierarchy, also denoted by the symbol ⊥. That is, Nothing is a sub-type of any given type. The requirement for a Nothing type is explained well by James Iry for those of us without a theoretical background in type theory!

So my question is, if Nothing is a subtype of every type, why can I not call any type s methods on Nothing? Obviously, I cannot instantiate Nothing but why doesn t the following compile?

var n: Nothing = _

def main(args: Array[String]) {
  println(n.length) //compile error: value length is not a member of Nothing
}

Surely as Nothing is a subtype of String this should be OK? Note that the following compiles just fine!

var n: Nothing = _

def foo(s: String) : Int =  s.length

def main(args: Array[String]) {
  println(foo(n))
}

as does:

def main(args: Array[String]) {
  println(n.asInstanceOf[String].length) 
}
最佳回答

While Nothing is a subtype of everything, it does not inherit any method except for those in Any. This is because Nothing is more geared toward the functional end of the language. It s necessary for things like Option and List, but only as a type, not as a class.

The distinction here is a bit weird for those coming from an object-oriented background, but the fact is that subtyping as a concept is very distinct from OOP. Granted, object-oriented really implies subtyping in some form, but the reverse is not true. Benjamin Pierce s Types and Programming Languages does a good job of presenting the language F_< (pronounced "F sub"), which serves as a minimal example of a language with subtyping (but not OO).

Now, with all that said, I do agree that the fact that Nothing is immune from the normal inheritance rules does seem a bit inconsistent. However, from a theoretical standpoint, it makes perfect sense.

问题回答

I suppose Nothing could accept any method, and perform a standard operation on all of them (throwing an exception). That wouldn t be very useful, though.

By presenting a compile error, the compiler is warning the programmer that a type he most likely didn t want, Nothing, got inferred somehow at a certain point in the code.

You can call toString on Nothing variable because of it s defintion:
final trait Nothing extends Any
And toString is member of Any. I think scala compiler treat s Nothing in type bounds only and treats it like any other trait on all over cases. Letting invoke any method on variable with type of Nothing will be very strange I think.





相关问题
Having many stacks with different types

I m making a C program that needs to use two stacks. One needs to hold chars, the other needs to hold doubles. I have two structs, node and stack: struct node { double value; struct node *...

Creating (boxed) primitive instance when the class is known

I need a method that returns an instance of the supplied class type. Let s assume that the supplied types are limited to such that an "empty" instance of them can be created. For instance, supplying ...

How does php cast boolean variables?

How does php cast boolean variables? I was trying to save a boolean value to an array: $result["Users"]["is_login"] = true; but when I use debug the is_login value is blank. and when I do ...

How to generate an instance of an unknown type at runtime?

i ve got the following in C#: string typename = "System.Int32"; string value = "4"; theses two strings should be taken to generate an object of the specified type with the specified value... result ...

Type reference scope

I m studying databases and am currently working on a object-relational DB project and I ve encountered a small problem with the number of possible constraints in an object table. I m using "Database ...

热门标签