scala - scala 中什么时候必须使用分号?

标签 scala syntax semicolon-inference

我正在学习如何在 Scala 中编程,并被告知分号在 Scala 中是可选的。因此,考虑到这一点,我尝试使用以下没有分号的嵌套代码块。但是,它在 Scala REPL 中引发错误

scala> { val a = 1
 | {val b = a * 2
 | {val c = b + 4
 | c}
 | }
 | }
<console>:17: error: Int(1) does not take parameters
   {val b = a * 2

带有分号的示例工作得很好。

scala> { val a = 1;
 | { val b = a*2;
 | { val c = b+4; c}
 | }
 | }
res22: Int = 6

因此,在我看来,分号并不是真正可选的,并且在某些情况下是强制性的。请问什么情况下必须加分号?

最佳答案

我将尝试从您的示例中提取精华。

考虑以下代码片段:

{ val x = 1 { val y = 2 } }

对于编译器来说,它看起来像是

的语法糖
{ val x = 1.apply({ val y = 2 }) }

但是对象 1 没有使用 block 的 apply 方法,因此编译器会产生错误:

error: Int(1) does not take parameters

  { val x = 1 { val y = 2 } }
              ^

对比一下

object I { def apply(a: => Any): Unit = () }
{ val x = I { val y = 2 } }

这是可行的,因为现在确实有一个apply方法。

为了更容易区分这两种情况,编译器需要在第一种情况下使用分号。

现在,人们可能想知道为什么 val x = 1{ 之间的换行符没有转换为推断的分号。我认为规范中的相关引用是这样的( 1.2 Newline Characters )(省略了枚举的大部分部分([...]),强调我的):

The Scala grammar [...] contains productions where optional nl tokens, but not semicolons, are accepted. This has the effect that a newline in one of these positions does not terminate an expression or statement. These positions can be summarized as follows:

[...]

  • in front of an opening brace ‘{’, if that brace is a legal continuation of the current statement or expression,

    [...]

请注意,此引用仅涵盖带有单个可选换行符的情况。它不适用于两个或多个连续换行符,例如

scala> {
     |   val x = 1
     | 
     |   { val y = 2 }
     | }

有效,并且 { val y = 2 } 被解析为单独的表达式。

我猜想的动机是允许嵌入带有语法糖的 DSL,如下所示:

MY_WHILE(x >= 0)
{
  println(x)
  x -= 1
}

如果必须将每个这样的 MY_WHILE 语句括在一对额外的圆括号中,那会很奇怪,不是吗?

关于scala - scala 中什么时候必须使用分号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52017702/

相关文章:

scala - Playframework设置取决于环境

scala - akka 类 Receive 定义在哪里?

java - 如何在两个 JVM 实例之间共享内存?

syntax - 优先类型在右侧的运算符的原因

java - Java 中数组的不常见语法

php - PHP Heredoc语法(<<<)在关闭Heredoc时始终在注释我的代码?

python - if 语句在分号分隔符后使用时失败

scala - Scala 的哪些特性允许使用 Props[SomeActor] 语法