Si el tipo de nada está en la parte inferior de la jerarquía de clases, ¿por qué no puedo llamar a ningún método concebible?
Pregunta
El tipo Scala Nothing
representa (según tengo entendido) la parte inferior de la jerarquía de tipos, también denotada por el símbolo ⊥. Eso es, Nothing
es un subtipo de cualquier tipo dado. El requisito para un Nothing
tipo es explicado bien por James Iry ¡Para aquellos de nosotros sin antecedentes teóricos en la teoría de tipos!
Entonces mi pregunta es si Nothing
es un subtipo de cada tipo, ¿por qué no puedo llamar a los métodos de ningún tipo en Nothing
? Obviamente, no puedo instanciar nada, pero ¿por qué no se compila el siguiente?
var n: Nothing = _
def main(args: Array[String]) {
println(n.length) //compile error: value length is not a member of Nothing
}
Seguramente como Nothing
es un subtipo de String
¿Esto debería estar bien? ¡Tenga en cuenta que lo siguiente se compila bien!
var n: Nothing = _
def foo(s: String) : Int = s.length
def main(args: Array[String]) {
println(foo(n))
}
al igual que:
def main(args: Array[String]) {
println(n.asInstanceOf[String].length)
}
Solución
Tiempo Nothing
es un subtipo de todo, no heredar cualquier método excepto los de Any
. Esto es porque Nothing
está más orientado hacia el extremo funcional del idioma. Es necesario para cosas como Option
y List
, pero solo como un escribe, no como una clase.
La distinción aquí es un poco extraña para aquellos que provienen de un fondo orientado a objetos, pero el hecho es que el subtipo como concepto es muy distinto de OOP. De acuerdo, orientado a objetos realmente implica subtipo de alguna forma, pero el reverso no es cierto. Benjamin Pierce's Tipos y lenguajes de programación hace un buen trabajo al presentar el idioma F_ (pronunciado "f sub"), que sirve como un ejemplo mínimo de un lenguaje con subtipo (pero no oo).
Ahora, con todo lo dicho, estoy de acuerdo en que el hecho de que Nothing
es inmune a las reglas de herencia normales parece un poco inconsistente. Sin embargo, desde un punto de vista teórico, tiene mucho sentido.
Otros consejos
Supongo Nothing
podría aceptar cualquier método y realizar una operación estándar en todos ellos (lanzando una excepción). Sin embargo, eso no sería muy útil.
Al presentar un error de compilación, el compilador advierte al programador que un tipo que probablemente no quería, Nothing
, se infiere de alguna manera en cierto punto del código.
Puedes llamar toString
en Nothing
variable debido a la definición:
final trait Nothing extends Any
Y ToString es miembro de Any
. Creo que el compilador de Scala Treat Nothing
solo en límites de tipo y lo trata como cualquier otro rasgo en todos los casos. Dejar invocar cualquier método en variable con el tipo de Nothing
Será muy extraño, creo.