Совместимость назначения смешанных признаков Scala (иерархия)

У меня есть следующие объявления классов и признаков

class C
class D extends C
trait T extends C
trait U extends D with T

и следующие задания:

val x1:C with T with U = new D with U
val x2:D with T = new C with U
val x3:D with T = new U
val x4:U = new D with T

Первое задание работает, остальные нет. Я хочу понять, почему в обоих случаях.

Насколько я понимаю, линеаризации следующие (-> означает extends):

  • C with T with U: U -> D -> T -> C
  • D with U: U -> T -> D -> C
  • D with T: T -> D -> C
  • C with U: U -> T -> D -> C

Я нарисовал иерархию типов, чтобы лучше понять:

иерархия типов

Мое понимание следующее:

  • x1: работает, потому что линеаризованные типы одинаковы (порядок D и T не важен для типа)
  • x2: не работает потому что...?
  • x3: не работает, потому что трейты не могут быть созданы.
  • x4: не работает, потому что D with T является супертипом U.

Номер 2, где я застрял. Это должно работать IMO, потому что линеаризация D with T - это D -> T -> C, который является супертипом линеаризации C with U (то есть U -> T -> D -> C).

Либо мое предположение о том, что порядок смешанных признаков/классов не важен (но тогда почему компилируется первое задание?), либо моя линеаризация неверна, либо ???

Можете ли вы помочь мне в этом?


person tiefenauer    schedule 10.09.2018    source источник
comment
Тип x2 не имеет значения, произойдет сбой, даже если вы не укажете тип, потому что new C with U недействителен.   -  person Tim    schedule 10.09.2018
comment
Хотя проблема не в этом, ваша линеаризация D with T неверна. Это должно быть T->D->C, потому что трейт является подклассом класса, к которому он применяется (чтобы он мог видеть методы этого класса).   -  person Tim    schedule 11.09.2018
comment
Спасибо что подметил это! Я отредактировал текст соответствующим образом. Я также собираюсь отметить ваш ответ как правильный. Спасибо и за это!   -  person tiefenauer    schedule 11.09.2018


Ответы (1)


Проблема в том, что new C with U недействителен; тип val x2 не имеет значения.

Признак U расширяет D, что означает, что его можно применять только к подклассам D. Поскольку C не является подклассом D, к нему нельзя применить черту.

Черта, которая расширяет класс, похожа на тип self, но с некоторыми тонкими отличиями. Дополнительную информацию см. в этом ответе.

person Tim    schedule 10.09.2018