我偶然遇到了奇怪的Scala语法编译:
class Some extends {
def hi = println("hi")
}
专家:
- 它是Scala支持的官方语法吗?
- 这是否意味着简单地扩展
Object
? - 它是否与“鸭子打字”有关?
- 你知道有趣或棘手的用法吗?
谢谢。
我偶然遇到了奇怪的Scala语法编译:
class Some extends {
def hi = println("hi")
}
专家:
Object
?谢谢。
这实际上是Scala语法中的一个奇怪的怪癖。一个无关紧要的 extends
在开始上课之前允许。以下是相关部分 Scala语法摘要:
ClassDef ::= id [TypeParamClause] {ConstrAnnotation} [AccessModifier]
ClassParamClauses ClassTemplateOpt
ClassTemplateOpt ::= ‘extends’ ClassTemplate | [[‘extends’] TemplateBody]
ClassTemplate ::= [EarlyDefs] ClassParents [TemplateBody]
ClassTemplateOpt
是类的参数之后的一切,在这种情况下一切都来自 extends
向前。通常使用 extends
是第一个轮换 ClassTemplateOpt
,与 extends
由父母或早期初始化者遵循。但是,早期初始化程序不能包含 def
,并且无法将大括号的内容解释为父级。它不能是结构类型,因为 hi
有一个具体的定义。
第二次交替允许类参数紧跟在类主体之后,而不使用 extends
。但是,可选 extends
被允许。该 extends
在OP的代码中就是一个例子,并且完全等同于没有可选扩展的相同代码:
class Some {
def hi = println("hi")
}
这实际上只是一个语法上的意外(我认为)。 Scala允许 早期定义 看起来像
class Some extends {
...
} with ATrait
所以解析器也接受了 class Some extends { ... }
这相当于 class Some { ... }
(资源)。
这实际上是Scala语法中的一个奇怪的怪癖。一个无关紧要的 extends
在开始上课之前允许。以下是相关部分 Scala语法摘要:
ClassDef ::= id [TypeParamClause] {ConstrAnnotation} [AccessModifier]
ClassParamClauses ClassTemplateOpt
ClassTemplateOpt ::= ‘extends’ ClassTemplate | [[‘extends’] TemplateBody]
ClassTemplate ::= [EarlyDefs] ClassParents [TemplateBody]
ClassTemplateOpt
是类的参数之后的一切,在这种情况下一切都来自 extends
向前。通常使用 extends
是第一个轮换 ClassTemplateOpt
,与 extends
由父母或早期初始化者遵循。但是,早期初始化程序不能包含 def
,并且无法将大括号的内容解释为父级。它不能是结构类型,因为 hi
有一个具体的定义。
第二次交替允许类参数紧跟在类主体之后,而不使用 extends
。但是,可选 extends
被允许。该 extends
在OP的代码中就是一个例子,并且完全等同于没有可选扩展的相同代码:
class Some {
def hi = println("hi")
}
这实际上只是一个语法上的意外(我认为)。 Scala允许 早期定义 看起来像
class Some extends {
...
} with ATrait
所以解析器也接受了 class Some extends { ... }
这相当于 class Some { ... }
(资源)。
是的,这是Scala的结构类型或更常见的鸭子打字。
object LoudDuck {
def quack(): String = "QUACK"
}
object QuietDuck {
def quack(): String = "quack"
}
object CowDuck {
def quack(): String = "moo"
}
def quackMyDuck(duck: { def quack(): String }) {
println(duck.quack())
}
scala>quackMyDuck(LoudDuck)
QUACK
scala>
scala>quackMyDuck(QuietDuck)
quack
scala>
scala>quackMyDuck(CowDuck)
moo
您还可以使用“type”关键字声明结构类型。
type Duck = { def quack(): String }
def quackMyDuck(duck: Duck) {
println(duck.quack())
}