该阶编码标准状态
从技术上讲,Scala的解析器确实支持GNU风格的表示法,并在声明后的行上打开括号.但是,由于实现了分号推断的方式,解析器在处理此样式时并不是非常可预测的.通过简单地遵循上面演示的花括号约定,可以节省许多麻烦.
我看了,我找不到任何真实的例子.任何人都可以用exmaple来解释这背后的原因吗?有没有人在新线上使用花括号时遇到问题?
考虑这个表达式:
someElement
{
// Some code
}
Run Code Online (Sandbox Code Playgroud)
这怎么解释?它是一个表达式(例如一个值,或一个没有参数的函数调用)后跟一个括在括号内的块语句?或者它是一个函数调用,括号括起一个参数?
如果Scala没有分号推断 - 也就是说,如果Scala要求分号以与Java相同的方式表示语句的结尾- 那么这两者可以很容易地区分,因为前者需要在分号结尾处使用分号第一行.但是,Scala解析器必须推断分号在哪里才能理解代码,有时它会出错.(根据上下文,这两种解释都是有效的,并且Scala解析器并不总是能够自行解决歧义.)
例如,假设这someElement
是一个带有by name参数的函数.如果你试图在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
^
Run Code Online (Sandbox Code Playgroud)
也就是说,你甚至没有进入大括号.但是,如果您输入以下内容,那么您就可以了:
scala> someElement {
| 10
| }
res0: Int = 10
Run Code Online (Sandbox Code Playgroud)
但是,如果someElement
是一个价值呢?现在我们在REPL中看到这个:
scala> val someElement = 5
someElement: Int = 5
scala> someElement
res1: Int = 5
scala> {
| 5
| }
res2: Int = 5
Run Code Online (Sandbox Code Playgroud)
现在,REPL在不同的行上接受相同的代码,作为两个不同的表达式.
让我们变得非常暧昧.Say 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
Run Code Online (Sandbox Code Playgroud)
也就是说,它被视为两个单独的语句:一个值后跟一个块语句.然而:
scala> someElement {
| 5
| }
res5: Int = 25
Run Code Online (Sandbox Code Playgroud)
被视为square
参数为5 的调用.
在斯卡拉编译器比聪明一点REPL,因为它可以一次性看到所有的代码,并试图通过了解哪些替代品的最有意义,以解决歧义,但其解释不总是匹配你的.
因此,正如您所看到的,将开括号放在同一行 - 如果两个表达式是链接的 - 使关系显式化并消除歧义.或者,如果您希望将表达式明确地解析为单独的语句,请在第一行之后添加分号.
(恕我直言,分号推断是斯卡拉的阿喀琉斯之踵.)