在Scala的Martin Odersky的recent post about levels of programmer ability中,在专家库设计器部分中,他包含术语“早期初始化程序”。
Programming in Scala 中未提及这些内容。它们是什么?
答案 0 :(得分:99)
早期初始化程序是子类的构造函数的一部分,该子类旨在在其超类之前运行。例如:
abstract class X {
val name: String
val size = name.size
}
class Y extends {
val name = "class Y"
} with X
如果代码编写为
class Z extends X {
val name = "class Z"
}
然后在初始化Z
时会发生空指针异常,因为size
在初始化的正常排序(类前超类)中name
之前被初始化。
答案 1 :(得分:2)
据我所知,动机(如上面的链接所示)是:
“自然地,当val被覆盖时,它不会被初始化多次。所以虽然上面例子中的x2似乎在每个点都被定义,但情况并非如此:在构造过程中,重写的val似乎为null超类,以及抽象的val。“
我不明白为什么这很自然。 r.h.s.完全有可能作业可能会产生副作用。请注意,这样的代码结构在C ++或Java中是完全不可能的(我会猜测Smalltalk,尽管我不会说这种语言)。实际上你必须隐含这样的双重赋值... ticilpmi ...通过构造函数在这些语言中显示。根据r.h.s.s.副作用的不确定性,它看起来真的不是一种动机:通过ASSIGNMENT回避超类副作用(从而排除超类不变量)的能力?伊克!
是否有其他“杀手”动机允许这种不安全的代码结构?面向对象的语言在没有这种机制的情况下已经存在了大约40年(30多年,如果你从语言的创建中算起),为什么现在包括它呢?
...只是......似乎......危险。
答案 2 :(得分:1)
第二个想法,一年......
这只是蛋糕。字面上。
不是早期的任何事情。只是蛋糕(mixins)。
蛋糕是由The Grand Pooh-bah自己创造的一个术语/模式,它采用Scala的特质系统,它在一个类和一个界面之间。它远比Java的装饰模式好。
所谓的“接口”只是一个未命名的基类,而以前的基类就是一个特征(我坦率地说不知道可以做到)。我不清楚“with'd”类是否可以接受参数(特征不能),会尝试并报告。
这个问题及其答案已经成为Scala最酷的功能之一。阅读并敬畏。