Совместимость назначения смешанных признаков 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

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

type hierarchy

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

  • 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).

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

Вы можете мне помочь?

Тип x2 не имеет значения, он выйдет из строя, даже если вы не укажете тип, потому что new C with U недействителен.

Tim 10.09.2018 13:07

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

Tim 11.09.2018 08:28

Спасибо что подметил это! Я отредактировал текст соответствующим образом. Я также отмечу ваш ответ как правильный. И за это спасибо!

tiefenauer 11.09.2018 14:09
1
3
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

Признак, расширяющий класс, похож на собственный тип, но с некоторыми небольшими отличиями. См. Этот ответ для получения дополнительной информации.

Другие вопросы по теме