Ответ 1

Ранние инициализаторы являются частью конструктора подкласса, который предназначен для запуска перед его суперклассом. Например:

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 в обычном порядке инициализации (суперкласс перед классом).

Ответ 3

Насколько я могу судить, мотивация (как указано в ссылке выше):

"Естественно, когда val переопределяется, он не инициализируется более одного раза. Поэтому, хотя x2 в приведенном выше примере, по-видимому, определен в каждой точке, это не так: переопределенный val будет казаться нулевым во время построения суперклассов, как и абстрактное значение.

Я не понимаю, почему это естественно. Вполне возможно, что r.h.s. задания может иметь побочный эффект. Обратите внимание, что такая структура кода полностью невозможна ни на С++, ни на Java (и я буду предполагать Smalltalk, хотя я не могу говорить на этом языке). На самом деле вам нужно сделать такие двойные назначения неявными... ticilpmi... Явно в этих языках через конструкторы. В свете r.h.s. неопределенность в отношении побочных эффектов, на самом деле это не похоже на большую мотивацию: способность преодолевать побочные эффекты суперкласса (тем самым аннулируя инварианты суперкласса) через ASSIGNMENT? Ик!

Существуют ли другие мотивы "убийцы" для разрешения такой небезопасной структуры кода? Объектно-ориентированные языки проработали без такого механизма в течение примерно 40 лет (30 с лишним лет, если вы считаете, что это связано с созданием языка), зачем включать его сейчас?

Это... просто... кажется... опасно.

Ответ 4

Во второй мысли, годовой уровень...

Это просто торт. В буквальном смысле.

Не рано. Просто торт (миксины).

Торт - это термин/образец, созданный самим The Grand Pooh-bah, который использует систему признаков Scala, которая находится на полпути между классом и интерфейсом. Это намного лучше, чем шаблон оформления Java.

Так называемый "интерфейс" - это просто неназванный базовый класс, и то, что раньше было базовым классом, действует как признак (которого я, откровенно говоря, не знал, можно было бы сделать). Мне непонятно, может ли класс "with'd" принимать аргументы (черты не могут), попробует и отчитается.

Этот вопрос и его ответ вошли в один из Scala самых классных функций. Прочитайте это и будьте в страхе.