Подтвердить что ты не робот

Инициализация анонимного класса с признаком

Может кто-нибудь помочь мне понять следующее поведение?

Проще говоря: в чем разница между следующими двумя случаями, когда...

Я определяю простой класс c + trait t

scala> class c {val x=true; val y=this.x} 
defined class c

scala> trait t {}
defined trait t

Я могу создать новый "c с t"

scala> new c with t
res32: c with t = [email protected]

Но я не могу создать экземпляр нового "[анонимного класса, подобного c], с t"

scala> new {val x=true; val y=this.x} with t
<console>:9: error: type mismatch;
 found   : type
 required: ?{def x: ?}
<console>:9: error: value x is not a member of object $iw
              new {val x=true; val y=this.x} with t

Какая разница между этими двумя случаями?

Спасибо!

4b9b3361

Ответ 1

Вы наткнулись на синтаксис "раннего определения" (подробнее).

Ознакомьтесь с разделом 5.1.6 спецификации языка:

Раннее определение проверяется и проверяется по типу, которое действует непосредственно перед определением шаблона, дополненным любым параметры типа охватывающего класса и любые ранние определения предшествующий той, которая определена. В частности, любая ссылка на thisв правой части раннего определения относится к личности из this за пределами шаблона. Следовательно, невозможно, чтобы раннее определение относится к объекту, создаваемому шаблон или относится к одному из его полей и методов, за исключением любого другое предыдущее раннее определение в том же разделе.

В вашем случае проблема связана с this.x. Если вы замените его только на x, значит, вы ссылаетесь на "предыдущее раннее определение", как упоминалось в последнем предложении выше (спасибо, @som-snytt!), Он компилируется.

Конечно, вы, вероятно, не собирались писать ранний инициализатор, поэтому просто напишите его в ответ на вопрос Кристиана Домагалы.

Ответ 2

Это то, что вам нужно:

new t {val x=true; val y=this.x}

Если у вас есть другой признак, u {}, вы можете написать new t with u {val x=true; val y=this.x}