/ / spoliehať sa na metódy prípadovej triedy v znaku - scala, prípadová trieda

spoliehajú sa na metódy triedy prípadov v znakoch - scala, case-class

Existuje spôsob, ako sa spoľahnúť na metódy definované v prípade triedy v znaku? Napr. Kópia: nasledovné nefunguje. Nie som si istý, prečo.

trait K[T <: K[T]] {
val x: String
val y: String
def m: T = copy(x = "hello")
def copy(x: String = this.x, y: String = this.y): T
}

case class L(val x: String, val y: String) extends K[L]

dáva:

error: class L needs to be abstract, since method copy in trait K of type
(x: String,y: String)L is not defined
case class L(val x: String, val y: String) extends K[L]
^

odpovede:

5 pre odpoveď č. 1

Predpokladám, že mať metódu s kopírovaním názvu vo Windowstrait dáva pokyn kompilátoru, aby negeneroval kópiu metódy v triede prípadu - takže vo vašom príklade nie je kópia metódy implementovaná vo vašej triede prípadov. Nižší krátky experiment s implementáciou kópie metódy do znaku:

scala> trait K[T <: K[T]] {
| val x: String
| val y: String
| def m: T = copy(x = "hello")
| def copy(x: String = this.x, y: String = this.y): T = {println("I"m from trait"); null.asInstanceOf[T]}
| }

defined trait K

scala> case class L(val x: String, val y: String) extends K[L]
defined class L

scala> val c = L("x","y")
c: L = L(x,y)

scala> val d = c.copy()
I"m from trait
d: L = null

12 pre odpoveď č. 2

Riešením je vyhlásiť, že váš znak musí byť aplikovaný na triedu metódou kopírovania:

trait K[T <: K[T]] {this: {def copy(x: String, y: String): T} =>
val x: String
val y: String
def m: T = copy(x = "hello", y)
}

(v metóde kopírovania bohužiaľ nemôžete použiť implicitný parameter, pretože v deklarácii typu nie je povolená implicitná deklarácia)

Potom je vaše vyhlásenie v poriadku:

case class L(val x: String, val y: String) extends K[L]

(testované v REPL scala 2.8.1)

Dôvod, prečo váš pokus nefunguje, je vysvetlený v riešení navrhnutom inými používateľmi: váš copy vyhlásenie blokuje generovanie „case copy"metóda. \ t


1 pre odpoveď č. 3

Môžete spustiť repl s $ scala -Xprint: typer.Pomocou parametra -Xprint: typer môžete vidieť, čo sa presne deje, keď vytvoríte vlastnosť alebo triedu. A z výstupu uvidíte, že metóda „copy“ nebola vytvorená, takže kompilátor požaduje, aby ste ju definovali sami.