我曾经尝试过写这篇文章,但最后我放弃了,因为规则有些分散。基本上,你必须掌握它。
也许最好专注于花括号和圆括号可以互换使用的地方:将参数传递给方法调用时。当且仅当方法需要单个参数时,您可以用花括号替换括号。例如:
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 明确指出右花括号必须在自己的行中:
…右大括号在最后一行之后
函数行。
许多自动重新格式化程序(例如 IntelliJ 中的)会自动为您执行重新格式化。所以尽量坚持使用圆括号。
中缀表示法
使用中缀表示法时,如List(1,2,3) indexOf (2),如果只有一个参数,可以省略括号,写成List(1, 2, 3) indexOf 2。这不是点符号的情况。
另请注意,当您有一个参数是多标记表达式时,例如 x + 2 或 a => a % 2 == 0,您必须使用括号来指示表达式的边界。
元组
因为有时可以省略括号,所以有时元组需要额外的括号,例如((1, 2)),有时可以省略外括号,例如(1, 2)。这可能会引起混淆。
带有case 的函数/部分函数字面量
Scala 具有函数和部分函数字面量的语法。它看起来像这样:
{
case pattern if guard => statements
case pattern => statements
}
您可以使用case 语句的唯一其他地方是使用match 和catch 关键字:
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 }
这不是一个方法调用,所以你不能用任何其他方式编写它。好吧,您可以将花括号 inside 放在 condition 的括号中,也可以将括号 inside 放在代码块的花括号中:
while ({x < 10}) { (x += 1) }
所以,我希望这会有所帮助。