Un sealed
trait ne peut être étendu que dans le même fichier que sa déclaration.
Ils sont souvent utilisés pour fournir une alternative à enums
. Puisqu'ils ne peuvent être étendus que dans un seul fichier, le compilateur connaît tous les sous-types possibles et peut en raisonner.
Par exemple avec la déclaration:
sealed trait Answer
case object Yes extends Answer
case object No extends Answer
Le compilateur émettra un avertissement si une correspondance n'est pas exhaustive:
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
Vous devez donc utiliser des traits scellés (ou une classe abstraite scellée) si le nombre de sous-types possibles est fini et connu à l'avance. Pour plus d'exemples, vous pouvez consulter les implémentations de liste et d' options .
En ce qui concerne
sealed
, oui. Ils partagent les différences normales entretrait
etclass
, bien sûr.Discutable.
Si vous en avez un
sealed class X
, vous devez vérifierX
ainsi que les sous-classes. Il n'en va pas de même poursealed abstract class X
ousealed trait X
. Donc, vous pourriez le fairesealed abstract class X
, mais c'est beaucoup plus verbeux que justetrait
et pour peu d'avantages.Le principal avantage d'utiliser un
abstract class
sur untrait
est qu'il peut recevoir des paramètres. Cet avantage est particulièrement pertinent lors de l'utilisation de classes de types. Disons que vous voulez construire un arbre trié, par exemple. Vous pouvez écrire ceci:mais vous ne pouvez pas faire ceci:
puisque les limites de contexte (et les limites de vue) sont implémentées avec des paramètres implicites. Étant donné que les traits ne peuvent pas recevoir de paramètres, vous ne pouvez pas le faire.
Personnellement, je préfère
sealed trait
et l'utilise à moins qu'une raison particulière ne me fasse utiliser unsealed abstract class
. Et je ne parle pas de raisons subtiles, mais de raisons que vous ne pouvez pas ignorer, telles que l'utilisation de classes de types.la source
[A: F]
) ne fonctionne pas de la même manière que les contraintes de variance. C'est plutôt le sucre syntaxique qui demande uneF[A]
portée implicite . Il est généralement utilisé pour invoquer des instances de classe d'une manière un peu plus subtile et plus facile à lire qu'un paramètre implicite ((implicit fa: F[A])
), mais il fonctionne toujours de la même manière sous le capot, et comme le souligne Daniel, les traits ne sont pas adaptés. cette.Sur le blog daily-scala :
la source
Je ressens également le besoin de vous indiquer les spécifications:
la source
brièvement:
et pour plus de détails Tout sur les traits scellés dans Scala
la source