Scala: «неявные преобразования не применимы» в простом выражении - PullRequest
1 голос
/ 30 марта 2011

Сегодня я начал со 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 ]

1 голос
/ 31 марта 2011

Не используйте необработанный метод 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 голос
/ 31 марта 2011

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, вот исправление минимальный для приведенного выше кода:

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, это решение работает всегда.

0 голосов
/ 30 марта 2011

Я попробовал ваш код (с дополнительным println), и он работает в 2.8.1:

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

Может использоваться с:

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