2010-07-25 5 views
2

Est-ce que quelqu'un sait ce qui se passe ici avec cette erreur de compilation? L'erreur disparaît si je ne prolonge pas l'INode.Problème de type dépendant du chemin abstrait Scala

trait AbsTypes 
{ 
    type TKey 
    type TValue 
} 

trait INode extends AbsTypes 
{ 
    def get(key : TKey) : TValue 
    def set(key : TKey, v : TValue) : INode 
} 

class ANode[TKey,TValue](
    val akey : TKey, 
    val aval : TValue 
) extends INode 
{ 
    // ERROR : type mismatch; found : ANode.this.aval.type (with underlying type TValue) required: ANode.this.TValue 
    def get(key : TKey) : TValue = { aval } 
    def set(key : TKey, v : TValue) : INode = { 
     new ANode(key,v) 
    } 
} 

Répondre

4

Les paramètres génériques ne remplacent pas automatiquement les types abstraits, même s'ils portent le même nom. Essayez de renommer les paramètres génériques (pour éviter les conflits de noms), puis déclarez les types TKey et TValue dans le corps de la méthode.

class ANode[A,B](
    val akey : A, 
    val aval : B 
) extends INode { 
    type TKey=A 
    type TValue=B 
    def get(key : TKey) : TValue = aval 
    def set(key : TKey, v : TValue) : INode = new ANode(key,v) 
} 

Je suppose que ce serait bien si le compilateur émis une erreur sur la ligne où vous avez spécifié les noms des types génériques, au lieu d'attendre jusqu'à ce que vous commencer à utiliser ces types.

+0

Merci, qui ont résolu cette partie, mais j'ai une question de suivi, je posterai séparément – ACyclic

+1

pourrait être utile d'ajouter ici http: // stackoverflow .com/questions/1332574/common-programming-errors-for-scala-developers-to-avoid – oluies

+0

@Brent, est-ce une erreur * commune *? –

1

Je n'ai malheureusement pas le temps de tester ce que je vais écrire mais ma compréhension de votre code est que chaque INode va avoir son propre type TValue. Donc, l'opération get retourne vraiment INode.this.TValue qui n'est pas compatible avec un autre type TValue sur un autre nœud.

La façon d'éviter cela pourrait être d'écrire:

trait Nodes { 
    type TKey 
    type TValue 

    trait INode { 
    def get(key : TKey) : TValue 
    } 

    class ANode(
    val akey : TKey, 
    val aval : TValue 
) extends INode 
} 
+0

Il aura toujours le même problème avec votre code, car 'akey' et' aval' sont des types nommés par les génériques, pas les types abstraits. (En outre, si vous compilez uniquement ce code, vous ne remarquerez aucune erreur de compilation car vous n'avez pas essayé d'utiliser les types en conflit.) –

+0

Oh, oui, c'est une erreur de copier/coller. Mon intention était d'utiliser les types du trait Nodes. – Eric

+0

J'ai modifié votre réponse pour refléter cette intention, et supprimé mon downvote. –

Questions connexes