从Actor向调用者发回None

fwi*_*tra 2 scala option actor akka

我有一个简单的Actor使用ScalaQuery查询数据库,我已经嘲笑过对使用它的客户端的测试.

我想要的是(模拟)Actor Some(MyObject)如果ID匹配则回复,None否则.但是,我无法弄清楚如何使这项工作.这是我到目前为止的代码:

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

但是,它不会返回None客户端代码,而是返回Some(None)- 这当然会让我的客户端感到困惑.我希望客户端如何工作是这样的:

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

(当然,以上可能只是错误 - 而不是Some,它可能是Option)

我怎样才能做到这一点?也许更具体一点,我如何None通过self.channel 发送回来,所以当匹配它时,它是None不是Some(None)

Did*_*ont 8

故障发生在客户端,它错误地解释了回复,而不是遵循AKKA协议.从Akka文档:

!! 方法返回一个Option [Any],如果成功返回则为Some(result),如果调用超时则为None.

因此,如果回复为None,则客户端为Some(None).如果回复是某些(12)你得到一些(一些(12)).如果客户端收到None,则不应该表示actor回答None,这意味着actor没有回复.

这是AKKA协议,它意味着客户端应该处理回复

case Some(answer) => process answer
case None => actor did not reply
Run Code Online (Sandbox Code Playgroud)

然后,如果你的演员碰巧用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
Run Code Online (Sandbox Code Playgroud)

当然,你也可以写

case Some(Some(actualValue)) => 
case Some(None) => 
case None => 
Run Code Online (Sandbox Code Playgroud)

旁注,不匹配x: Some[A](在泛型类型上匹配时不要给出类型参数).它不工作,也不会验证您有一个Some[Something],但不是说SomethingA(见类型擦除,编译器会发出警告).你想与之匹配case Some(x: A),为你提供你通常想要的Somein 的内容x.如果你真的想要Some而不是它的内容,case s @ Some(x: A)将绑定sSome实例,x它的内容._如果您对它不感兴趣,请使用而不是x.

如果知道选项中的类型是A,那么不要提它,只是写 case Some(x),case s: Some(_)