gpt4 book ai didi

scala - Akka Actor - 按通用类型接收模式匹配

转载 作者:行者123 更新时间:2023-12-01 12:13:31 25 4
gpt4 key购买 nike

我有一个通用的 actor 类,我想在接收方法中与通用类型进行模式匹配。

例如:

class Test[S] extends Actor {
override def receive: Receive = {
case _: S => println("yes")
case _ => println("no")
}
}

val ac = system.actorOf(Props(new Test[Int]))
ac ! "abc" // expect print "no"
ac ! 3 // expect print "yes"

然而,它似乎永远不会进入第二种情况,并且总是打印输出"is"......

如何让它打印“no”?

最佳答案

问题

您刚刚偶然发现了一个叫做类型删除 的东西。这意味着,泛型类型信息在编译期间被删除(JVM 不了解泛型)。所以在运行时,你的 Actor 将看起来像这样:

class Test extends Actor {
override def receive: Receive = {
case _: Object => println("yes")
case _ => println("no")
}
}

这就是为什么 ac ! "abc" 以及 ac ! 3 将始终与第一种情况匹配。

幸运的是,Scala 提供了有助于克服这个问题的机制。您可以阅读更多关于它们的信息 in this articlein the docs .

解决方案

tldr;您可以找到一个工作示例 here, on Scastie .

您应该使用其中一种机制:ClassTag。您可以将其视为一个对象,它在运行时保存编译时可用的所有信息。

import scala.reflect.ClassTag

object Main extends App {

class Test[S](implicit ct: ClassTag[S]) extends Actor {
override def receive: Receive = {
case _: S => println("yes")
case _ => println("no")
}
}

val system = ActorSystem()

val ac = system.actorOf(Props(new Test[Int]))
ac ! "abc" // expect print "no"
ac ! 3 // expect print "yes"

system.terminate()

}

您可能想知道我们在哪里可以找到 ClassTag[T] 的隐式实例。幸运的是,编译器会按需提供。

奖励:您可以重写 class Test[S](implicit ct: ClassTag[S]) extends Actor 以使用所谓的 Context Bounds : class Test[S: ClassTag] extends Actor.

您可以按如下方式阅读此签名:

A class Test is parametrized by type S, for which there is available ClassTag[S] in an implicit scope.

关于scala - Akka Actor - 按通用类型接收模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49925594/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com