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