使用case语句破坏Scala中的元组的规则

and*_*nka 7 scala

我有以下代码:

val xs = List(('a', 1), ('a', 2), ('b', 3), ('b', 4))
Run Code Online (Sandbox Code Playgroud)

我想把它变成一张地图.例如Map('a' -> Seq(1,2), 'b' -> Seq(3,4)).所以我继续写转换:

xs.groupBy(_._1) map {
  case (k, v) => (k, v.map(_._2))
}
Run Code Online (Sandbox Code Playgroud)

为什么地图后的括号需要是a {.当我开始时,我假设我可以做以下事情:

xs.groupBy(_._1).map(case (k, v) => (k, v.map(_._2)))
Run Code Online (Sandbox Code Playgroud)

但那不编译.

om-*_*nom 12

因为.map 方法接受一个函数

你真正写的是

map({
  case (k, v) => (k, v.map(_._2))
})
Run Code Online (Sandbox Code Playgroud)

并且{ case (k, v) => (k, v.map(_._2)) }模式匹配匿名函数(SLS,§8.5)的快捷方式定义,它是函数类型之一:

val isOdd: PartialFunction[Int, String] = {
   case x if x % 2 == 1 => x+" is odd"
}

val upcastedIsOdd: Function[Int, String] = {
   case x if x % 2 == 1 => x+" is odd"
}
Run Code Online (Sandbox Code Playgroud)

你不能省略花括号(所以你会松开部分功能和模式匹配的区别),但你可以跳过纯括号(并保留部分功能),就像下面的代码片段一样:

scala> List(1,2,3).take(1)
//res0: List[Int] = List(1)
scala> List(1,2,3) take 1
//res1: List[Int] = List(1)
Run Code Online (Sandbox Code Playgroud)


Kip*_*ros 2

看来这里真正的问题是何时可以使用括号代替(大括号{来表示匿名函数。我建议看一下 Daniel Sobral对这个问题的回答: Scala 中大括号和圆括号之间的正式区别是什么,以及何时应该使用它们?