【问题标题】:Scala type mismatch errorScala类型不匹配错误
【发布时间】:2012-02-16 14:12:09
【问题描述】:

我有一种情况导致我似乎无法解决的类型不匹配。这是代码的简化版本:

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 其中类型 _$1 <: 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)
}

【问题讨论】:

    标签: generics scala


    【解决方案1】:

    我可以让它在 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 总是意味着同样的事情。第二个变化是在 trait Channel 中引入类型成员 type M2 = M。我不完全确定为什么这是必要的(这可能是一个错误吗?)。需要注意的一点是c.M2 是有效类型,而c.M 是未定义的。

    【讨论】:

    • 好东西,谢谢!我不明白为什么这些更改都是必要的。如果 Channel.M 在外部不可见,那有什么好处呢?我们是否总是必须为类型参数创建一个类型别名才能在 trait/class 之外使用?对于 ChannelSender 的更改,由于我在同一个 channel 对象上调用 receive()ack,因此依赖路径的类型 c.M2 是否意味着相同的事情?
    • 好问题。对于第一个,我不知道答案。也许邮件列表中知识渊博的人可以提供帮助。对于第二个问题,我同意 Scala 可以确定 channel 对象在这种情况下没有变化,但我假设通常 Scala 会简化假设 vars 不可信以保持不变。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多