Pourquoi la méthode de copie de classe de cas Scala paramétrée uniquement avec les variables définies dans la classe de cas?
La question basée sur le Q & A:
La copie de classe de cas ne conserve pas l'état d'un trait hérité
Bref résumé - lorsque trait est défini avec un champ et étendu par une classe de cas, copy
sur la classe de cas créera la nouvelle instance de classe uniquement avec les variables définies dans la classe de cas, sans trait étendu
trait A {
var list: List[Int] = List()
def add(element: Int) = {
list = element :: list
}
}
case class B(str: String) extends A {
val b = B("foo")
println("B1: " + b.list)
b.add(1)
b.add(2)
b.add(3)
println("B2: " + b.list)
val b2 = b.copy(str = "bar")
println("B3: " + b.list)
println("B4: " + b2.list)
}
Ici, B4: ()
sera vide, alors que B3:(3,2,1)
Réponses:
2 pour la réponse № 1Parce qu'il n'y a pas de moyen raisonnable de faire ce que vous voulez de manière constante.
Pour votre exemple, le code généré pour copy
pourrait être
def copy(str: String = this.str, list: List[Int] = this.list): B = {
val newB = B(str)
newB.list = list
newB
}
Assez bien. Maintenant que se passe-t-il si vous changez list
être privé, ou un val
au lieu d'un var
? Dans les deux cas newB.list = ...
ne va pas compiler, alors quel code le compilateur doit-il générer?
0 pour la réponse № 2
Si vous voulez vraiment garder la valeur de list
après la copie (compte tenu du problème de mutabilité que j’ai mentionné dans les commentaires de OP), vous pouvez écrire votre propre copy
méthode.
case class B(str: String) extends A {
def copy(str: String = this.str, list: List[Int] = this.list): B = {
val newB = B(str)
list.reverse.foreach(newB.add)
newB
}
}