当Scala中的赋值语句后跟花括号时,分号推断不起作用?

时间:2013-09-03 15:30:39

标签: scala

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不在括号或括号中。

1 个答案:

答案 0 :(得分: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定义Int,但正如隐式浓缩显示的那样,它是完全可能的。


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

一般来说,给出了三条规则(ex-negativo in this blog entry),在你的例子中,它们都是满意的。仍然没有推断出分号的原因在文中进一步说明了。

  

Scala语法...包含可选nl令牌但不接受分号的作品。这会导致其中一个位置的换行符[!]终止表达式或语句。

此类额外规则的相关案例如下:

  

接受单个新线路令牌    - 在开头括号“{”前面,如果该括号是当前陈述或表达的合法延续......

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