Se o tipo de nada estiver na parte inferior da hierarquia da classe, por que não posso chamar nenhum método concebível nele?

StackOverflow https://stackoverflow.com/questions/1728541

  •  19-09-2019
  •  | 
  •  

Pergunta

O tipo scala Nothing representa (como eu entendo) a parte inferior da hierarquia do tipo, também denotada pelo símbolo ⊥. Aquilo é, Nothing é um subtipo de qualquer tipo. O requisito para um Nothing tipo é explicado bem por James Iry Para aqueles de nós sem um contexto teórico da teoria do tipo!

Então minha pergunta é, se Nothing é um subtipo de todos os tipos, por que não posso chamar os métodos de nenhum tipo Nothing? Obviamente, não consigo instanciar nada, mas por que o seguinte não compila?

var n: Nothing = _

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

Certamente como Nothing é um subtipo de String Isso deve estar bem? Observe que os seguintes compilam bem!

var n: Nothing = _

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

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

como faz:

def main(args: Array[String]) {
  println(n.asInstanceOf[String].length) 
}
Foi útil?

Solução

Enquanto Nothing é um subtipo de tudo, não herdar qualquer método, exceto para aqueles em Any. Isto é porque Nothing é mais voltado para o fim funcional do idioma. É necessário para coisas como Option e List, mas apenas como um modelo, não como uma classe.

A distinção aqui é um pouco estranha para quem vem de um fundo orientado a objetos, mas o fato é que a subtipagem como conceito é muito distinta do OOP. Concedido, orientado a objetos, realmente implica subtipagem de alguma forma, mas o inverso não é verdadeiro. Benjamin Pierce's Tipos e linguagens de programação faz um bom trabalho de apresentar o idioma F_ (pronunciado "f sub"), que serve como um exemplo mínimo de uma linguagem com subtipagem (mas não OO).

Agora, com tudo isso dito, concordo que o fato de que Nothing está imune às regras normais de herança parece um pouco inconsistente. No entanto, do ponto de vista teórico, faz todo o sentido.

Outras dicas

Eu suponho Nothing poderia aceitar qualquer método e executar uma operação padrão em todos eles (lançando uma exceção). Isso não seria muito útil, no entanto.

Ao apresentar um erro de compilação, o compilador está avisando ao programador que um tipo que ele provavelmente não queria, Nothing, foi inferido de alguma forma em um determinado ponto do código.

Você pode ligar toString sobre Nothing variável por causa de sua definição:
final trait Nothing extends Any
E a tostring é membro de Any. Eu acho que o Scala Compiler Treat Nothing apenas nos limites do tipo e o trata como qualquer outra característica em todos os casos. Deixar invocar qualquer método em variável com tipo de Nothing Será muito estranho, eu acho.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top