我偶然遇到了奇怪的编译Scala语法:
class Some extends {
def hi = println("hi")
}
专家:
Object
?感谢。
答案 0 :(得分:7)
这实际上是Scala语法中的一个奇怪的怪癖。在开始课堂主体之前,允许使用无关的extends
。以下是Scala Syntax Summary:
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
。 OP代码中的extends
就是一个例子,它完全等同于没有可选extends的相同代码:
class Some {
def hi = println("hi")
}
答案 1 :(得分:6)
这实际上只是一个语法上的意外(我认为)。 Scala允许early definitions看起来像
class Some extends {
...
} with ATrait
因此解析器也接受class Some extends { ... }
,相当于class Some { ... }
(source)。
答案 2 :(得分:-1)
是的,这是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 Duck = { def quack(): String }
def quackMyDuck(duck: Duck) {
println(duck.quack())
}