2012-01-30 2 views
17

j'écris la conversion implicite suivante dans scala:Pourquoi ce type de conversion implicite est-il illégal?

implicit def strToInt2(str: String):Int = { 
    str.toInt 
    } 

Mais il monte cette erreur de compilation:

<console>:9: error: type mismatch; 
found : str.type (with underlying type String) 
required: ?{val toInt: ?} 
Note that implicit conversions are not applicable because they are ambiguous: 
both method augmentString in object Predef of type (x: String)scala.collection. 
immutable.StringOps 
and method toi in object $iw of type (str: String)Int 
are possible conversion functions from str.type to ?{val toInt: ?} 
      str.toInt 
     ^

Si je supprime le type de retour, déclare simplement comme ceci:

implicit def strToInt2(str: String) = { 
    str.toInt 
    } 

Il compile avec succès. Quelqu'un peut-il me dire quelle est la différence entre les deux?

+0

Je ne connais pas la réponse exacte, mais je suppose qu'il y a une chaîne de conversion implicite -> int dans Predef. Donc, ajouter une nouvelle conversion de ce type rend les choses ambiguës. – dmitry

Répondre

17

Ok, commençons par le début, pourquoi échouer dans le premier cas:

  1. Vous essayez de définir une méthode implicite qui transforme un String en un Int et de le faire vous appelez toInt. Malheureusement, toInt ne fait pas partie de la classe String. Ainsi, le compilateur doit trouver un implicite pour convertir str dans quelque chose qui a une méthode toInt:Int.
  2. Heureusement, Predef.augmentString convertir un String en StringOps, qui a une telle méthode. Mais le type Int a aussi une telle méthode et AS vous définissez un type de retour, la méthode strToInt2 peut être appelée récursivement, et comme la méthode est implicite, elle peut être appliquée pour transformer quelque chose avec une fonction toInt:Int.
  3. Le compilateur ne sait pas quelle méthode implicite à utiliser (entre le vôtre et Predef.augmentString et renvoie une erreur.

Dans le second cas, comme vous ne spécifiez pas le type de retour, la fonction strToInt2 ne peut pas être récursive, et il n'y a plus de deux candidats pour transformer le String

MAIS si après cette définition, vous essayez. "2".toInt, l'erreur est de retour: quand vous avez un String vous avez maintenant deux façons d'obtenir quelque chose avec une fonction toInt:Int

.
Questions connexes