/ / Prečo metóda skopírovania skalárnych prípadov Scala je parametrizovaná len s premennými definovanými v triede prípadov? - scala

Prečo metóda skenovania triedy Skala v prípade písmen parametrizovaná len s premennými definovanými v triede prípadov? - scala

Prečo metóda skopírovania triedy Skala v prípade písmen parametrizovaná len s premennými definovanými v triede prípadov?

Otázka založená na Q & A:

Trieda kópie prípadu neudržiava stav zdedeného znaku

Stručné zhrnutie - ak je znak definovaný poľom a rozšírený podľa triedy prípadov, copy na triede prípadov vytvorí novú inštanciu triedy iba s premennými definovanými v triede prípadov bez rozšírenej tradície.

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

Tu, B4: () budú prázdne, zatiaľ čo B3:(3,2,1)

odpovede:

2 pre odpoveď č. 1

Pretože neexistuje rozumný spôsob, ako robiť to, čo chcete dôsledne.

Napríklad vygenerovaný kód pre copy može byť

def copy(str: String = this.str, list: List[Int] = this.list): B = {
val newB = B(str)
newB.list = list
newB
}

Dobre. Teraz čo sa stane, ak sa zmeníte list byť súkromný, alebo val namiesto a var? V oboch prípadoch newB.list = ... nebude kompilovať, tak aký kód by mal kompilátor generovať?


0 pre odpoveď č. 2

Ak naozaj chcete zachovať hodnotu list po kopírovaní (berúc do úvahy problematiku vymeniteľnosti, ktorú som spomenul v komentároch OP), môžete napísať svoje vlastné copy metóda.

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