(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
参数因此我不明白为什么我会收到错误。谁能解释一下呢?
答案 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