如何在匹配类型列表中使用模式匹配结果?

时间:2015-11-07 02:31:41

标签: scala pattern-matching akka

我在Akka发现了一些奇怪的行为。当我匹配模式时,我无法在列表中添加消息:

  var msgs: List[Message] = Message() :: Nil

  ...

  override def receive: Receive = {
    case msg @ Message  => { 
      msgs = msgs.::(Message())   // ok
      //msgs = msgs.::(msg)       // doesn't work
      sender ! "Thanks!" 
    }
    case Request => { sender ! msgs.head }
    case _       =>
  }

这是ScalaAkka中的错误吗?

要修复它,我需要输入类型

msgs = msgs.::(msg.asInstanceOf[Message])

这不是一个方便的解决方案。

1 个答案:

答案 0 :(得分:4)

问题在于你在case语句中发生匹配时遇到了一个微妙的错误。您在那里与Message伴随对象进行匹配,而不是Message案例类。

另一种看待它的方法是case x @ Y语法可以被认为是&#34;匹配任何类型为Y的实例,然后运行等效的val x: Y = <incoming value>.asInstanceOf[Y] }&#34;,但是这里你提供的推断类型是一个名为Message的无参数类型,编译器可以是object Message,而不是case class Message()

因此,要修复该行,请在参数列表中写入。例如,如果Message类定义为:

case class Message()

这将是:

case msg @ Message() => ...

如果我们有,请说:

case class Message(text: String, id: Int)

然后case语句就像:

case msg @ Message(txt, is) => ... 

或者,如果我们不关心(或需要使用)textid参数:

case msg @ Message(_, _) => ... 

为了在技术上更准确地描述这里发生的事情,case语句实际上是尝试与任何&#34; unapply&#34;匹配。伴随对象中可用的方法(也称为&#34;提取器&#34;)。默认情况下,对于任何与case类构造函数中提供的参数列表完全匹配的案例类,将在随附对象中免费提供applyunapply方法。在上面Message类的第二个版本中,相关的unapply方法将具有以下签名:

def unapply(text: String, id: Int): Option[Message]

您可以阅读有关提取器herehere的更多信息。