Akka 中 case 类 有什么特别之处?
What is special about case classes in Akka?
我读过 classes 可以与模式匹配一起使用。但是,我也可以使用带有模式匹配的常规 class。
This question 给出了常规的 Scala 视角。我希望从 scala 和 akka 的角度来看这个特定的代码。
例如:
演员class:
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二:
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
我知道我在这里遗漏了一些东西,可能是我对模式匹配的理解。有人可以帮我吗?
正如您所注意到的,与 Akka 中的 case classes 的主要区别是在匹配时能够使用它们的提取器(不应用方法)(除了您从我们的 case [= 中获得的通常功能之外) 33=]es,例如 hashCode
、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
方法,并自己获得与案例相同的语义 class,但您通常不想这样写样板文件,允许编译器为您完成。
总而言之,在 Akka 中使用 case class
作为数据容器简化了模式匹配的工作,这通常是您在实现 receive
方法时所做的。
我读过 classes 可以与模式匹配一起使用。但是,我也可以使用带有模式匹配的常规 class。 This question 给出了常规的 Scala 视角。我希望从 scala 和 akka 的角度来看这个特定的代码。 例如:
演员class:
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二:
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
我知道我在这里遗漏了一些东西,可能是我对模式匹配的理解。有人可以帮我吗?
正如您所注意到的,与 Akka 中的 case classes 的主要区别是在匹配时能够使用它们的提取器(不应用方法)(除了您从我们的 case [= 中获得的通常功能之外) 33=]es,例如 hashCode
、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
方法,并自己获得与案例相同的语义 class,但您通常不想这样写样板文件,允许编译器为您完成。
总而言之,在 Akka 中使用 case class
作为数据容器简化了模式匹配的工作,这通常是您在实现 receive
方法时所做的。