O que é uma característica selada?

332

As classes seladas são descritas em 'Programação em Scala', mas as características seladas não são. Onde posso encontrar mais informações sobre uma característica selada?

Gostaria de saber se uma característica selada é igual a uma classe selada? Ou, se não, quais são as diferenças? Quando é uma boa ideia usar uma característica selada (e quando não)?

John Threepwood
fonte

Respostas:

473

Uma sealedcaracterística pode ser estendida apenas no mesmo arquivo que sua declaração.

Eles são freqüentemente usados ​​para fornecer uma alternativa para enums . Como eles podem ser estendidos apenas em um único arquivo, o compilador conhece todos os subtipos possíveis e pode argumentar sobre isso.

Por exemplo, com a declaração:

sealed trait Answer
case object Yes extends Answer
case object No extends Answer

O compilador emitirá um aviso se uma correspondência não for exaustiva:

scala> val x: Answer = Yes
x: Answer = Yes

scala> x match {
     |   case No => println("No")
     | }
<console>:12: warning: match is not exhaustive!
missing combination            Yes

Portanto, você deve usar traços selados (ou classe abstrata selada) se o número de possíveis subtipos for finito e conhecido com antecedência. Para mais exemplos, você pode dar uma olhada nas implementações de lista e opção .

paradigmático
fonte
113
Levei seis meses para chegar aleatoriamente aqui e entender como substituir o Java Enum no Scala.
Sscarduzio # 14/14
1
muito agradável ! e não apenas finito e conhecido antecipadamente, mas também parte de um contexto restrito (selado?), onde faz sentido verificar todos os subtipos possíveis, como yes | não mesmo | impar etc ...
Mário de Sá Vera
90

uma característica selada é igual a uma classe selada?

Na medida do possível sealed, sim. Eles compartilham as diferenças normais entre traite class, é claro.

Ou, se não, quais são as diferenças?

Discutível.

Quando é uma boa ideia usar uma característica selada (e quando não)?

Se você tiver um sealed class X, precisará verificar Xas subclasses e todas as subclasses. O mesmo não se aplica a sealed abstract class Xou sealed trait X. Então você poderia fazer sealed abstract class X, mas isso é muito mais detalhado do que apenastrait e com pouca vantagem.

A principal vantagem de usar um abstract classover a traité que ele pode receber parâmetros. Essa vantagem é particularmente relevante ao usar classes de tipo. Digamos que você queira construir uma árvore classificada, por exemplo. Você pode escrever isto:

sealed abstract class Tree[T : Ordering]

mas você não pode fazer isso:

sealed trait Tree[T : Ordering]

desde que os limites de contexto (e os limites de exibição) sejam implementados com parâmetros implícitos. Dado que as características não podem receber parâmetros, você não pode fazer isso.

Pessoalmente, prefiro sealed traite uso a menos que alguma razão em particular me faça usar a sealed abstract class. E não estou falando de razões sutis, mas de razões que você não pode ignorar, como o uso de classes de tipo.

Daniel C. Sobral
fonte
"desde que limites de contexto (e limites de exibição) são implementados com parâmetros implícitos." - você poderia elaborar sobre isso?
Ruby
@ Ruby - resposta bastante tardia, mas caso você ou qualquer outra pessoa esteja interessada: o contexto bounding ( [A: F]) não funciona da mesma maneira que as restrições de variação. Pelo contrário, é o açúcar sintático que exige um F[A]alcance implícito . Geralmente é usado para convocar instâncias de classe de tipo de uma maneira um pouco mais tensa e mais fácil de ler do que um parâmetro implícito ( (implicit fa: F[A])), mas ainda funciona exatamente da mesma maneira sob o capô e, como Daniel aponta, os traços não conseguem fazer aquele.
mirichan
54

No blog daily-scala :

Quando uma característica é "selada", todas as suas subclasses são declaradas no mesmo arquivo e isso torna o conjunto de subclasses finito, o que permite determinadas verificações do compilador.

Brian Agnew
fonte
Obrigado. Com "todas as suas subclasses" significa classes e características?
precisa
@ John - Eu não tentei, mas suspeito de aulas. O ponto sobre vedação é que tudo é definido dentro dessa unidade de fonte
Brian Agnew
1
@ JohnThreepwood: classes, características e objetos. Na maioria das vezes, em Scala, o termo "classe" é usado para se referir a classes, características e objetos. Somente quando se fala sobre as diferenças específicas entre eles, isso significa apenas classes. O SLS usa o termo "modelo" para se referir a classes e características, mas esse termo não é usado muito fora do SLS, e não há termo que englobe todas as três classes, características e objetos.
Jörg W Mittag
30

Também sinto a necessidade de apontar as especificações:

O modificador selado aplica-se às definições de classe. Uma classe selada não pode ser herdada diretamente, exceto se o modelo herdado for definido no mesmo arquivo de origem que a classe herdada. No entanto, subclasses de uma classe selada podem ser herdadas em qualquer lugar.

- M. Odersky. A especificação da linguagem Scala, versão 2.8. online, setembro de 2013.

AT
fonte
7

IefBriefly:

  • Os traços selados só podem ser estendidos no mesmo arquivo
  • Listar isso permite que o compilador conheça facilmente todos os subtipos possíveis
  • Use traços selados quando o número de possíveis subtipos for finito e conhecido antecipadamente
  • Uma maneira de criar algo como enum em Java
  • Ajuda para definir tipos de dados algébricos (ADTs)

e para mais detalhes Tudo sobre traços selados no Scala

Majid Hosseini
fonte