在 Scala 中,什么是“早期初始化器”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4712468/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:44:01  来源:igfitidea点击:

In Scala, what is an "early initializer"?

scala

提问by oxbow_lakes

In Martin Odersky's recent post about levels of programmer abilityin Scala, in the Expert library designersection, he includes the term "early initializers".

在 Martin Odersky最近关于Scala程序员能力水平的帖子中,在专家库设计器部分,他包含了术语“早期初始化程序”

These are not mentioned in Programming in Scala. What are they?

这些在Programming in Scala中没有提到。这些是什么?

回答by Daniel C. Sobral

Early initializers are part of the constructor of a subclass that is intended to run before its superclass. For example:

早期初始化器是子类的构造函数的一部分,旨在在其超类之前运行。例如:

abstract class X {
    val name: String
    val size = name.size
}

class Y extends {
    val name = "class Y"
} with X

If the code was written instead as

如果代码写成

class Z extends X {
    val name = "class Z"
}

then a null pointer exception would occur when Zgot initialized, because sizeis initialized before namein the normal ordering of initialization (superclass before class).

然后在Z初始化时会发生空指针异常,因为size在初始化name的正常顺序中被初始化(超类在类之前)。

回答by Mark Gerolimatos

As far as I can tell, the motivation (as given in the link above) is:

据我所知,动机(如上面的链接所示)是:

"Naturally when a val is overridden, it is not initialized more than once. So though x2 in the above example is seemingly defined at every point, this is not the case: an overridden val will appear to be null during the construction of superclasses, as will an abstract val."

“当然,当一个 val 被覆盖时,它不会被初始化多次。所以虽然上面例子中的 x2 似乎在每个点都定义了,但事实并非如此:在超类的构造过程中,一个被覆盖的 val 将显示为空,抽象的 val 也是如此。”

I don't see why this is natural at all. It is completely possible that the r.h.s. of an assignment might have a side effect. Note that such code structure is completely impossible in either C++ or Java (and I will guess Smalltalk, although I can't speak for that language). In fact you have to make such dual assignments implicit...ticilpmi...EXplicit in those languages via constructors. In the light of the r.h.s. side effect uncertainty, it really doesn't seem like much of a motivation at all: the ability to sidestep superclass side effects (thereby voiding superclass invariants) via ASSIGNMENT? Ick!

我不明白为什么这是自然的。作业的 rhs 完全有可能产生副作用。请注意,这种代码结构在 C++ 或 Java 中是完全不可能的(我猜是 Smalltalk,虽然我不会说那种语言)。事实上,您必须通过构造函数在这些语言中隐式地进行这种双重赋值...ticilpmi...EXplicit。鉴于 rhs 副作用的不确定性,它似乎根本不是一个动机:通过 ASSIGNMENT 回避超类副作用(从而使超类不变量无效)的能力?哎呀!

Are there other "killer" motivations for allowing such unsafe code structure? Object-oriented languages have done without such a mechanism for about 40 years (30-odd years, if you count from the creation of the language), why include it now?

允许这种不安全的代码结构是否有其他“杀手”动机?面向对象语言已经有大约 40 年没有这种机制了(30 多年,如果从语言的创建算起),为什么现在包括它?

It...just...seems...dangerous.

它……只是……看起来……很危险。

回答by Mark Gerolimatos

On second thought, a year layer...

再想一想,一年的层次......

This is just cake. Literally.

这只是蛋糕。字面上地。

Not an early ANYTHING. Just cake (mixins).

不是早期的任何东西。只是蛋糕(mixins)。

Cake is a term/pattern coined by The Grand Pooh-bah himself, one that employs Scala's trait system, which is halfway between a class and an interface. It is far better than Java's decoration pattern.

Cake 是 The Grand Pooh-bah 自己创造的一个术语/模式,它采用了 Scala 的 trait 系统,介于类和接口之间。它远远优于Java的装饰模式。

The so-called "interface" is merely an unnamed base class, and what used to be the base class is acting as a trait (which I frankly did not know could be done). It is unclear to me if a "with'd" class can take arguments (traits can't), will try it and report back.

所谓的“接口”只是一个未命名的基类,原来基类的作用是作为一个trait(坦白说我不知道​​可以做到)。我不清楚“with'd”类是否可以接受参数(特征不能),是否会尝试并报告。

This question and its answer has stepped into one of Scala's coolest features. Read up on it and be in awe.

这个问题及其答案已经进入 Scala 最酷的特性之一。阅读它并敬畏。