你可以在ruby中执行以下操作:
l = [[1, 2], [3, 4], [5, 6]]
m = l.map {|(a, b)| a+b}
Run Code Online (Sandbox Code Playgroud)
但你不能在scala中执行以下操作:
val a = List((1, 2), (3, 4), (5, 6))
a.map((f, s) => f + s)
<console>:9: error: wrong number of parameters; expected = 1
a.map((f, s) => f + s)
Run Code Online (Sandbox Code Playgroud)
相反,你必须这样做:
a.map { case (f, s) => f + s }
Run Code Online (Sandbox Code Playgroud)
我发现这个相当冗长,因为scala定义了一个"元组"类型,我期待它也能在它之上提供语法糖,以便像上面那样隐式匹配.是否有一些深层原因导致不支持这种匹配?有更优雅的方式吗?
原因是您尝试使用的语法已经具有意义.当高阶函数需要双参数函数时使用它.例如,使用reduce或fold:
List(1,2,3).reduce((a,b) => a+b)
Run Code Online (Sandbox Code Playgroud)
更清洁的方法可以通过定义自己的隐式方法来实现:
import scala.collection.generic.CanBuildFrom
import scala.collection.GenTraversableLike
implicit class EnrichedWithMapt2[A, B, Repr](val
self: GenTraversableLike[(A, B), Repr]) extends AnyVal {
def mapt[R, That](f: (A, B) => R)(implicit bf: CanBuildFrom[Repr, R, That]) = {
self.map(x => f(x._1, x._2))
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
val a = List((1, 2), (3, 4), (5, 6))
a.mapt((f, s) => f + s) // List(3, 7, 11)
Run Code Online (Sandbox Code Playgroud)
你可以做一些其他的技巧,比如使用tupled,但它们并没有真正帮助你解决你描述的情况:
val g = (f: Int, s: Int) => f + s
a.map(g.tupled)
Run Code Online (Sandbox Code Playgroud)
要不就
a.map(((f: Int, s: Int) => f + s).tupled)
Run Code Online (Sandbox Code Playgroud)