Scala: 'implicit conversions are not applicable' in a simple for expression
I started out with Scala today, and I ran into an intriguing problem. I am running a for expression to iterate over the characters in a string, like such:
class Example {
开发者_StackOverflow社区def forString(s: String) = {
for (c <- s) {
// ...
}
}
}
and it is consistently failing with the message:
error: type mismatch; found : Int required: java.lang.Object Note that implicit conversions are not applicable because they are ambiguous: ... for (c <- s) { ^ one error found
I tried changing the loop to several things, including using the string's length and using hardcoded numbers (just for testing), but to no avail. Searching the web didn't yield anything either...
Edit: This code is the smallest I could reduce it to, while still yielding the error:
class Example {
def forString(s: String) = {
for (c <- s) {
println(String.format("%03i", c.toInt))
}
}
}
The error is the same as above, and happens at compile time. Running in the 'interpreter' yields the same.
Don't use the raw String.format
method. Instead use the .format
method on the implicitly converted RichString
. It will box the primitives for you. i.e.
jem@Respect:~$ scala
Welcome to Scala version 2.8.0.final (Java HotSpot(TM) Client VM, Java 1.6.0_21).
Type in expressions to have them evaluated.
Type :help for more information.
scala> class Example {
| def forString(s: String) = {
| for (c <- s) {
| println("%03i".format(c.toInt))
| }
| }
| }
defined class Example
scala> new Example().forString("9")
java.util.UnknownFormatConversionException: Conversion = 'i'
Closer, but not quite. You might want to try "%03d"
as your format string.
scala> "%03d".format("9".toInt)
res3: String = 009
Scala 2.81 produces the following, clearer error:
scala> class Example {
| def forString(s: String) = {
| for (c <- s) {
| println(String.format("%03i", c.toInt))
| }
| }
| }
<console>:8: error: type mismatch;
found : Int
required: java.lang.Object
Note: primitive types are not implicitly converted to AnyRef.
You can safely force boxing by casting x.asInstanceOf[AnyRef].
println(String.format("%03i", c.toInt))
^
Taking into account the other suggestion about String.format, here's the minimal fix for the above code:
scala> def forString(s: String) = {
| for (c: Char <- s) {
| println(String.format("%03d", c.toInt.asInstanceOf[AnyRef]))
| }}
forString: (s: String)Unit
scala> forString("ciao")
099
105
097
111
In this case, using the implicit format is even better, but in case you need again to call a Java varargs method, that's a solution which works always.
I tried your code (with an extra println) and it works in 2.8.1:
class Example {
| def forString(s:String) = {
| for (c <- s) {
| println(c)
| }
| }
| }
It can be used with:
new Example().forString("hello")
h
e
l
l
o
精彩评论