#scala #generics #types
#scala #общие #типы
Вопрос:
Я пытаюсь создать систему обмена сообщениями, безопасную для типов. На данный момент лучшее, что я придумал, это:
trait Component
trait Message[From <: Component, -To <: Handler[From]]
trait Handler[From <: Component]{
type MessageType <: Message[From, this.type]
def handle(message: MessageType): Unit;
}
Я бы хотел чего-то большего, чем это:
trait Component
trait Message[From <: Component, -To <: Handler[From]]
trait Handler[From <: Component, MessageType <: Message[From, this.type]]{
def handle(message: MessageType): Unit;
}
но компилятор жалуется на использование this.type
в параметрах типа. Есть ли какой-нибудь способ для меня сослаться на тип, который я определяю в параметрах типа, чтобы я мог использовать синтаксис, который мне нравится?
Очевидно, что система типов может делать то, что я хочу, я бы просто хотел, чтобы она использовала синтаксис, который мне нравится.
—РЕДАКТИРОВАТЬ—
Я думаю, что нашел решение.
trait Component
trait Message[From <: Component,
To <: Handler[From, To, MessageType],
MessageType <: Message[From, To, MessageType]]
trait Handler[From <: Component,
To <: Handler[From, To, MessageType],
MessageType <: Message[From, To, MessageType]]{
def handle(message: MessageType ): Unit;
}
Немного более подробный в параметрах типа, но он работает хорошо.
Ответ №1:
Я не думаю, что вам нужны MessageType
параметры типа для достижения того, чего вы хотите. Вместо этого сделайте MessageType
равным Message[From, this.type]
.
trait Handler[From <: Component] {
type MessageType = Message[From, this.type]
def handle(message: MessageType): Unit;
}
Подумайте о том, чтобы сделать сообщение ковариантным в его первом параметре.
Обратите this.type
внимание, что это не относится к определяемому вами типу. this.type
это тип, который имеет только одно значение: this
. this
не существует вне тела признака и, следовательно, не может использоваться в параметрах типа. Если вам действительно нужно ссылаться на тип, в который будет смешан признак, вам нужен F-ограниченный полиморфизм.
Комментарии:
1. Итак, проблема с этим решением заключается в том, что вы не можете использовать подтип Message[From, this.type] в качестве параметра для обработки, что делает его гораздо менее полезным для сопоставления с образцом.
2. @Meshelton я не понимаю, что вы имеете в виду. Вы определенно можете передать подтип
handle
, методы всегда контравариантны по своим параметрам.3. вы можете передать подтип, но вы не можете объявить метод таким
def handle(message: SubtypeOfMessageType): Unit
образом, вы получаете ошибку компилятора, которая имеет смысл.