这是Scala代码
#1
def method1 = {
map1.foreach({
case(key, value) => { println("key " + key + " value " + value) }
})
}
#2
def method1 = {
map1.foreach{
case(key, value) => { println("key " + key + " value " + value) }
}
}
这几乎是我的意思,但是我想更清楚一点:为什么在这种情况下可以省略括号?
答案 0 :(得分:4)
您可以始终在Scala中为花括号交换方法参数括号。例如
def test(i: Int) {}
test { 3 }
这个的基础是参数表达式的定义,由Scala Language Specification (SLS)的第6.6节涵盖:
ArgumentExprs ::= ‘(’ [Exprs] ‘)’
| ‘(’ [Exprs ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ’)’
| [nl] BlockExpr
大括号由最后一个案例(块表达式)覆盖,基本上是‘{’ Block ‘}’
(参见第6章SLS的开头)。
这不适用于条件表达式if
,(§6.16SLS)和while
循环表达式(§6.17SLS),但它适用于for
理解(§6.19) SLS),有些不一致。
另一方面,模式匹配语句或模式匹配匿名函数文字必须用花括号定义,例如{ case i: Int => i + i }
,此处不允许使用括号(§8.5SLS)。
在方法调用中,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
的{{1}}方法将一个键和值的元组传递给函数,这就是你使用模式匹配(map
语句)来解构它的原因元组,所以你一定会有花括号。这比编写
case
作为旁注,在图案匹配案例主体周围放置大括号被认为是不好的风格;它们没有必要,即使身体跨越多条线。而不是
map1.foreach(tup => println("key " + tup._1 + " value " + tup._2)
你应该写
case(key, value) => { println("key " + key + " value " + value) }
关于在Scala中使用大括号,圆点和圆括号的不同变体,有一些论战in this blog post(“什么不喜欢”一节)。最后,你要决定哪种是最好的风格 - 这是人们提倡“自以为是”而非“不同意见”的语言相互斗争的地方。
通常,当表达式跨越多行或者模式匹配时,需要花括号。当使用多个参数列表调用方法时,通常最后一个列表包含一个函数参数,因此您可以获得很好的主观判断 - 语法:
case (key, value) => println("key " + key + " value " + value)