zjffdu
zjffdu

Reputation: 28880

Why this type of implicit conversion is illegal?

I write the following implicit conversion in scala:

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

But it rises this compilation error:

<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
           ^

If I remove the return type, just declare it like this:

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

It compiles successfully. Can anyone tell me what's the difference between the two ?

Upvotes: 17

Views: 1808

Answers (1)

Nicolas
Nicolas

Reputation: 24769

Ok, let's start with the beginning, why does it fail in the first case:

  1. You try to define an implicit method that transforms a String into an Int and to do so you call toInt.
  2. Unfortunately, toInt is not a part of the String class. Thus, the compiler needs to find an implicit to convert str in something that has a toInt:Int method.
  3. Fortunately, Predef.augmentString convert a String into a StringOps, which has such a method.
  4. But the Int type also have such a method and AS you define a return type, the method strToInt2 can be called recursively, and as the method is implicit, it can be applied to transform something with a toInt:Int function.
  5. The compiler doesn't know which implicit method to use (between yours and Predef.augmentString and throws an error.

In the second case, as you omit the return type, the strToInt2 function cannot be recursive, and there are no longer two candidates to transform the String.

BUT if after this definition, you try: "2".toInt, the error is back: you now have two ways to obtain something with a toInt:Intfunction when you have a String.

Upvotes: 17

Related Questions