从Actor向调用者发回None

时间:2011-09-15 09:23:44

标签: scala option actor akka

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

我想要的是(模拟)Actor如果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
}

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

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

1 个答案:

答案 0 :(得分:8)

故障发生在客户端,它错误解释了回复,而不是遵循AKKA协议。来自the Akka documentation

  

!!方法返回一个Option [Any],它将是Some(结果)   如果成功返回,或者如果通话超时则为无。

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

这是 AKKA协议,这意味着客户端应该使用

处理回复
case Some(answer) => process answer
case None => actor did not reply

然后,如果你的演员恰好用选项[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]不匹配(在泛型类型上匹配时不要给出type参数)。它不起作用,它不会验证您有Some[Something],但Something不是A(请参阅类型擦除,编译器会发出警告)。您希望与case Some(x: A)匹配,后者会为您提供Somex的内容,您通常需要的内容。如果您确实需要Some而不是其内容,case s @ Some(x: A)会将s绑定到Some实例,x绑定到其内容。如果您对它不感兴趣,请使用_代替x。

如果已知选项内的类型为A,则不要提及,只需写入 case Some(x)case s: Some(_)