这是一个akka演员的接收中的模式匹配问题。
我有这段代码:
class ActorReservation(reservation: Reservation) extends Actor {
import Entry._
import Customer._
def receive: Actor.Receive = messages
def messages: Receive = {
case Entry.Get.Result(obj) => // process entry
case Customer.Get.Result(obj) => // process customer
}
def test: Receive = {
case e =>
println(s"ClassName -> ${e.getClass.getName}")
println(s"isInstanceOf[GenericMessages#Get] -> ${isInstanceOf[GenericMessages[AppAny]#Get]}")
}
}
object Entry extends GenericMessages[EntryEntity]
object Customer extends GenericMessages[CustomerEntity]
trait GenericMessages[A <: AppAny] {
case class Get(id: Int)
object Get { case class Result(obj: Option[A]) }
} //trait
trait AppAny
case class EntryEntity(id: Int) extends AppAny
case class CustomerEntity(id: Int) extends AppAny
我的演员可以收到两条消息:Entry.Get.Result
,Customer.Get.Result
,当它收到第一个消息时,一切都会找到,但是当第二个消息到达时,它会抛出Customer
可以强制转换的异常Entry
,这是因为第二封邮件已被第一封case
抓住。
然后我用
更改接收 def receive: Actor.Receive = test
这两条消息都显示相同的类名GenericMessages$Get$Result
,这就是为什么这两个消息都属于第一个case
。
我尝试为case
的两封邮件创建通用GenericMessages#Get
,但这会引用Get
内的GenericMessages
类,而不是对象Get
所以,我的问题是:有没有办法在Result
特征的Get
对象中引用GenericMessages
类?还有另一种方法可以让case
避免这种模式匹配问题吗?
其他信息: 真正的actor是泛型actor的实现,因为我需要在其他actor中使用相同的行为。
消息Entry.Get.Result
,Customer.Get.Result
是同一个参与者(anotherActor ! Customer.Get
)发送的先前消息的响应,并以这种方式实现,因为我更喜欢并行调用而不是线性调用。线性解决方案是使用一种方法来接收第一条消息,而不是使用become
来更改为另一条接收并处理第二条消息。我想避免这种线性方法,因为1.我更喜欢它是一个并行过程而且2.它打破了我所做的抽象。
答案 0 :(得分:0)
有一个解决方案(非常难看):让入门和客户进入班级:
case class Entry() extends GenericMessages[EntryEntity]
case class Customer() extends GenericMessages[CustomerEntity]
然后创建一个条目和客户实例:
val entry = Entry()
val customer = Customer()
并将它们作为参数传递给您的ActorReservation actor(以及需要它的anybidy)。然后像这样创建和匹配:
entry.Get.Result
customer.Get.Result
但这是糟糕的设计。
我建议在与演员合作时避免使用泛型。当您需要在运行时匹配类型时,类型擦除会成为问题。 如果我是你,我会重做设计。
答案 1 :(得分:0)
我找到了解决方案。
除了 var applicationView = ApplicationView.GetForCurrentView();
var titleBar = applicationView.TitleBar;
CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
titleBar.ButtonBackgroundColor = Colors.Transparent;
titleBar.ButtonForegroundColor = Colors.White;
和object
Entry
Customer
并使用此
更改接收功能private object Messages extends GenericMessages[AppAny]
现在它可以根据需要运行。
完整代码:
def messages: Receive = {
case Messages.Get.Result(obj) =>
obj match {
case Some(e: Entry) => // process entry
case Some(c: Customer) => // process customer
}
}