【问题标题】:What is special about case classes in Akka?Akka 中的案例类有什么特别之处?
【发布时间】:2017-05-16 07:05:52
【问题描述】:

我已经读到案例类可以与模式匹配一​​起使用。但是,我也可以使用带有模式匹配的常规类。 This question 给出了一个常规的 scala 视角。对于这个特定的代码,我想要从 scala 和 akka 的角度来看它。 例如:

演员类:

class TestActor extends Actor {

  def receive={
    case One(num)=>println("One "+num)
    case t:Two=>println("Two "+t.num)
    case _=>println("Another")
  }
}

object TestActor{
  case class One(num:Int)
}

二班:

class Two(var num:Int){  }

主要:

object Main2 extends App{

  val system=ActorSystem("t")
  val testActor=system.actorOf(Props[TestActor],"test")

  val t=new Two(200)
  val o=TestActor.One(100)

  testActor!o
  testActor!t

}

输出是:

One 100
Two 200

我知道我在这里遗漏了一些东西,可能是我对模式匹配的理解。有人可以帮帮我吗?

【问题讨论】:

  • 请注意,您不能编写 case Two(t),因为案例类带有一个默认的 unapply 方法,可以启用它,而常规类则没有(尽管您可以编写一个)。
  • 如果我的代码适用于案例 t:Two,我为什么需要案例类?
  • 当然,行为将是相同的 - 在这种情况下,它主要是一个可读性问题 - Two(num) 允许您根据需要命名内部变量 - 使您的 intent i> 在这个特定的上下文中更清晰,例如case Two(receivedNum) 什么的。正如您引用的答案所述,案例类还有其他好处(例如默认equalshashCode),但在此特定代码中都不会使用它们。尽管如此 - 将案例类用于“数据容器”类是一种很好的做法 - 如果以及何时以不同方式使用它们,这些可能会派上用场。

标签: scala akka case-class


【解决方案1】:

正如您所注意到的,Akka 中案例类的主要区别在于能够在匹配时使用它们的提取器(取消应用方法)(除了您获得我们的案例类的常用功能,例如 @987654321 的实现@、equals,并将它们作为产品类型使用)。

通过一个更大的示例,您可以看到效果如何。例如,假设您正在使用 Akka-HTTP 客户端向第三方服务发出 HTTP 请求,并且如果您收到 StatusCode.OK 或任何其他状态代码,您希望以不同的方式操作。因为HttpResponse提供了unapply方法,你可以这样做:

case HttpResponse(StatusCodes.OK, _, entity, _)) => // We're good, parse the data.
case HttpResponse(statusCode, _, _, _)) => // Operate on status code != OK

代替:

case response: HttpResponse =>
  if (response.statusCode != StatusCodes.OK) {
    // Stuff
  }
  else {
    // Other stuff
  }

当您的逻辑变得更加复杂时,仅提取您想要的值会非常有用且不那么冗长。在我们的代码库中,我们有更复杂的多个值,例如:

case (Foo(bar, baz), resp@HttpResponse(statusCode, _, _, _))

当然,您始终可以自己在伴随对象中创建unapply 方法并自己获得与案例类相同的语义,但您通常不想编写该样板文件,而是让编译器来做给你。

总而言之,在 Akka 中使用 case class 作为数据容器可以简化模式匹配的工作,这通常是您在实现 receive 方法时所做的。

【讨论】:

    猜你喜欢
    • 2015-01-09
    • 2019-04-06
    • 2016-11-26
    • 2011-07-13
    • 2011-04-18
    • 2017-02-19
    • 2016-09-30
    • 1970-01-01
    相关资源
    最近更新 更多