2012-02-06 5 views
6

Je suis un problème avec la conversion implicite dans le code suivant:Scala problème de conversion implicite

trait A { 
    def send(s: String): String = { 
    println(s) 
    s 
    } 
} 

object X { 
    implicit def toB(a: A): B = new B(a) 

    class B(a: A) { 
    def <<(s: String): String = a send s 
    } 
} 

object Y { 
    implicit def toB(a: A): B = new B(a) 

    class B(a: A) { 
    } 
} 

object Test extends App { 
    import X._ 
    import Y._ 
    val a: A = new A {} 
    a << "Test" 
} 

La dernière instruction des causes de test erreur de compilation:

error: value << is not a member of A 
a << "Test" 

Cependant si je retire import Y._ de Test, il compile bien.

Notez que dans le code réel à la fois X.B et Y.B font partie de Scala DSL pour une bibliothèque Java et j'aimerais pouvoir utiliser les deux dans la même unité de compilation.

Répondre

7

Il semble que ce qui se passe est que Y.toB surcharge X.toB lorsque vous importez les deux dans la même étendue. Si je mets le import Y._avant puis import X._, alors cela fonctionne. En outre, si je renomme Y est implicite à quelque chose d'autre (par exemple toYB), alors cela fonctionne quel que soit l'ordre dans lequel vous l'avez mis.

+3

Et c'est ce que vous attendez. C'est comme une importation statique en Java. Si vous appeliez la méthode implicite comme 'toB (a)', comment le compilateur connaîtrait-il celui que vous vouliez utiliser si le dernier ne remplaçait pas l'autre? OP devrait donner les noms implicites de defs comme 'AtoXB' et' AtoYB' comme vous dites, parce que 'X.B' et' Y.B' sont des classes différentes. –

+0

En effet, d'une manière ou d'une autre, je ne m'attendais pas à ce que les noms de méthode implicites causent le problème. J'ai renommé et ça marche bien maintenant, merci! – elk

Questions connexes