Совместимость назначения смешанных признаков 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
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
1
3
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

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

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

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

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