Scala 编码标准 : curly braces on the same line

标签 scala

scala coding standards说明

Technically, Scala’s parser does support GNU-style notation with opening braces on the line following the declaration. However, the parser is not terribly predictable when dealing with this style due to the way in which semi-colon inference is implemented. Many headaches will be saved by simply following the curly brace convention demonstrated above.

我查了一下,没有找到任何真实的例子。任何人都可以用例子解释其背后的原因吗?有人在新行上使用花括号时遇到过问题吗?

最佳答案

考虑这个表达式:

someElement
{
   // Some code
}

这如何解释?它是一个表达式(例如一个值或不带参数的函数调用),后跟一个用大括号括起来的 block 语句吗?或者它是一个用大括号括住单个参数的函数调用?

如果Scala没有分号推断,也就是说,Scala需要分号以与Java<相同的方式表示语句的结束/em> 确实如此,那么可以很容易地区分两者,因为前者需要在第一行末尾有一个分号。然而,Scala 解析器必须推断 分号需要在哪里才能理解代码,有时它会出错。 (根据上下文,两种解释都是有效的,并且 Scala 解析器并不总是能够自行解决歧义。)

例如,假设 someElement 是一个带有按名称参数的函数。如果您尝试在 Scala REPL 中调用它,并打算将参数(在大括号内)放在另一行,您会发现单独输入 someElement 会导致错误:

> scala
Welcome to Scala 2.12.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_161).
Type in expressions for evaluation. Or try :help.

scala> def someElement(x: => Int): Int = {
     |   // Do something...
     |   x
     | }
someElement: (x: => Int)Int

scala> someElement
<console>:13: error: missing argument list for method someElement
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `someElement _` or `someElement(_)` instead of `someElement`.
       someElement
       ^

也就是说,您甚至没有输入大括号。但是,如果您输入以下内容,那就没问题了:

scala> someElement {
     |   10
     | }
res0: Int = 10

但是如果 someElement 是一个值怎么办?现在我们在 REPL 中看到了这一点:

scala> val someElement = 5
someElement: Int = 5

scala> someElement
res1: Int = 5

scala> {
     |   5
     | }
res2: Int = 5

现在REPL接受相同的代码,在不同的行上,作为两个不同的表达式。

让我们变得非常暧昧。假设 someElement 是一个值,但它现在是对采用单个参数的函数的引用。让我们看看可能的解释:

scala> def square(a: Int) = a * a
square: (a: Int)Int

scala> val someElement = square _
someElement: Int => Int = $$Lambda$1034/1609754699@74abbb

scala> someElement
res3: Int => Int = $$Lambda$1034/1609754699@74abbb

scala> {
     |   5
     | }
res4: Int = 5

也就是说,它被视为两个单独的语句:一个值后跟一个 block 语句。但是:

scala> someElement {
     |   5
     | }
res5: Int = 25

被视为对 square 的调用,参数为 5。

Scala 编译器比 REPL 更聪明,因为它可以立即查看所有代码,并尝试通过查看哪些替代方案来解决歧义最有道理,但其解释可能并不总是符合您的。

因此,正如您所看到的,将左大括号放在同一行(如果两个表达式链接)会使关系明确并消除歧义。或者,如果您希望将表达式明确地解析为单独的语句,请在第一行后添加分号。

(恕我直言,分号推断是 Scala 的致命弱点之一。)

关于Scala 编码标准 : curly braces on the same line,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49207924/

相关文章:

scala - 使用 Scala 在不同数据帧的列之间进行计算,其中包含类似 for 循环的内容

scala - 如何在 Scala 中对可变长度的重复序列进行分组

scala - [A,Future [B]]到Future [E [[A,B]]

scala - 是否需要调用 Future 方法参数 "by-name"?

未找到 scalacheck/scalatest : how to add it in sbt/scala?

scala - 如何在 dotty 中解压元组中的元素类型?

scala - 有没有一种快速的方法来显示在 Scala 控制台中声明的方法的代码?

json - Jackson Scala JSON 反序列化到案例类

java - Intellij 无法运行 Scala 代码

Scala 命名和默认参数以及隐式参数