11
votes

Erreur de référence ambiguë parasite dans SCALA 2.7.7 Compilateur / interprète?

Quelqu'un peut-il expliquer l'erreur de compilée ci-dessous? Fait intéressant, si je modifie le type de retour de la méthode code> code> à chaîne code>, le code compile tout simplement bien. Notez que la méthode ThuReTurn code> comporte deux surcharges: une méthode unaire et une méthode varargs qui prend au moins un argument. Il me semble que si l'invocation est ambiguë ici, il serait toujours ambigu.

Plus important encore, y a-t-il un moyen de résoudre l'ambiguïté? P>

import org.scalatest.mock.MockitoSugar
import org.mockito.Mockito._

trait Thing { 
   def get(): java.lang.Object 
}

new MockitoSugar {   
   val t = mock[Thing]  

   when(t.get()).thenReturn("a")  
}


2 commentaires

J'ai ouvert un billet à ce sujet, comme je l'ai découvert Scala n'était même pas conforme à elle-même. Billet Lamsvn.epfl.ch/trac/scala/ticket/2991 .


Le billet a été fermé comme invalide et il y a maintenant une explication quant à ce qui se passe, que je copierai à ma propre réponse. À l'heure actuelle, je ne pense pas qu'il y ait beaucoup de chances de changer cela.


5 Réponses :


5
votes

Eh bien, j'ai compris comment résoudre l'ambiguïté (semble être évidente de rétrospective): xxx

comme ANDREAS a noté, si la méthode ambiguë nécessite une référence null plutôt que d'un tableau vide , vous pouvez utiliser quelque chose comme xxx

pour résoudre l'ambiguïté.


1 commentaires

C'est la réponse réelle (bien que Daniel Sobral soit bien sûr très informatif). Bien que j'ai trouvé que je devais fournir une matrice du type de retour plutôt que simplement un tableau [objet].



10
votes

Eh bien, il est ambigu. Je suppose que Java Semantics le permet, et cela pourrait mériter un billet pour demander une sémantique Java d'être appliquée à Scala.

La source de l'ambiguït est la suivante: un paramètre Vararg peut recevoir n'importe quel nombre d'arguments, y compris 0. Ainsi, Lorsque vous écrivez TURETURN ("A") code>, voulez-vous appeler le theReturn code> qui reçoit un seul argument ou voulez-vous appeler le theReturn Code> qui reçoit un objet plus un Vararg, passant 0 arguments à la Vararg? P>

Maintenant, ce que ce genre de chose se passe, Scala essaie de trouver quelle méthode est "plus précise". Toute personne intéressée par les détails devrait rechercher que dans la spécification de Scala, mais voici l'explication de ce qui se passe dans ce cas particulier: P>

scala> def f(t: Tuple2[Int, Int]) = t._1 + t._2
f: (t: (Int, Int))Int

scala> f(1,2)
res0: Int = 3


0 commentaires

4
votes

Si vous regardez les API de la bibliothèque standard, vous verrez ce numéro manipulé comme ceci:

def meth(t1: Thing): OtherThing = { ... }
def meth(t1: Thing, t2: Thing, ts: Thing*): OtherThing = { ... }


2 commentaires

Cela semble être un meilleur moyen de l'écrire. Malheureusement, Thenreturn est défini dans une bibliothèque Java tierce (Makito). Comme Daniel a souligné que Java résout l'ambiguïté à la méthode des non-varargs, je ne peux même pas appeler un bug dans la bibliothèque.


Et il est fort probable d'être vulnérable à l'ambiguïté lors du passage de deux paramètres, maintenant que je comprends la question.



4
votes

J'ai eu un problème similaire à l'aide d'ovale (ovale.sf.net) essayant d'appeler sa validate () - méthode.

ovale définie 2 validation () Méthodes: P>

both method validate in class Validator of type (x$1: Any,x$2: <repeated...>[java.lang.String])java.util.List[net.sf.oval.ConstraintViolation]                                                          
and  method validate in class Validator of type (x$1: Any)java.util.List[net.sf.oval.ConstraintViolation]                                                                                               
match argument types (T)                                                                                                                                                                                
        var violations = validator.validate(entity);                                                                                                                                                    


1 commentaires

Merci d'avoir ajouté votre cas, Andreas. Je l'ai documenté sur le ticket de TRAC de Daniel ( Lamsvn.epfl.ch/trac/scala/ticket/ 2991 ) aussi bien.



7
votes

Dans le cas spécifique de Mockito, il est possible d'utiliser les méthodes d'API alternatives conçues pour une utilisation avec des méthodes de vide: xxx

clunky, mais cela devra faire, comme Martin et al Ne semble pas susceptible de compromettre Scala afin de prendre en charge les varargs de Java.


0 commentaires