Generics Scala类型不匹配错误
我有一个导致类型不匹配的场景,我似乎无法解决。下面是代码的简化版本:Generics Scala类型不匹配错误,generics,scala,Generics,Scala,我有一个导致类型不匹配的场景,我似乎无法解决。下面是代码的简化版本: 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
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
}
}
我可以让它在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始终表示相同的含义。第二个变化是在特征通道中引入类型成员类型M2=M。我不完全确定为什么这是必要的,可能是个bug吗?。需要注意的一点是,c.M2是一个有效类型,而c.M是未定义的。我可以在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始终表示相同的含义。第二个变化是在特征通道中引入类型成员类型M2=M。我不完全确定为什么这是必要的,可能是个bug吗?。需要注意的是,c.M2是一个有效类型,而c.M是未定义的。好东西,谢谢!我不明白为什么这两个改变都是必要的。如果Channel.M在外部不可见,那么它有什么好处?我们是否总是必须为类型参数创建一个类型别名,以便在trait/类之外使用?对于ChannelSender的更改,路径依赖类型c.M2是否意味着相同的事情,因为我在同一个通道对象上调用receive和ack?好问题。对于第一个问题,我不知道答案。也许邮件列表上更了解情况的人能帮上忙。对于第二个问题,我同意Scala可以发现在这种情况下通道对象是不变的,但我假设Scala通常会简化假设,即变量不受信任,以保持不变。好东西,谢谢!我不明白为什么这两个改变都是必要的。如果Channel.M在外部不可见,那么它有什么好处?我们是否总是必须为类型参数创建一个类型别名,以便在trait/类之外使用?对于ChannelSender的更改,路径依赖类型c.M2是否意味着相同的事情,因为我在同一个通道对象上调用receive和ack?好问题。对于第一个问题,我不知道答案。也许邮件列表上更了解情况的人能帮上忙。对于第二种情况,我同意Scala可以发现在这种情况下通道对象是不变的,但我假设Scala通常会简化假设,即变量不受信任,从而保持不变。