Как актеры Scala могут возвращать значение в ответ на сообщение? - PullRequest
14 голосов
/ 14 мая 2010

Существует множество примеров, когда актеры отвечают отправителю другим сообщением, но во время просмотра документации по API я заметил !! а также !? операторы, которые являются частью черты CanReply (которая, кажется, является новой для 2.8: http://www.scala -lang.org / archives / rc-api / scala / актеры / CanReply.html ). Поэтому мне было интересно, был ли это случай, когда блок приема / реагирования возвращал значение, то есть сделал ли тип возвращаемого значения PartialFunction чем-то отличным от Unit?

Я начну копаться в источнике, чтобы попытаться выяснить, как они должны использоваться, но если у кого-то есть какие-либо идеи или они знают о более глубокой документации или примерах, я был бы очень признателен.

Ура, Пол.

1 Ответ

22 голосов
/ 15 мая 2010

Ответы можно отправлять методом reply, как показано здесь:

import scala.actors._
class Reverser extends Actor {
  def act() { Actor.loop { react {
    case s: String => Thread.sleep(1000); reply(s.reverse)
    case _ => exit()
  }}}
}

Существует три способа явного принятия ответа.

  • Используйте !!, который возвращает Future, который является контейнерным классом, который обещает предоставить вам содержимое, когда вам это нужно. Он немедленно возвращается, но если вы действительно запрашиваете содержимое, вам придется подождать, пока другой поток не завершит работу, и заполнить запрос.
  • Используйте !? без таймаута. Ваш код будет приостановлен до тех пор, пока другой поток ответит.
  • Используйте !? с таймаутом. Ваш код будет приостановлен до получения ответа или до истечения времени ожидания, в зависимости от того, что наступит раньше.

Вот пример всех трех:

val r = new Reverser
r.start
val a = (r !! "Hi")
a() match {
  case s: String => println(s)
  case _ => println("Error A")
}
val b = r !? "Hello"
b match {
  case s: String => println(s)
  case _ => println("Error B")
}
val c = (r !? (500,"Howdy"))
c match {
  case Some(s: String) => println(s)
  case Some(_) => println("Error C")
  case None => println("Too slow!")
}
r ! None  // None isn't a string, so r will stop running

И если вы запустите это, вы получите

iH
elloH
Too slow!
...