Скала Карта foreach - PullRequest
       1

Скала Карта foreach

48 голосов
/ 23 декабря 2011

Дано:

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) => ?

Ответы [ 7 ]

74 голосов
/ 23 декабря 2011

Я не уверен насчет ошибки, но вы можете добиться того, что вы хотите, следующим образом:

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 ... }является частичной функцией.

28 голосов
/ 23 декабря 2011

упс, прочитайте документ неправильно, map.foreach ожидает функциональный литерал с аргументом кортежа!

так что

m.foreach((e: (String, Int)) => println(e._1 + "=" + e._2))

работает

15 голосов
/ 23 декабря 2011

Вам необходимо сопоставить с аргументом Tuple2 аргумент, чтобы назначить переменные его частям key, value. Вы можете сделать с очень немногими изменениями:

m.foreach{ case (key: String, value: Int) => println(">>> key=" + key + ", value=" + value)} 
14 голосов
/ 23 декабря 2011

Смущающее сообщение об ошибке - ошибка компилятора, которая должна быть исправлена ​​в 2.9.2 :

5 голосов
/ 23 декабря 2011

Отличный вопрос! Даже при явном вводе метода 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)}
                                                         ^
1 голос
/ 06 июля 2015

Docs говорит, что аргумент - это кортеж -> единица, поэтому мы можем легко сделать это

0 голосов
/ 27 сентября 2013

Еще один способ:

Map(1 -> 1, 2 -> 2).foreach(((x: Int, y: Int) => ???).tupled)

Однако для этого требуются явные аннотации типов, поэтому я предпочитаю частичные функции.

...