wake-up-neo.com

Scala Map foreach

gegeben:

val m = Map[String, Int]("a" -> 1, "b" -> 2, "c" -> 3)
m.foreach((key: String, value: Int) => println(">>> key=" + key + ", value=" + value))

warum beschwert sich der Compiler?

error: type mismatch
found   : (String, Int) => Unit
required: (String, Int) => ?
48
Dzhu

oops, lies das doco falsch, map.foreach erwartet ein Funktionsliteral mit einem Tuple-Argument!

so

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

funktioniert

29
Dzhu

Ich bin mir über den Fehler nicht sicher, aber Sie können das, was Sie wollen, folgendermaßen erreichen:

m.foreach(p => println(">>> key=" + p._1 + ", value=" + p._2))

Das heißt, foreach nimmt eine Funktion, die ein Paar annimmt und Unit zurückgibt, nicht eine Funktion, die zwei Argumente annimmt: Hier hat p den Typ (String, Int).

Eine andere Art zu schreiben ist:

m.foreach { case (key, value) => println(">>> key=" + key + ", value=" + value) }

In diesem Fall ist der { case ... } Block ist eine Teilfunktion.

75
Philippe

Sie müssen das Argument Tuple2 Mit einem Muster abgleichen, um den Unterabschnitten key, value Variablen zuzuweisen. Sie können mit sehr wenigen Änderungen tun:

m.foreach{ case (key: String, value: Int) => println(">>> key=" + key + ", value=" + value)} 
15
huitseeker

Die verwirrende Fehlermeldung ist ein Compiler-Fehler, der behoben werden sollte in 2.9.2 :

14
Paul Butcher

Hervorragende Frage! Selbst wenn die foreach-Methode explizit eingegeben wird, ist der Kompilierungsfehler immer noch sehr unklar. Es gibt verschiedene Möglichkeiten, aber ich kann nicht verstehen, warum dieses Beispiel nicht funktioniert.

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)}
                                                         ^
5
Eishay Smith

Laut Docs ist das Argument Tuple -> unit, also können wir das leicht tun

Map(1 -> 1, 2 -> 2).foreach(Tuple => println(Tuple._1 +" " + Tuple._2)))
1
vikashait

Noch ein anderer Weg:

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

Es sind jedoch explizite Typanmerkungen erforderlich, daher bevorzuge ich Teilfunktionen.

0
Yaroslav