2014-06-19 122 views
1

我试图想出一个类型安全的消息传递系统。现在,我已经拿出最好的是这样的:参考类型参数中定义的类型

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。有没有办法让我参考我在类型参数中定义的类型,以便我可以使用我想要的语法?

类型系统显然可以做我想做的事我只是喜欢它使用我喜欢的语法。

- EDIT--

我想我找到了解决方案。

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; 
} 

在类型参数中稍微冗长一些,但效果很好。

回答

0

我不认为你需要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是只有一个值的类型:thisthis不存在特征体外,因此不能用在类型参数中。如果您确实需要参考特征将混入的类型,则需要F-bounded polymorphism

+0

所以这个解决方案的问题是,你不能使用Message [From,this.type]的子类型作为参数来处理使其对模式匹配更加有用。 – Meshelton

+0

@Meshelton我不明白你的意思。你绝对可以将一个子类型传递给'handle',方法总是在它们的参数中是不相容的。 – wingedsubmariner

+0

你可以传递一个子类型,但是你不能像这样'def handle(message:SubtypeOfMessageType):Unit'声明方法,你会得到一个合理的编译器错误。 – Meshelton