scala - Scala 中大括号和圆括号之间的正式区别是什么,何时应该使用它们?

标签 scala syntax parentheses braces

将参数传递给括号中的函数之间的正式区别是什么()和大括号 {} ?

我从Programming in Scala得到的感觉本书是 Scala 非常灵活,我应该使用我最喜欢的那个,但我发现有些情况可以编译,而另一些则不能。

例如(仅作为示例;我将不胜感激任何讨论一般情况的回复,而不仅仅是这个特定示例):

val tupleList = List[(String, String)]()
val filtered = tupleList.takeWhile( case (s1, s2) => s1 == s2 )

=> 错误:简单表达式的非法开始
val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }

=> 很好。

最佳答案

我曾经尝试过写这个,但最后我放弃了,因为规则有点分散。基本上,你必须掌握它的窍门。
也许最好将注意力集中在花括号和圆括号可以互换使用的地方:在将参数传递给方法调用时。当且仅当该方法需要单个参数时,您可以用花括号替换括号。例如:

List(1, 2, 3).reduceLeft{_ + _} // valid, single Function2[Int,Int] parameter

List{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter
但是,要更好地掌握这些规则,您还需要了解更多信息。
使用括号增加编译检查
Spray 的作者推荐圆括号,因为它们增加了编译检查。这对于像 Spray 这样的 DSL 尤其重要。通过使用括号,您告诉编译器它应该只给出一行;因此,如果您不小心给它两个或更多,它会提示。现在花括号不是这种情况——例如,如果你在某处忘记了一个运算符,那么你的代码将被编译,你会得到意想不到的结果,并且可能是一个很难找到的错误。下面是人为设计的(因为表达式是纯粹的并且至少会给出警告),但说明了这一点:
method {
  1 +
  2
  3
}

method(
  1 +
  2
  3
)
第一个编译,第二个给出 error: ')' expected but integer literal found .作者想写1 + 2 + 3 .
有人可能会争辩说,它与带有默认参数的多参数方法类似;使用括号时,不可能不小心忘记用逗号分隔参数。
冗长
关于冗长的一个重要的经常被忽视的注释。由于 Scala style guide 使用大括号不可避免地导致冗长的代码明确指出关闭大括号必须在自己的行上:

… the closing brace is on its own line immediately following the last line of the function.


许多自动重新格式化程序,如 IntelliJ,会自动为您执行此重新格式化。所以尽量坚持使用圆形括号。
中缀表示法
使用中缀表示法时,如 List(1,2,3) indexOf (2)如果只有一个参数,可以省略括号,写成 List(1, 2, 3) indexOf 2 .这不是点符号的情况。
另请注意,当您有一个多标记表达式的单个参数时,例如 x + 2a => a % 2 == 0 , 你必须使用括号来表示表达式的边界。
元组
因为有时可以省略括号,有时元组需要额外的括号,如 ((1, 2)) ,有时可以省略外括号,如 (1, 2) .这可能会引起混淆。
函数/部分函数文字与 caseScala 有函数和部分函数字面量的语法。它看起来像这样:
{
    case pattern if guard => statements
    case pattern => statements
}
唯一可以使用的其他地方 case声明与 matchcatch关键词:
object match {
    case pattern if guard => statements
    case pattern => statements
}
try {
    block
} catch {
    case pattern if guard => statements
    case pattern => statements
} finally {
    block
}
您不能使用 case任何其他上下文中的陈述。所以,如果你想使用 case ,你需要花括号。如果您想知道函数和部分函数文字之间的区别是什么,答案是:上下文。如果 Scala 需要一个函数,那么你得到的就是一个函数。如果它需要一个偏函数,你就会得到一个偏函数。如果两者都是预期的,则会给出关于歧义的错误。
表达式和块
括号可用于创建子表达式。花括号可用于创建代码块(这不是函数字面量,所以要小心尝试像使用它一样使用它)。一个代码块由多个语句组成,每个语句可以是一个导入语句、一个声明或一个表达式。它是这样的:
{
    import stuff._
    statement ; // ; optional at the end of the line
    statement ; statement // not optional here
    var x = 0 // declaration
    while (x < 10) { x += 1 } // stuff
    (x % 5) + 1 // expression
}

( expression )
所以,如果你需要声明、多条语句,一个 import或类似的东西,你需要花括号。并且因为表达式是一个语句,括号内可能出现在花括号内。但有趣的是代码块也是表达式,所以你可以在表达式中的任何地方使用它们:
( { var x = 0; while (x < 10) { x += 1}; x } % 5) + 1
因此,由于表达式是语句,而代码块是表达式,因此以下所有内容都是有效的:
1       // literal
(1)     // expression
{1}     // block of code
({1})   // expression with a block of code
{(1)}   // block of code with an expression
({(1)}) // you get the drift...
它们不可互换的地方
基本上,你不能代替{}()反之亦然。例如:
while (x < 10) { x += 1 }
这不是方法调用,因此您不能以任何其他方式编写它。好吧,您可以将花括号放在 condition 的括号内。 ,以及在代码块的花括号内使用括号:
while ({x < 10}) { (x += 1) }
所以,我希望这会有所帮助。

关于scala - Scala 中大括号和圆括号之间的正式区别是什么,何时应该使用它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4386127/

相关文章:

arrays - Scala非连续子数组

scala - 如何为协变泛型类型参数设置别名

php 语法区别 unix 和 windows

html - 此 'icon' block 的正确 HTML 语法

java - 明显的括号不好吗?

c - 在确定数组大小时,括号是否有所不同?

scala - Scala 集合如何能够从映射操作返回正确的集合类型?

image - 如何创建任意大小的黑白图像

bash - 理解 bash 中的 $' ' 引号

c++ - 使用额外括号时为 "error: expected expression"