超级不在运营商的位置?

时间:2011-04-16 21:33:36

标签: scala

在Scala中,当方法调用处于操作符位置时,通过调用方法来存在语法糖。例如,(5).+(3)可以写为5 + 3。对此的规则是<object>.<method>(<parameter>)。这个规则是正确的,点和圆括号可以留下。但我发现这个规则有一个例外:它无法在操作员位置编写超级关键字:

class X {
  def x(i: Int) = i * 2
}
class Y extends X {
  override def x(i: Int) = super.x(i + 1)
}

当我将点留在超级后面时,我得到编译器错误。在这里,super是对象,x方法和i + 1参数因此我不明白为什么我会收到错误。谁能解释一下呢?

1 个答案:

答案 0 :(得分:5)

我认为这是因为super关键字必须(但请参阅huynhjl的评论和下面的详细信息)后跟.,然后是有效的成员标识符 - 它似乎是语法生成规则

考虑val expr = (super)没有任何有用的意义,应始终无效(在这方面,它与this完全不同,后者本身就是一个有效的表达式)。在语法级别要求super.member形式是可能是有意的,但它需要一些挖掘。故意按照规范的措辞(参见huynhjl的评论)和语法“摘要”规则。

class X {
  def x(): X = this
}
class Y extends X {
  // Still kaboom of course -- message is effectively the same
  // and indicates a grammar production has been violated.
  // Message: error: '.' expected but '}' found.
  override def x(): X = super
}

快乐的编码。


更新(参考):

来自第6.5节中的Scala Language Specification 2.8讨论super

  
    

引用super.m静态引用到方法或类型m至少是正确的     包含引用的最里面模板的超类型。它评估为     该模板的实际超类型中的成员,等于m或其中     覆盖m静态引用的成员m必须是类型或方法     ...     超级前缀后跟特征限定符[T],如C.super[T].x中所示。这个     被称为静态超级引用。在这种情况下,引用的是类型或方法     x的父级特征C,其简称为T

  

从Scala语法摘要(A章):

stableId ::= id
           | Path ‘.’ id
           | [id ’.’] ‘super’ [ClassQualifier] ‘.’ id