Scala не позволяет мне добавлять целые числа

Вот код, который выглядит достаточно разумным для меня:

val myMap: Map[Int, Int] = ((x: Int) => Map[Int, Int](1 -> x + 1, 2 -> x + 2))(4)

Когда я пытаюсь его скомпилировать, я получаю две ошибки:

Error:(20, 68) type mismatch;
 found   : Int(1)
 required: String
    val myMap: Map[Int, Int] = ((x: Int) => Map[Int, Int](1 -> x + 1, 2 -> x + 2))(4)
                                                                   ^

Я понимаю, что мой компилятор пытается использовать реализацию сложения строк +, Но почему он это делает? Как мне попросить компилятор использовать целочисленное сложение здесь?

(Изменение Int в Integer не помогает.)

3 ответа

Решение

Вот более простой пример, который воспроизводит ошибку:

scala> def fail(x: Int) = 1 -> x + 1
<console>:10: error: type mismatch;
 found   : Int(1)
 required: String
       def fail(x: Int) = 1 -> x + 1
                                   ^

Все операторы в игре являются ассоциативными слева, поэтому все читается слева направо. То есть цепочка вызовов выглядит так:

1.->(x).+(1)

или используя инфиксную запись:

(1 -> x) + 1

1 -> x возвращает кортеж (1, x) и кортеж не имеет + метод, поэтому компилятор пытается неявно преобразовать его в String с помощью toString, так как String есть + метод, который в конечном итоге терпит неудачу, потому что Int необходимо.

Просто используйте скобки, чтобы сгруппировать вещи соответствующим образом:

scala> def foo(x: Int) = 1 -> (x + 1)
foo: (x: Int)(Int, Int)

'->' имеет тот же приоритет, что и '+', поэтому 1 -> x + 1 разбирает как (1 -> x) + 1, Добавление скобок как 1 -> (x + 1) исправляет эту ошибку.

Проблема в том, что в соответствии с правилами приоритетов Scala, -> связывает так же крепко, как +потому что это начинается с -,

Это исправлено добавлением скобок:

val myMap: Map[Int, Int] = ((x: Int) => Map[Int, Int](1 -> (x + 1), 2 -> (x + 2)))(4)
Другие вопросы по тегам