你可以在 Scala 中总是用花括号交换方法参数括号。例如
def test(i: Int) {}
test { 3 }
此基础是参数表达式的定义,在Scala Language Specification (SLS) 的第 6.6 节中涵盖:
ArgumentExprs ::= ‘(’ [Exprs] ‘)’
| ‘(’ [Exprs ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ’)’
| [nl] BlockExpr
花括号被最后一种情况(块表达式)覆盖,本质上是‘{’ Block ‘}’(参见第 6 章 SLS 的开头)。
这不适用于条件表达式,if, (§6.16 SLS) 和 while 循环表达式 (§6.17 SLS),但它适用于 for 推导式 (§6.19 SLS),有点像不一致。
另一方面,模式匹配语句或模式匹配匿名函数字面量必须用花括号定义,例如{ case i: Int => i + i },此处不允许使用括号 (§8.5 SLS)。
在您的方法调用中,foreach 接受一个函数参数,因此您可以删除多余的括号或双括号:
List(1, 2).foreach({ case i => println(i) })
List(1, 2).foreach {{ case i => println(i) }}
List(1, 2).foreach { case i => println(i) } // no reason to have double braces
在这种情况下,模式匹配并不能真正为您带来任何好处,您可以使用常规(非模式匹配)函数,因此以下方法也可以:
List(1, 2).foreach(i => println(i)) // §6.23 SLS - anonymous functions
List(1, 2).foreach(println) // §6.26.2 / §6.26.5 - eta expansion
在您的情况下,Map 的 map 方法将键和值的元组传递给函数,这就是您使用模式匹配(case 语句)来解构该元组的原因,因此您被绑定了有花括号。这比写作更好
map1.foreach(tup => println("key " + tup._1 + " value " + tup._2)
作为旁注,在模式匹配案例主体周围放置大括号被认为是不好的风格;即使正文跨越多行,它们也不是必需的。所以不是
case(key, value) => { println("key " + key + " value " + value) }
你应该写
case (key, value) => println("key " + key + " value " + value)
关于在 Scala 中使用大括号、圆点和圆括号的不同变体,in this blog post 存在一些争议(“不喜欢的部分”部分)。最后,你要决定哪种风格最好——这就是提倡“自以为是”与“非自以为是”语言的人们相互争斗的地方。
通常,当表达式跨越多行或有模式匹配时,您需要花括号。当调用具有多个参数列表的方法时,通常最后一个列表包含一个函数参数,所以你会很好看——当然是主观判断——语法:
val l = List(1, 2, 3)
l.foldLeft(0) {
(sum, i) => sum + i
}