Ответ 1
В конце раздела 5.1 Scala спецификация определено следующее:
Оценка шаблона. Рассмотрим шаблон sc с mt 1 с mt n {stats}. Если это шаблон признак (п. 5.3.3), то его mixin-оценка состоит из eval- последовательности операторов Статистика. Если это не шаблон, то его оценка состоит из выполните следующие действия.
- Сначала вычисляется конструктор суперкласса sc (§5.1.1).
- Затем все базовые классы в линеаризации шаблонов (п. 5.1.2) вверх к указанному суперклассу шаблонов по sc оцениваются по mixin. Оценка миксинов в обратном порядке порядок возникновения в линеаризация.
- Наконец, оценивается статистика последовательности операторов.
Обратите внимание, однако, что параметры конструктора могут использоваться любыми последующими конструкторами. Поэтому перед этим необходимо выполнить инициализацию. Это делается явным в конце раздела 5.1.1:
Оценка конструктора invocation x.c.,. (argsn) состоит из следующих шаги:
- Сначала оценивается префикс x.
- Затем аргументы args1,.,, argsn оцениваются слева направо право.
- Наконец, построенный класс инициализируется путем оценки шаблон класса, на который ссылается с.
У вас нет проблем, но у вас проблема с {stats} исполняется последним. Причина, по которой {stats} выполняется последним, заключается в том, что она может ссылаться на атрибуты ее классов и свойств предков, тогда как предки, очевидно, не знают о своих потомках. Таким образом, предки должны быть полностью инициализированы до выполнения {stats}.
Конечно, возможно, вам нужна ранняя инициализация. Об этом говорится в разделе 5.1.6: "Ранние определения". Вот как вы его напишете:
class MyClass extends { val myVal = "Value" } with MyTrait