省略括号

时间:2013-06-20 10:05:05

标签: scala

这是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) }
   }
}

这几乎是我的意思,但是我想更清楚一点:为什么在这种情况下可以省略括号?

1 个答案:

答案 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)