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

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

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

最佳答案

问题是您在 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) => ... 

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

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

为了对此处发生的情况进行技术上稍微正确的描述,case 语句实际上尝试与伴生对象中可用的任何“unapply”方法(也称为“提取器”)进行匹配。默认情况下,会有 apply和一个unapply方法在任何案例类的伴随对象中免费提供,该方法与案例类构造函数中提供的参数列表完全匹配。在第二个版本Message上面的类,相关unapply方法将具有如下签名:

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

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

关于scala - 如何使用匹配类型列表中的模式匹配结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33578527/

相关文章:

erlang - 模式匹配的基本问题

scala - 具有类型成员的 Case 对象的模式匹配

scala - 在Akka中是否必须拥有大师级 Actor ?

java - Http Websocket 作为 Akka 流源

c# - 如何在 Akka.NET 中远程部署具有动态名称的 actor

scala - 案例类继承另一个类/特征

scala - 如何删除密封特征实现中的重复 case 语句

java - 为什么 Java 的 DateTimeFormatter 不能安全地解析/格式化 Instant 上的往返?

scala - 返回一个 Future 的更好方法是异步的

regex - 如果正则表达式有嵌套组,如何使用正则表达式来匹配字符串?