如果我这样做:
val l = Seq(("un", ""), ("deux", "hehe"), ("trois", "lol"))
l map { t => t._1 + t._2 }
没关系。
如果我这样做:
val l = Seq(("un", ""), ("deux", "hehe"), ("trois", "lol"))
l map { case (b, n) => b + n }
也没问题。
但如果我这样做:
val l = Seq(("un", ""), ("deux", "hehe"), ("trois", "lol"))
l map { (b, n) => b + n }
它不起作用。
我为什么要使用" case"使用命名元组的关键字?
答案 0 :(得分:6)
2.11的错误消息更具说明性:
scala> l map { (b, n) => b + n }
<console>:9: error: missing parameter type
Note: The expected type requires a one-argument function accepting a 2-Tuple.
Consider a pattern matching anonymous function, `{ case (b, n) => ... }`
l map { (b, n) => b + n }
^
<console>:9: error: missing parameter type
l map { (b, n) => b + n }
^
对于申请,您将获得“自动翻译”:
scala> def f(p: (Int, Int)) = p._1 + p._2
f: (p: (Int, Int))Int
scala> f(1,2)
res0: Int = 3
你提供了两个args而不是一个。
但你没有得到自动解决。
答案 1 :(得分:1)
使用types
内部函数可以理解这种情况。
首先,map
函数的参数函数的类型语法如下:
Tuple2[Int,Int] => B //Function1[Tuple2[Int, Int], B]
第一个参数功能扩展到此。
(t:(Int,Int)) => t._1 + t._2 // type : Tuple2[Int,Int] => Int
这没关系。然后是第二个功能。
(t:(Int, Int)) => t match {
case (a:Int, b:Int) => a + b
}
这也没关系。在故障情形中,
(a:Int, b:Int) => a + b
让我们检查一下功能的类型
(Int, Int) => Int // Function2[Int, Int, Int]
所以参数函数类型错误。
作为一种解决方案,您可以使用Function对象中的辅助函数将多个arity函数转换为元组模式并向后转换。你可以这样做。
val l = Seq(("un", ""), ("deux", "hehe"), ("trois", "lol"))
l map(Function.tupled((b, n) => b + n ))
请参阅Function API了解更多信息。
答案 2 :(得分:0)
传递给应用于序列的map函数的函数参数的类型由序列中元素的类型推断。特别是,
方案1:l map { t => t._1 + t._2 }
与l map { t: ((String, String)): (String) => t._1 + t._2 }
相同但更短,这可能是因为类型推断。 Scala编译器自动推断参数的类型为(String, String) => String
方案2:你也可以用更长的形式写作
l map { t => t match {
case(b, n) => b + n
}
}
方案3:将错误类型的函数传递给map,类似于
def f1 (a: String, b: String) = a + b
def f2 (t: (String, String)) = t match { case (a, b) => a + b }
l map f1 // won't work
l map f2