Akka在Scala中的感叹号和问号

82

在给演员发送消息时,惊叹号(!)和问号(?)有什么区别?

myActor ! Hello(value1)
myActor ? Hello(value1)
2个回答

137

不要介意,我抄袭了一个 [厉害的]官方文档 (查看更多信息请看发送消息部分):

消息可以通过以下方法之一发送给Actor。

! 表示“fire-and-forget”,即异步发送消息并立即返回。也称为 tell

? 异步发送消息并返回表示可能回复的 Future。 也称为 ask


3
对于任何对此感兴趣的人,请查看Scala中的运算符重载:https://dzone.com/articles/operator-overloading-scala - Janac Meena
感叹号表示“发射并忘记”,这个描述再贴切不过了! - Adelin

26

从接收者的角度来看,它以相同的方式看待 tellask 消息。但是在接收到 tell 时,sender 的值将是发送消息的 Actor 的引用,而对于一个 asksender 被设置为任何回复都会被发送到提问者 Actor 中创建的 Future

ask 的优点在于易于知道您接收到的响应确实是您所请求的消息的结果,而使用 tell,您可能需要使用唯一的 ID 才能实现类似的结果。但是,对于 ask,您需要在接收到响应之前设置一个 timeout,否则 Future 将失败。

在下面的代码中,使用 tellask 实现了相同的效果。

import akka.actor.{Props, Actor}
import scala.concurrent.duration._
import akka.pattern.ask

class TellActor extends Actor {

  val recipient = context.actorOf(Props[ReceiveActor])

  def receive = {
    case "Start" =>
      recipient ! "Hello" // equivalent to recipient.tell("hello", self)

    case reply => println(reply)
  }
} 

class AskActor extends Actor {

  val recipient = context.actorOf(Props[ReceiveActor])

  def receive = {
    case "Start" =>
      implicit val timeout = 3 seconds
      val replyF = recipient ? "Hello" // equivalent to recipient.ask("Hello")
      replyF.onSuccess{
        case reply => println(reply)
      }
  }
}

class ReceiveActor extends Actor {

  def receive = {
    case "Hello" => sender ! "And Hello to you!"
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接