【发布时间】:2014-07-20 21:27:54
【问题描述】:
我偶然发现了奇怪的 Scala 编译语法:
class Some extends {
def hi = println("hi")
}
伙计们:
- 它是 Scala 官方支持的语法吗?
- 这是否意味着简单地扩展
Object? - 它是否与“鸭子打字”有关?
- 你知道这个有趣或棘手的用法吗?
谢谢。
【问题讨论】:
我偶然发现了奇怪的 Scala 编译语法:
class Some extends {
def hi = println("hi")
}
伙计们:
Object?谢谢。
【问题讨论】:
这实际上是 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 就是一个例子,它完全等同于没有可选扩展的相同代码:
class Some {
def hi = println("hi")
}
【讨论】:
这实际上只是一个语法意外(我认为)。 Scala 允许 early definitions 看起来像
class Some extends {
...
} with ATrait
所以解析器也接受class Some extends { ... },相当于class Some { ... }(source)。
【讨论】:
是的,这是 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())
}
【讨论】:
type T = { def hi = println("hi") } - 它不能编译,因为结构类型不能有定义。