Scala中的Akka,感叹号和问号

tic*_*fab 63 scala operators actor akka

向Actors发送消息时感叹号(!)和问号(?)之间有什么区别?

myActor ! Hello(value1)
myActor ? Hello(value1)
Run Code Online (Sandbox Code Playgroud)

om-*_*nom 111

无耻地复制[awesome] 官方文档(查看发送消息部分了解更多):

消息通过以下方法之一发送到Actor.

!意思是"发射并忘记",例如异步发送消息并立即返回.也称为tell.

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

  • 对于任何对此如何完成感兴趣的人 - 请参阅 Scala 中的运算符重载:https://dzone.com/articles/operator-overloading-scala (2认同)

mat*_*its 20

从收件人的角度来看,它以相同的方式看到tellask发送消息.然而,当接收到tell的值sender将是发送消息的actor的引用时,而对于a ask,sender则设置为使得任何回复转到Future在执行询问的actor中创建的.

有一个优点是ask,很容易知道您收到的响应肯定是您询问的消息的结果,而使用Tell,您可能需要使用唯一ID来获得类似的结果.但是,如果没有收到响应,则ask需要设置一个timeout之后Future将失败.

在下面的代码中,a tell和and 实现了相同的效果ask.

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!"
  }
}
Run Code Online (Sandbox Code Playgroud)