假设:
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) => ?
假设:
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) => ?
我不确定错误的原因,但您可以按照以下方式实现所需的功能:
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 ... }
块是一个部分函数。抱歉,我误读了文档,map.foreach需要一个带有元组参数的函数字面值!
所以
m.foreach((e: (String, Int)) => println(e._1 + "=" + e._2))
工作
你需要对 Tuple2
参数进行模式匹配,以将变量分配给它的子部分 key
、value
。你可以用很少的改动来实现:
m.foreach{ case (key: String, value: Int) => println(">>> key=" + key + ", value=" + value)}
这个令人困惑的错误信息是编译器的一个bug,应该在2.9.2版本中得到修复:
非常好的问题!即使明确输入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)}
^
Map(1 -> 1, 2 -> 2).foreach(tuple => println(tuple._1 +" " + tuple._2)))
另一种方式:
Map(1 -> 1, 2 -> 2).foreach(((x: Int, y: Int) => ???).tupled)
然而,它需要显式类型注释,因此我更喜欢使用部分函数。