akka 从执行元向调用方发回None

pftdvrlh  于 2022-11-05  发布在  其他
关注(0)|答案(1)|浏览(151)

我有一个简单的Actor,它使用ScalaQuery查询数据库,我已经模拟了一个客户端使用它的测试。
我想要的是(模拟)演员在ID匹配时回复Some(MyObject),否则回复None。但是,我不知道如何实现这一点。下面是我目前得到的代码:

def receive = {
  case FetchSomething(someId) => {
    if (someId == 1234) self.channel ! someObject
    else self.channel ! None
  }
}

然而,它在客户端代码中返回的不是None,而是Some(None)--这当然会让我的客户端感到困惑。

val object = persister !! FetchSomething(1337) match {
    case myObject: Some[MyObject] => myObject
    case _ => None
}

(of当然,上述内容可能是错误的--可能不是Some,而是Option
我如何才能做到这一点?也许更具体地说,我如何才能通过www.example.com发送一个Noneself.channel以便在匹配时,它是None而不是Some(None)

np8igboo

np8igboo1#

错误在客户端,客户端错误地解释了回复,没有遵循AKKA协议。从Akka文档:
!!方法会传回Option[Any],如果传回成功,则为Some(result),如果呼叫逾时,则为None。
所以如果应答是None,客户端得到Some(None).如果应答是Some(12)你得到Some(Some(12)).如果客户端得到None,这不应该意味着actor应答了None,而是意味着actor没有应答。
这是AKKA协议,表示客户端处理应答时应使用

case Some(answer) => process answer
case None => actor did not reply

然后,如果你的参与者碰巧回复了一个Option[Something],这就是你的协议,这是另一层:

case Some(answer) => /* your protocol */ answer match { 
  case Some(actualValue) => reply had actualValue
  case None => None was the reply
}
case None => actor did not reply

当然,你也可以写

case Some(Some(actualValue)) => 
case Some(None) => 
case None =>

旁注,与x: Some[A]不匹配(在泛型类型上匹配时不要给予类型参数)。它不起作用,它不会验证您是否有Some[Something],但不会验证Something是否为A(参见类型擦除,编译器会给出警告)。你想与case Some(x: A)匹配,它会给出xSome的内容,如果您确实需要Some而不是它的内容,case s @ Some(x: A)会将s绑定到Some示例,将x绑定到它的内容。如果您对它不感兴趣,请使用_而不是x。
如果已知选项内的类型为A,则不必提及,只需写入case Some(x)case s: Some(_)即可

相关问题