Ответ 1
oops, прочитайте doco wrong, map.foreach ожидает литерал функции с аргументом кортежа!
так
m.foreach((e: (String, Int)) => println(e._1 + "=" + e._2))
работы
Дано:
val m = Map[String, Int]("a" -> 1, "b" -> 2, "c" -> 3)
m.foreach((key: String, value: Int) => println(">>> key=" + key + ", value=" + value))
почему компилятор жалуется
error: type mismatch
found : (String, Int) => Unit
required: (String, Int) => ?
oops, прочитайте doco wrong, map.foreach ожидает литерал функции с аргументом кортежа!
так
m.foreach((e: (String, Int)) => println(e._1 + "=" + e._2))
работы
Я не уверен в ошибке, но вы можете добиться того, чего хотите:
m.foreach(p => println(">>> key=" + p._1 + ", value=" + p._2))
То есть foreach
берет функцию, которая берет пару и возвращает Unit
, а не функцию, которая принимает два аргумента: здесь p
имеет тип (String, Int)
.
Другой способ записать это:
m.foreach { case (key, value) => println(">>> key=" + key + ", value=" + value) }
В этом случае блок { case ... }
является частичной функцией.
Запутанное сообщение об ошибке - ошибка компилятора, которая должна быть исправлена в 2.9.2:
Для аргумента Tuple2
вам нужно сопоставить patter-match, чтобы назначить переменные своим подстрокам key
, value
. Вы можете сделать очень мало изменений:
m.foreach{ case (key: String, value: Int) => println(">>> key=" + key + ", value=" + value)}
Отличный вопрос! Даже при явном вводе метода foreach он все еще дает очень неясную ошибку компиляции. Есть способы обойти это, но я не могу понять, почему этот пример не работает.
scala> m.foreach[Unit] {(key: String, value: Int) => println(">>> key=" + key + ", value=" + value)}
<console>:16: error: type mismatch;
found : (String, Int) => Unit
required: (String, Int) => Unit
m.foreach[Unit] {(key: String, value: Int) => println(">>> key=" + key + ", value=" + value)}
^
Docs говорит, что аргумент tuple → unit, поэтому мы можем легко сделать это
Map(1 -> 1, 2 -> 2).foreach(tuple => println(tuple._1 +" " + tuple._2)))
Еще один способ:
Map(1 -> 1, 2 -> 2).foreach(((x: Int, y: Int) => ???).tupled)
Однако для этого требуются явные аннотации типа, поэтому я предпочитаю частичные функции.