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)?

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 .


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.


"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.


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


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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.