/ / s'appuie sur des méthodes de classe de cas en trait - scala, cas-classe

s'appuyer sur des méthodes de classe de cas en trait - scala, classe de cas

Existe-t-il un moyen de s'appuyer sur des méthodes définies dans la classe de cas dans un trait? Par exemple, copie: ce qui suit ne fonctionne pas. Je ne sais pas pourquoi, cependant.

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]

Donne:

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]
^

Réponses:

5 pour la réponse № 1

Je suppose que la méthode avec la copie du nom danstrait indique au compilateur de ne pas générer de copie de méthode dans la classe de cas. Par conséquent, dans votre exemple, la copie de méthode n'est pas implémentée dans votre classe de cas. Ci-dessous une courte expérience avec la copie de méthode implémentée dans trait:

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 pour la réponse № 2

Une solution consiste à déclarer que votre trait doit être appliqué à une classe avec une méthode de copie:

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

(malheureusement, vous ne pouvez pas utiliser de paramètre implicite dans la méthode de copie, car la déclaration implicite n'est pas autorisée dans la déclaration de type)

Ensuite, votre déclaration est ok:

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

(testé dans REPL scala 2.8.1)

La raison pour laquelle votre tentative ne fonctionne pas est expliquée dans la solution proposée par d’autres utilisateurs: votre copy déclaration bloquer la génération de la "case copy" méthode.


1 pour la réponse № 3

Vous pouvez lancer repl avec $ scala -Xprint: typer. Avec le paramètre -Xprint: typer, vous pouvez voir ce qui se passe exactement lorsque vous créez un trait ou une classe. Et vous verrez en sortie que la méthode "copy" n'est pas créée, donc le compilateur demande à la définir vous-même.