Scala:在一个简单的表达式中,“隐式转换不适用”

时间:2011-03-30 03:51:09

标签: scala for-loop implicit-conversion

我今天开始使用Scala,我遇到了一个有趣的问题。我正在运行for表达式来迭代字符串中的字符,如:

class Example {
  def forString(s: String) = {
    for (c <- s) {
      // ...
    }
  }
}

并且始终没有显示消息:

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

我尝试将循环更改为几个东西,包括使用字符串的长度和使用硬编码的数字(仅用于测试),但无济于事。搜索网络也没有产生任何结果......

编辑:此代码是我可以减少的最小代码,同时仍然会产生错误:

class Example {
  def forString(s: String) = {
    for (c <- s) {
      println(String.format("%03i", c.toInt))
    }
  }
}

错误与上面相同,并在编译时发生。在'解释器'中运行产生相同的结果。

3 个答案:

答案 0 :(得分:1)

不要使用原始String.format方法。而是在隐式转换的.format上使用RichString方法。它将为您打包基元。即。

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'

更近,但并不完全。您可能希望尝试"%03d"作为格式字符串。

scala> "%03d".format("9".toInt)
res3: String = 009

答案 1 :(得分:1)

Scala 2.81产生以下更明确的错误:

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

考虑到有关String.format的其他建议,这里是上面代码的 minimal 修复:

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

在这种情况下,使用隐式格式甚至更好,但是如果您再次需要调用Java varargs方法,那么这是一个始终有效的解决方案。

答案 2 :(得分:0)

我尝试了你的代码(带有额外的println),它适用于2.8.1:

class Example {
     | def forString(s:String) = {
     |   for (c <- s) {
     |    println(c)   
     |   }
     | }
     | }

它可以用于:

new Example().forString("hello")
h
e
l
l
o