【问题标题】:Scala: 'implicit conversions are not applicable' in a simple for expressionScala:简单的 for 表达式中的“隐式转换不适用”
【发布时间】:2011-03-30 03:51:09
【问题描述】:

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

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

并且它始终失败并显示消息:

错误:类型不匹配; 发现:整数 必需:java.lang.Object 请注意,隐式转换不适用,因为它们不明确: ... 对于 (c

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

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

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

错误与上述相同,并且发生在编译时。在“解释器”中运行会产生相同的结果。

【问题讨论】:

  • 如果您显示更多/所有代码会有所帮助。您显示的代码 sn-p 似乎没问题。
  • 显示问题的邮政编码。如果帖子太长,则从中删除行,直到获得显示问题的最小样本。您甚至可能会找出问题所在。

标签: scala for-loop implicit-conversion


【解决方案1】:

不要使用原始的String.format 方法。而是对隐式转换的RichString 使用.format 方法。它将为您装箱。即

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

【讨论】:

    【解决方案2】:

    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 方法,这是一个始终有效的解决方案。

    【讨论】:

    • 我很难选择要选择哪个答案...但我最终在这里选择了 +1。
    • 我同意;这个答案解释了如何进行代码类型检查,但另一个答案解释了你应该更好地编写什么代码(正如我所说);所以它们是互补的。无论如何,谢谢,我很感激!
    • 更简洁的是c: Integer。
    【解决方案3】:

    我尝试了您的代码(带有额外的 println),它在 2.8.1 中有效:

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

    它可以用于:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-16
      相关资源
      最近更新 更多