我在 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 _ =>
}
这是 Scala
或 Akka
中的错误吗?
要修复它,我需要区分类型
msgs = msgs.::(msg.asInstanceOf[Message])
这不是一个方便的解决方案。
最佳答案
问题是您在 case 语句中发生的匹配中犯了一个微妙的错误。您正在与 Message
进行匹配伴随对象,而不是 Message
案例类。
另一种看待它的方式是 case x @ Y
语法可以被认为是“与 Y
类型的任何实例匹配,然后运行 val x: Y = <incoming value>.asInstanceOf[Y]
的等效项”,但这里您提供的推断类型是名为 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) => ...
或者,如果我们不关心(或需要使用)text
和id
参数:
case msg @ Message(_, _) => ...
为了对此处发生的情况进行技术上稍微正确的描述,case 语句实际上尝试与伴生对象中可用的任何“unapply”方法(也称为“提取器”)进行匹配。默认情况下,会有 apply
和一个unapply
方法在任何案例类的伴随对象中免费提供,该方法与案例类构造函数中提供的参数列表完全匹配。在第二个版本Message
上面的类,相关unapply
方法将具有如下签名:
def unapply(text: String, id: Int): Option[Message]
关于scala - 如何使用匹配类型列表中的模式匹配结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33578527/