从 Actor 向调用者发送 None
我有一个简单的 Actor,它使用 ScalaQuery 查询数据库,我已经模拟了它来测试使用它的客户端。
我想要的是,如果 ID 匹配,(模拟)Actor 会回复 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)
?
I have a simple Actor that queries a database using ScalaQuery, which I've mocked for a test of a client using it.
What I want is for the (mock) Actor to reply with Some(MyObject)
if the ID matches up, and None
otherwise. However, I can't figure out how to make this work. Here's the code I have so far:
def receive = {
case FetchSomething(someId) => {
if (someId == 1234) self.channel ! someObject
else self.channel ! None
}
}
However, instead of returning None
in the client code, it returns Some(None)
- which, of course, confuses my client. How I want the client to work is something like this:
val object = persister !! FetchSomething(1337) match {
case myObject: Some[MyObject] => myObject
case _ => None
}
(of course, the above may just be wrong - instead of Some
, it could be Option
)
How can I achieve this? Perhaps more specific, how can I send a None
back through self.channel so when matching it, it's None
and not Some(None)
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
错误在于客户端,它误解了回复,不遵循 AKKA 协议。来自 Akka 文档:
因此,如果回复为 None,则客户端为 Some(None)。如果回复是 Some(12),您会得到 Some(Some(12))。如果客户端收到 None,则不应该意味着参与者回复 None,而是意味着参与者没有回复。
这是AKKA协议,这意味着客户端应该使用
Then处理回复,如果你的actor碰巧回复了一个Option[Something],那就是你的协议,这是另一层:
当然,你也可以写
一个旁注,不要与
x: Some[A]
匹配(匹配泛型类型时不要给出类型参数)。它不起作用,它不会验证您是否有Some[Something]
,但不会验证Something
是A
(请参阅类型擦除,编译器会给出警告)。您想要与case Some(x: A)
匹配,它会为您提供x
中Some
的内容,这是您通常想要的。如果您实际上想要Some
而不是其内容,case s @ Some(x: A)
会将s
绑定到Some
实例,x
为其内容。如果您对此不感兴趣,请使用_
代替 x。如果知道选项里面的类型是
A
,那就不用提了,直接写case Some(x)
,case s: Some(_)
The fault is in the client, which misinterpret the reply, not following AKKA protocol. From the Akka documentation :
So if reply is None, client Some(None). If reply is Some(12) you get Some(Some(12)). If client receives None, it should not means the actor replied None, it means the actor did not reply.
This is AKKA protocol, and it means client should process reply with
Then if your actor happens to reply with an Option[Something], that is your protocol, which is another layer:
Which of course, you can also write
A side note, do not match with
x: Some[A]
(do not give the type parameter when matching on a generic type). It does not work, it will not verify that you have aSome[Something]
, but not thatSomething
isA
(see type erasure, the compiler gives a warning). You want to match withcase Some(x: A)
which gives you the content of theSome
inx
, what you normally want. If you actually want theSome
rather than its content,case s @ Some(x: A)
will binds
to theSome
instance,x
to its content. Use_
instead of x if you are not interested in it.If it is known that the type inside the option is
A
, then do not mention it, just writecase Some(x)
,case s: Some(_)