Mise à jour: décantées et élargi, étant donné que la question initiale a été simplifiée trop loinScala génériques récursives: Parent [enfant] et enfant [Parent]
je besoin d'une paire de traits, dont chacun se réfère à l'autre tel que les classes parentales et les enfants doivent être en relation les uns avec les autres.
trait Parent [C <: Child] {
def foo(c: C)
}
trait Child [P <: Parent] {
def parent: P = ...
def bar = parent.foo(this)
}
telle que les cours de mise en œuvre doivent venir par paires:
class ActualParent extends Parent [ActualChild] {
def foo(c: ActualChild) = ...
}
class ActualChild extends Child [ActualParent] {
}
Malheureusement, le compilateur n'aime pas ces traits parce que les types génériques ne sont pas complets. Au lieu de il faut dire C <: Child[
quelque chose]
. les laissant sans précision ne fonctionne pas non plus:
trait Parent [C <: Child[_]] {
def foo(c: C)
}
trait Child [P <: Parent[_]] {
def parent: P = ...
def bar = parent.foo(this)
}
Il se plaint maintenant sur la ligne parent.foo(this)
, parce qu'il ne sait pas que this
est du type correct. Le type de parent
doit être Parent[this.type]
pour l'appel au foo
pour avoir les bons types.
Je pense qu'il doit y avoir une façon de faire référence au propre type d'un objet? Ou à un type qui doit être lui-même?
Mise à jour: Suite à @ la réponse de Daniel, j'ai essayé d'utiliser un membre de type abstrait chez l'enfant d'indiquer les types génériques de type parent comme celui-ci:
trait Parent [C <: Child] {
def foo(c: C)
}
trait Child {
type P <: Parent[this.type]
def parent: P = ...
def bar = parent.foo(this)
}
Ce ISN « t travailler lorsque je tente de la mettre en œuvre:
class ActualParent extends Parent [ActualChild] {
def foo(c: ActualChild) = ...
}
class ActualChild extends Child {
type P = ActualParent
}
donne l'erreur suivante:
overriding type Parent in trait Child with bounds >: Nothing <: Parent[ActualChild.this.type]
type Parent has incompatible type
Qu'est-ce que cela signifie?
Cela semble correct. Maintenant, comment pourriez-vous développer cela pour inclure les chaînes de parent -> enfant -> enfant? –
Cette approche est couronnée de succès, mais je ne me sens pas très satisfait. Je ne suis pas sûr de pouvoir expliquer pourquoi. –