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