Scala中的Akka,感叹号和问号


74

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

myActor ! Hello(value1)
myActor ? Hello(value1)

Answers:


124

无耻地复制[很棒的] 官方文档(有关更多信息,请参见“发送消息”部分):

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

!表示“一劳永逸”,例如异步发送消息并立即返回。也称为tell

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


2
对于对此实现方式感兴趣的任何人,请参见Scala中的操作员重载:dzone.com/articles/operator-overloading-scala
Janac Meena,

!意思是“一劳永逸”,描述性更强!
阿德林

24

从收件人的角度来看,它以相同的方式查看tellask发送消息。但是,当接收到时,tell的值sender将是发送消息的演员的引用,而对于ask,则将sender设置为,使得任何答复都将发送给Future进行询问的演员中的创建者。

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

在下面的代码中,使用tell和和可实现相同的效果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!"
  }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.