为什么在编程中会使用花括号而不是圆括号?

14

在很多Scala的例子中,我看到人们在某些地方使用花括号,这让我感到非常奇怪,因为同样的语句可以很容易地用括号来表示。

例如:

lst foreach (x => println(s"the value returned is: $x")) // parens
lst foreach {x => println(s"you get the idea, $x")} // braces

我知道你可以使用大括号作为括号的替代,因为它允许你将语句写在多行上:

val res = for {
  x <- coll1
  y <- coll2
} yield (x, y) 
  • 当代码写成一行时,使用其中一个相对于另一个是否有内在的原因?
  • 最终的结果应该是相同的,或者我漏掉了什么吗?
  • 还是这只是风格和/或个人喜好的问题?

1
除了 foreach,在柯里化函数时,如果最后一个参数是一个函数,使用 { } 允许你创建(类似)新的控制结构。在实践中非常有用。 - VH-NZZ
实际上,阅读Odersky等人所写的《Scala编程》第9章。 - VH-NZZ
3个回答

18

通常来讲,有很多情况下你可能更喜欢用花括号(例如多行表达式,for 推导式),但是现在我们具体谈论一下:

当它只写在一行时,有没有任何固有的理由选择其中之一

在第二种情况中,这不仅仅是花括号代替圆括号,而是省略了圆括号的花括号。Scala 有时允许你省略括号,后一种语法用于访问你在部分函数中获得的某些好处(即模式匹配),所以

lst foreach {x => println(s"you get the idea, $x")}

实际上是

lst foreach({x => println(s"you get the idea, $x")})

正如我所说,从模式匹配的角度来看,这可能是有用的:

val map = Map("foo" -> "bar")
map foreach { case (k, v) => println(s"key: $k, value: $v") }
// which is not possible with the usual parenthesis

我故意省略了“case”版本,因为它似乎是多余的。 - Electric Coffee
1
即使有最初的限定词,这仍然有点误导——有很多情况下你需要其中一个(例如for推导不允许({ ... })),或者括号根本不起作用(match)。 - Travis Brown
@TravisBrown同意,还有许多其他情况,但是op特别询问当它写在一行上时,是否有任何固有的理由使用其中之一?不过我会添加免责声明。 - om-nom-nom

2
这是一则关于代码风格的问题。请参考http://www.codecommit.com/scala-style-guide.pdf
如果你传递的函数仅包含一个表达式,你可以使用任意一种方式,结果相同。但是,如果函数包含多个表达式,则必须使用大括号。因此,我总是更喜欢使用大括号。除此之外,我认为这样做可以使你的意图更加清晰。(请注意,我们所说的是单个表达式,而不是单行。例如:
lst map (x => findInDatabase(x)
               .getOrElse(ERROR_VALUE))

如果函数是单个表达式,即使它被拆分成多行,findInDatabase(x).getOrElse(ERROR_VALUE)也可以。

另外,如果函数当前是单个表达式,以后需要将其更改为多个表达式,则必须记住将括号更改为大括号(需要记住的另一件事)。


0

只有当函数只接受一个参数时,才能使用花括号。这样做的想法是让方法调用感觉更像控制抽象。所以,你是对的,这确实是一种风格问题。


在柯里化函数的最后一个参数中也很有用。 - VH-NZZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接