donné:
val m = Map[String, Int]("a" -> 1, "b" -> 2, "c" -> 3)
m.foreach((key: String, value: Int) => println(">>> key=" + key + ", value=" + value))
pourquoi le compilateur se plaint
error: type mismatch
found : (String, Int) => Unit
required: (String, Int) => ?
oups, lisez mal le doco, map.foreach attend un littéral de fonction avec un argument Tuple!
alors
m.foreach((e: (String, Int)) => println(e._1 + "=" + e._2))
travaux
Je ne suis pas sûr de l'erreur, mais vous pouvez obtenir ce que vous souhaitez comme suit:
m.foreach(p => println(">>> key=" + p._1 + ", value=" + p._2))
Autrement dit, foreach
prend une fonction qui prend une paire et renvoie Unit
, pas une fonction qui prend deux arguments: ici, p
a le type (String, Int)
.
Une autre façon de l'écrire est:
m.foreach { case (key, value) => println(">>> key=" + key + ", value=" + value) }
Dans ce cas, le { case ... }
block est une fonction partielle.
Vous devez faire correspondre les motifs sur l'argument Tuple2
Pour affecter des variables à ses sous-parties key
, value
. Vous pouvez le faire avec très peu de changements:
m.foreach{ case (key: String, value: Int) => println(">>> key=" + key + ", value=" + value)}
Le message d'erreur déroutant est un bogue du compilateur, qui devrait être corrigé dans 2.9.2 :
Excellente question! Même en tapant explicitement la méthode foreach, cela donne toujours cette erreur de compilation très peu claire. Il existe des moyens de contourner cela, mais je ne comprends pas pourquoi cet exemple ne fonctionne pas.
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 dit que l'argument est Tuple -> unité, donc nous pouvons facilement le faire
Map(1 -> 1, 2 -> 2).foreach(Tuple => println(Tuple._1 +" " + Tuple._2)))
Encore une autre façon:
Map(1 -> 1, 2 -> 2).foreach(((x: Int, y: Int) => ???).tupled)
Cependant, cela nécessite des annotations de type explicites, donc je préfère les fonctions partielles.