我有一个导致类型不匹配的情况,我似乎无法解决。这是代码的简化版本:
abstract class Msg
trait Channel[M <: Msg] {
def receive(): M
def ack(envelope: M)
}
object ChannelSender {
private var channel : Channel[_ <: Msg] = _
def assignChannel(channel : Channel[_ <: Msg]) = this.channel = channel
def test() {
val msg = channel.receive()
channel.ack(msg) // Type mismatch here
}
}
编译器的错误是:
类型不匹配;发现:msg.type(带底层类型 com.msgtest.Envelope)必需:_ $ 1其中type _ $ 1&lt;: com.msgtest.Envelope
我可以通过哪些更改来实现这项工作?此外,更改需要以下具体实现编译:
class SomeMsg extends Msg
object SomeChannel extends Channel[SomeMsg] {
def receive(): SomeMsg = { null.asInstanceOf[SomeMsg] }
def ack(envelope: SomeMsg) {}
}
object Setup {
ChannelSender.assignChannel(SomeChannel)
}
答案 0 :(得分:4)
我可以通过两次更改在Scala 2.9下编译它,
trait Channel[M <: Msg] {
type M2 = M // Introduce a type member that's externally visible
def receive(): M2
def ack(envelope: M2)
}
object ChannelSender {
private var channel : Channel[_ <: Msg] = _
def assignChannel(channel : Channel[_ <: Msg]) = this.channel = channel
def test() {
val c = channel // An immutable value, so that c.M2 is stable
val msg = c.receive()
c.ack(msg) // OK now
}
}
第一个更改是使用不可变值val c = channel
,因此路径相关类型c.M2
总是意味着相同的事情。第二个变化是在特征type M2 = M
中引入类型成员Channel
。我不完全确定为什么这是必要的(这可能是一个错误?)。需要注意的一点是,c.M2
是有效类型,而c.M
未定义。