Qu’est-ce qu’un trait scellé?

Les classes scellées sont décrites dans «Programmation en Scala», mais les traits scellés ne le sont pas. Où puis-je trouver plus d’informations sur un trait scellé?

J’aimerais savoir si un trait scellé est identique à une classe scellée? Ou, sinon, quelles sont les différences? Quand est-ce une bonne idée d’utiliser un trait scellé (et quand pas)?

    Un trait sealed ne peut être étendu que dans le même fichier que sa déclaration.

    Ils sont souvent utilisés pour fournir une alternative aux enums . Comme ils ne peuvent être étendus que dans un seul fichier, le compilateur connaît tous les sous-types possibles et peut les 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") | } :12: warning: match is not exhaustive! missing combination Yes 

    Vous devez donc utiliser des traits scellés (ou 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 listes et d’ options .

    un trait scellé est le même qu’une classe scellée?

    En ce qui concerne le sealed , oui. Ils partagent naturellement les différences entre les trait et les class .

    Ou, sinon, quelles sont les différences?

    Discutable.

    Quand est-ce une bonne idée d’utiliser un trait scellé (et quand pas)?

    Si vous avez une sealed class X , vous devez vérifier X ainsi que toute sous-classe. La même chose n’est pas vraie de sealed abstract class X ou du sealed trait X Donc, vous pouvez faire sealed abstract class X , mais c’est beaucoup plus verbeux que juste le trait et pour peu d’avantage.

    Le principal avantage de l’utilisation d’une abstract class sur un trait est qu’il peut recevoir des parameters. Cet avantage est particulièrement pertinent lorsque vous utilisez des classes de type. Disons que vous voulez construire un arbre sortingé, par exemple. Vous pouvez écrire ceci:

     sealed abstract class Tree[T : Ordering] 

    mais vous ne pouvez pas faire ceci:

     sealed trait Tree[T : Ordering] 

    car les limites de contexte (et les limites de vue) sont implémentées avec des parameters implicites. Étant donné que les traits ne peuvent pas recevoir de parameters, vous ne pouvez pas le faire.

    Personnellement, je préfère le sealed trait et je l’utilise à moins qu’une raison particulière me fasse utiliser une sealed abstract class . Et je ne parle pas de raisons subtiles, mais pour des raisons que vous ne pouvez pas ignorer, comme l’utilisation de classes de type.

    Du blog quotidien-scala :

    Lorsqu’un trait est “scellé”, toutes ses sous-classes sont déclarées dans le même fichier et cela rend l’ensemble des sous-classes finies, ce qui permet certaines vérifications du compilateur.

    Je ressens également le besoin de vous indiquer les spécifications:

    Le modificateur scellé s’applique aux définitions de classe. Une classe scellée ne peut pas être directement héritée, sauf si le modèle hérité est défini dans le même fichier source que la classe héritée. Cependant, les sous-classes d’une classe scellée peuvent être héritées n’importe où.

    – M. Odersky. La spécification du langage Scala, version 2.8. en ligne, sept. 2013.

    brièvement:

    • Les traits scellés ne peuvent être étendus que dans le même fichier
    • Lister ceci permet au compilateur de connaître facilement tous les sous-types possibles
    • Utiliser des traits scellés lorsque le nombre de sous-types possibles est fini et connu à l’avance
    • Une façon de créer quelque chose comme enum en Java
    • Aide à la définition des types de données algébriques (ADT)

    et pour plus de détails Tout sur les traits scellés à Scala