2010-05-14 6 views
14

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

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

Cheers, Paul.

ответ

22

Ответы могут быть отправлены с помощью метода 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! 
+0

Спасибо за это! Я также немного поработал и нашел это: http://java.dzone.com/articles/scala-threadless-concurrent , который к дате его предполагает, что операторы не новы к 2.8, даже если свойство CanReply. – pdbartlett

+1

@pdbartlett: Это правильно. Приведенный выше код будет работать и в версии 2.7, за исключением того, что '.reverse' не создает строку в 2.7, поэтому пример не будет работать, если вы не выполняете' .reverse.toString'. Но все актеры/будущие вещи прекрасно работают. –