Reputation: 28880
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
Reputation: 24769
Ok, let's start with the beginning, why does it fail in the first case:
String
into an Int
and to do so you call toInt
.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.Predef.augmentString
convert a String
into a StringOps
, which has such a method.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.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:Int
function when you have a String
.
Upvotes: 17