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)