3

http://www.artima.com/pins1ed/builtin-control-structures.html#7.7,我看到以下代码

val a = 1;
{
  val a = 2
  println(a)
}
println(a)

它说这里需要分号,但为什么呢?

根据http://www.artima.com/pins1ed/classes-and-objects.html#4.2的规则,我认为应该自动添加分号,因为

  1. val a = 1可以是法律声明。
  2. 下一行以 开头{,我认为这可以作为法律声明的开始。(因为如果我添加分号并将前两行分成两个语句,则不会出现编译错误。)
  3. val a = 1不在括号或方括号中。
4

1 回答 1

5

因为这将是一个合法的呼吁apply

implicit class RichInt(i: Int) {
  def apply(thunk: => Unit) = 33
}

val a = 1
{
  val a = 2
  println(a)
}
println(a)  // 33 !

1 { ... }是 的缩写1.apply {...}。现在默认情况下apply没有为 a 定义Int,但正如隐式丰富所显示的那样,这是完全可能的。


编辑:分号推断条件在Scala Language Specification的 '§1.2 Newline Characters' 中描述。nl推断的分号在该文本中称为“特殊标记” 。

一般来说,给出了三个规则(在此博客条目中总结了前否定),在您的示例中,它们都得到满足。分号仍然没有被推断出来的原因在文中进一步给出。

Scala 语法 ... 包含接受可选nl标记但不接受分号的产生式。这具有在这些位置之一中的换行符不会 [!] 终止表达式或语句的效果。

这种额外规则的相关案例如下:

接受单个换行符
- 在左大括号“{”之前,如果该大括号是当前语句或表达式的合法延续......

示例 1.2.2 显示了我在评论中提到的匿名子类的情况。

于 2013-09-03T15:39:58.293 回答