J'ai cherché dans Google pour trouver les différences entre a case class
et a class
. Tout le monde mentionne que lorsque vous souhaitez effectuer une correspondance de modèle sur la classe, utilisez la classe de cas. Sinon, utilisez des classes et mentionnez également des avantages supplémentaires tels que l'égalité et le remplacement du code de hachage. Mais sont-ce les seules raisons pour lesquelles on devrait utiliser une classe case au lieu d'une classe?
Je suppose qu'il devrait y avoir une raison très importante pour cette fonctionnalité dans Scala. Quelle est l'explication ou existe-t-il une ressource pour en savoir plus sur les classes de cas Scala?
la source
Techniquement, il n'y a pas de différence entre une classe et une classe de cas - même si le compilateur optimise certaines choses lors de l'utilisation des classes de cas. Cependant, une classe de cas est utilisée pour supprimer la plaque de chaudière pour un modèle spécifique, qui implémente des types de données algébriques .
Les arbres sont un exemple très simple de ces types. Un arbre binaire, par exemple, peut être implémenté comme ceci:
Cela nous permet de faire ce qui suit:
Notez que les arbres construisent et déconstruisent (par correspondance de motifs) avec la même syntaxe, qui est également exactement la façon dont ils sont imprimés (espaces moins).
Et ils peuvent également être utilisés avec des cartes ou des ensembles de hachage, car ils ont un hashCode valide et stable.
la source
(Vous avez déjà mentionné tout sauf le dernier).
Ce sont les seules différences par rapport aux classes ordinaires.
la source
Personne n'a mentionné que les classes de cas sont également des instances
Product
et héritent donc de ces méthodes:où
productArity
retourne le nombre de paramètres de classe,productElement(i)
retourne le i ème paramètre etproductIterator
permet de les parcourir.la source
Personne n'a mentionné que les classes de cas ont
val
des paramètres de constructeur, mais c'est également la valeur par défaut pour les classes régulières (ce qui, je pense, est une incohérence dans la conception de Scala). Dario a laissé entendre qu'il en était ainsi " immuable ".Notez que vous pouvez remplacer la valeur par défaut en ajoutant à chaque argument constructeur les
var
classes de cas. Cependant, la modification des classes de cas entraîne une variation temporelle de leurs méthodesequals
ethashCode
. [1]sepp2k a déjà mentionné que les classes de cas génèrent automatiquement des méthodes
equals
ethashCode
.Pas aussi un indiqué que les classes de cas créent automatiquement un compagnon
object
avec le même nom que la classe, qui contientapply
etunapply
méthodes. Laapply
méthode permet de construire des instances sans ajouter de préfixenew
. Launapply
méthode d'extraction permet la correspondance de motifs que d'autres ont mentionnée.De plus , le compilateur optimise la vitesse de
match
-case
appariement de formes pour les classes de cas [2].[1] Les classes de cas sont cool
[2] Classes de cas et extracteurs, p . 15 .
la source
La construction de classe de cas dans Scala peut également être considérée comme une commodité pour supprimer un passe-partout.
Lors de la construction d'une classe de cas, Scala vous donne ce qui suit.
apply
méthode que vous pouvez utiliser comme méthode d'usine. Vous obtenez l'avantage syntaxique du sucre de ne pas avoir à utiliser le nouveau mot clé.Parce que la classe est immuable, vous obtenez des accesseurs, qui ne sont que les variables (ou propriétés) de la classe mais pas de mutateurs (donc pas de possibilité de changer les variables). Les paramètres du constructeur sont automatiquement disponibles en tant que champs publics en lecture seule. Beaucoup plus agréable à utiliser que la construction de bean Java.
hashCode
,equals
et lestoString
méthodes par défaut et laequals
méthode compare un objet structurellement. Unecopy
méthode est générée pour pouvoir cloner un objet (certains champs ayant de nouvelles valeurs fournies à la méthode).Le plus grand avantage, comme cela a été mentionné précédemment, est le fait que vous pouvez faire correspondre les modèles sur les classes de cas. La raison en est que vous obtenez la
unapply
méthode qui vous permet de déconstruire une classe de cas pour extraire ses champs.En substance, ce que vous obtenez de Scala lors de la création d'une classe de cas (ou d'un objet cas si votre classe ne prend aucun argument) est un objet singleton qui sert à la fois de fabrique et d' extracteur .
la source
copy
méthode peut modifier les champs:val x = y.copy(foo="newValue")
Outre ce que les gens ont déjà dit, il existe des différences plus fondamentales entre
class
etcase class
1.
Case Class
n'a pas besoin d'être explicitenew
, alors que la classe doit être appelée avecnew
2.Par défaut, les paramètres des constructeurs sont privés dans
class
, tandis que son public danscase class
3. se
case class
comparer par valeurla source
Selon la documentation de Scala :
Une autre caractéristique du mot clé case est que le compilateur génère automatiquement plusieurs méthodes pour nous, y compris les méthodes familières toString, equals et hashCode en Java.
la source
Classe:
Mais si nous utilisons le même code mais que nous utilisons la classe de cas:
Classe de personne:
Correspondance de motif:
objet: singleton:
la source
Pour avoir la compréhension ultime de ce qu'est une classe de cas:
supposons la définition de classe de cas suivante:
puis procédez comme suit dans le terminal:
Scala 2.12.8 affichera:
Comme nous pouvons le voir, le compilateur Scala produit une classe régulière
Foo
et un objet compagnonFoo
.Passons en revue la classe compilée et commentons ce que nous avons:
Foo
classe, immuable:scala.Product
trait d' implémentation :scala.Equals
trait pour rendre les instances de classe de cas comparables pour l'égalité par==
:java.lang.Object.hashCode
pour obéir au contrat equals-hashcode:java.lang.Object.toString
:new
mot-clé:Object Foo: - méthode
apply
d'instanciation sansnew
mot-clé:unupply
pour utiliser la classe de cas Foo dans la correspondance de motifs:scala.runtime.AbstractFunction2
pour faire une telle astuce:tupled
from object retourne une fonction pour créer un nouveau Foo en appliquant un tuple de 2 éléments.La classe de cas n'est donc que du sucre syntaxique.
la source
Contrairement aux classes, les classes de cas ne sont utilisées que pour conserver des données.
Les classes de cas sont flexibles pour les applications centrées sur les données, ce qui signifie que vous pouvez définir des champs de données dans la classe de cas et définir la logique métier dans un objet compagnon. De cette façon, vous séparez les données de la logique métier.
Avec la méthode de copie, vous pouvez hériter une ou toutes les propriétés requises de la source et les modifier à votre guise.
la source
Personne n'a mentionné que l'objet compagnon de classe de cas a une
tupled
défense, qui a un type:Le seul cas d'utilisation que je peux trouver est lorsque vous devez construire une classe de cas à partir de tuple, par exemple:
Vous pouvez faire de même, sans tupled, en créant directement un objet, mais si vos jeux de données exprimés sous forme de liste de tuple avec arity 20 (tuple avec 20 éléments), vous pouvez utiliser tupled est votre choix.
la source
Une classe de cas est une classe qui peut être utilisée avec l'
match/case
instruction.Tu vois ça
case
est suivi d'une instance de classe Fun dont le 2e paramètre est un Var. Il s'agit d'une syntaxe très agréable et puissante, mais elle ne peut pas fonctionner avec les instances de n'importe quelle classe, il existe donc des restrictions pour les classes de cas. Et si ces restrictions sont respectées, il est possible de définir automatiquement le hashcode et les égaux.L'expression vague "un mécanisme de décomposition récursive via la correspondance de motifs" signifie simplement "qu'il fonctionne avec
case
". (En effet, l'instance suiviematch
est comparée (comparée à) l'instance suivantecase
, Scala doit les décomposer tous les deux et décomposer récursivement ce dont ils sont faits.)Quelles classes de cas sont utiles? L' article de Wikipedia sur les types de données algébriques donne deux bons exemples classiques, des listes et des arbres. La prise en charge des types de données algébriques (y compris savoir comment les comparer) est un must pour tout langage fonctionnel moderne.
Pour quelles classes de cas ne sont pas utiles? Certains objets ont un état, le code
connection.setConnectTimeout(connectTimeout)
n'est pas pour les classes de cas.Et maintenant, vous pouvez lire A Tour of Scala: Case Classes
la source
Je pense que dans l'ensemble toutes les réponses ont donné une explication sémantique sur les classes et les classes de cas. Cela pourrait être très pertinent, mais chaque débutant dans scala devrait savoir ce qui se passe lorsque vous créez une classe de cas. J'ai écrit ceci réponse, qui explique la classe de cas en un mot.
Chaque programmeur doit savoir que s'il utilise des fonctions prédéfinies, il écrit un code relativement moins, ce qui lui permet de donner le pouvoir d'écrire le code le plus optimisé, mais le pouvoir s'accompagne de grandes responsabilités. Donc, utilisez des fonctions prédéfinies avec beaucoup de précautions.
Certains développeurs évitent d'écrire des classes de casse en raison de 20 méthodes supplémentaires, que vous pouvez voir en désassemblant le fichier de classe.
Veuillez vous référer à ce lien si vous souhaitez vérifier toutes les méthodes à l'intérieur d'une classe de cas .
la source
la source
Certaines des fonctionnalités clés de
case classes
sont répertoriées ci-dessousnew
mot-clé.Exemple de code scala sur scala fiddle, tiré des documents scala.
https://scalafiddle.io/sf/34XEQyE/0
la source