Scala类型不匹配错误

时间:2012-01-23 06:45:35

标签: 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]) = 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)
}

1 个答案:

答案 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未定义。