2012-06-26 30 views
264

Las clases selladas se describen en 'Programación en Scala', pero las características selladas no lo son. ¿Dónde puedo encontrar más información sobre un rasgo sellado?¿Qué es un rasgo sellado?

Me gustaría saber, si un rasgo sellado es lo mismo que una clase sellada? O, si no, ¿cuáles son las diferencias? ¿Cuándo es una buena idea usar un rasgo sellado (y cuándo no)?

Respuesta

42

Desde el daily-scala blog:

Cuando un rasgo está "sellado" todas sus subclases son declarados dentro del mismo archivo y eso hace que el conjunto de subclases finitas que permite determinadas operaciones de control del compilador.

+0

Gracias. ¿Con "todas sus subclases" significa clases y rasgos? –

+1

Downvoted ¿por qué? –

+0

@John - No lo he intentado, pero sospecho que hay clases. El punto sobre el sellado es que todo se define dentro de esa unidad fuente –

354

A sealed rasgo solo se puede extender en el mismo archivo que su declaración.

A menudo se utilizan para proporcionar una alternativa a enums. Como solo se pueden extender en un solo archivo, el compilador conoce todos los subtipos posibles y puede razonar al respecto.

Por ejemplo, con la declaración:

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

El compilador emitirá un aviso si un partido no es exhaustiva:

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 

rasgos lo que debe utilizar sellados (o clase abstracta sellada) si el número de subtipos posibles es finito y conocido de antemano. Para ver más ejemplos, puede echar un vistazo a las implementaciones list y option.

+78

me tomó seis meses llegar aquí al azar y comprender cómo reemplazar Java Enum en Scala. – sscarduzio

77

¿un rasgo sellado es lo mismo que una clase sellada?

En cuanto a sealed va, sí. Comparten las diferencias normales entre trait y class, por supuesto.

O, en caso negativo, ¿cuáles son las diferencias?

Moot.

¿Cuándo es una buena idea usar un rasgo sellado (y cuándo no)?

Si usted tiene un sealed class X, entonces usted tiene que comprobar si hay X, así como cualquier subclase. Lo mismo no ocurre con sealed abstract class X o sealed trait X. Entonces podría hacer sealed abstract class X, pero eso es mucho más detallado que solo trait y para poca ventaja.

La principal ventaja de usar un abstract class en un trait es que puede recibir parámetros. Esa ventaja es particularmente relevante cuando se usan clases de tipo. Digamos que quieres construir un árbol ordenado, por ejemplo.Puede escribir lo siguiente:

sealed abstract class Tree[T : Ordering] 

pero no se puede hacer esto:

sealed trait Tree[T : Ordering] 

desde los límites de contexto (y ver los límites) se implementan con los parámetros implícitos. Dado que los rasgos no pueden recibir parámetros, no puedes hacer eso.

Personalmente, prefiero sealed trait y lo uso a menos que algún motivo en particular me haga usar un sealed abstract class. Y no estoy hablando de razones sutiles, sino de razones que no puedes ignorar, como usar clases de tipos.

+0

"ya que los límites de contexto (y los límites de vista) se implementan con parámetros implícitos". - ¿Podrías dar más detalles sobre eso? – Ruby

22

También siento la necesidad de señalar a las especificaciones:

El sellada modificador se aplica a la clase Definiciones. Una clase sellada sellada no puede heredarse directamente, excepto si la plantilla heredada se define en el mismo archivo origen que la clase heredada. Sin embargo, las subclases de una clase sellada se pueden heredar en cualquier lugar.

- M. Odersky. The Scala language specification, version 2.8. online, Sept., 2013.

Cuestiones relacionadas