Implicit conversion from String to Int in scala 2.8
Is there something I've got wrong with the following fragment:-
object Imp {
implicit def string2Int(s: String): Int = s.toInt
def f(i: Int) = i
def main(args: Array[String]) {
val n: Int = f("666")
}
}
I get the following from the 2.8 compiler:-
Information:Compilation completed with 1 error and 0 warnings
Information:1 error Information:0 warnings ...\scala-2.8-tests\src\Imp.scala E开发者_运维知识库rror:Error:line (4)error: type mismatch; found : String required: ?{val toInt: ?} Note that implicit conversions are not applicable because they are ambiguous: both method string2Int in object Imp of type (s: String)Int and method augmentString in object Predef of type (x:String)scala.collection.immutable.StringOps are possible conversion functions from String to ?{val toInt: ?} implicit def string2Int(s: String): Int = s.toIntWhat is happening is that Java does not define a toInt
method on String
. In Scala, what defines that method is the class StringOps
(Scala 2.8) or RichString
(Scala 2.7).
On the other hand, there is a method toInt
available on Int
as well (through another implicit, perhaps?), so the compiler doesn't know if it is to convert the string to StringOps
, through the defined implicit, or to Int
, through your own implicit.
To solve it, call the implicit explicitly.
object Imp {
implicit def string2Int(s: String): Int = augmentString(s).toInt
def f(i: Int) = i
def main(args: Array[String]) {
val n: Int = f("666")
}
}
There is already an implicit conversion in scope, from scala.Predef
. You don't need to declare your own implicit conversion to add a toInt
method to a String
. You have 3 options (I'd go for the last one!):
- Change your method name to something like
asInt
- Unimport the conversion in
Predef
- Don't bother defining your own and use instead the
toInt
that comes bundled with the scala library
Note that scala will only make use of an in-scope implicit conversion if it is unique.
I think I have a workaround.
If I create a RichString from the String argument, the implicit conversion occurs from RichString to Int using the implicit method I provide (this works for 2.7.x and 2.8). If I remove my implicit I get a type error.
object Imp {
implicit def string2Int(rs: RichString): Int = rs.toInt
def f(i: Int) = i
def main(args: Array[String]) {
val n: Int = f(new RichString("666"))
println(n)
}
}
I'm still confused as to why both implicits came into scope and clashed when I provided an implicit and as to why the Predef one didn't come into scope when I didn't provide one for String to Int. I suppose the question about an implicit conversion from String to Int remains open.
精彩评论