В Scala, что такое "ранний инициализатор"?
В Martin Odersky недавняя публикация об уровнях возможностей программиста в Scala, в разделе дизайнера библиотеки экспертов он включает термин "ранние инициализаторы" .
Они не упоминаются в Программирование в Scala. Что они?
Ответы
Ответ 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
в обычном порядке инициализации (суперкласс перед классом).
Ответ 2
Для синтаксиса и мотивации смотрите здесь: https://github.com/paulp/scala-faq/wiki/Initialization-Order (там они называются "ранние определения", но это то же самое)
Ответ 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 самых классных функций. Прочитайте это и будьте в страхе.