/ / 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? - scala

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? - scala

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 № 1

Parce 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
}
}