Scala类扩展{}

Max*_*Max 12 types scala

我偶然遇到了奇怪的Scala语法编译:

class Some extends {
  def hi = println("hi")
}
Run Code Online (Sandbox Code Playgroud)

专家:

  • 它是Scala支持的官方语法吗?
  • 这是否只是意味着扩展Object
  • 它是否与"鸭子打字"有关?
  • 你知道这个有趣或棘手的用法吗?

谢谢.

win*_*ner 7

这实际上是Scala语法中的一个奇怪的怪癖.extends在开始课堂主体之前允许无关紧要.以下是Scala语法摘要中的相关部分:

ClassDef          ::=  id [TypeParamClause] {ConstrAnnotation} [AccessModifier] 
                       ClassParamClauses ClassTemplateOpt 
ClassTemplateOpt  ::=  ‘extends’ ClassTemplate | [[‘extends’] TemplateBody]
ClassTemplate     ::=  [EarlyDefs] ClassParents [TemplateBody]
Run Code Online (Sandbox Code Playgroud)

ClassTemplateOpt是类的参数之后的所有内容,在这种情况下从一extends开始就是一切.通常使用的extends是第一次交替ClassTemplateOpt,extends由父母或早期初始化者遵循.但是,早期的初始化程序不能包含a def,并且无法将大括号的内容解释为父级.它不能是结构类型,因为它hi具有一个具体的定义.

第二次交替允许类参数紧跟在类体之后,而不使用extends.但是,extends允许使用可选项.的extends在OP的代码是这样的一个例子,并且是完全等同于相同的代码没有可选延伸:

class Some {
  def hi = println("hi")
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*nov 6

这实际上只是一个语法上的意外(我想).Scala允许早期定义看起来像

class Some extends {
  ...
} with ATrait
Run Code Online (Sandbox Code Playgroud)

所以解析器也接受class Some extends { ... }相当于class Some { ... } (源)的.

  • 看来,预先初始化/早期定义不允许声明函数.执行以下操作将无法编译:trait ATrait; class Some使用ATrait扩展{def hi = println("hi")} (2认同)