2010-05-14 16 views
14

Hay muchos ejemplos de actores que responden con otro mensaje al remitente, pero mientras navegaba por los documentos de la API noté el !! y! operadores que son parte del rasgo CanReply (que parece ser nuevo en 2.8: http://www.scala-lang.org/archives/rc-api/scala/actors/CanReply.html). Por lo tanto, me preguntaba si era solo el caso de que el bloque recibir/reaccionar devolviera un valor, es decir, hacer que el tipo de retorno de PartialFunction fuera distinto de la unidad.¿Cómo pueden los actores de Scala devolver un valor en respuesta a un mensaje?

Comenzaré a buscar en la fuente para tratar de averiguar cómo deben usarse, pero si alguien tiene alguna idea o sabe de más documentación o ejemplos detallados, le agradecería muchísimo. .

Cheers, Paul.

Respuesta

22

Las respuestas pueden enviarse con el método reply, como se muestra aquí:

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

Hay tres maneras de aceptar explícitamente la respuesta.

  • Uso !!, que devuelve un Future, que es una clase de contenedor que se compromete a darle el contenido cuando los necesite. Se devuelve inmediatamente, pero si realmente solicita los contenidos, debe esperar hasta que el otro hilo finalice y complete la solicitud.
  • Use !? sin tiempo de espera. Su código se detendrá durante el tiempo que tarde en responder el otro hilo.
  • Use !? con un tiempo de espera agotado. Su código se detendrá hasta que reciba una respuesta o hasta que expire el tiempo de espera, lo que ocurra primero.

He aquí un ejemplo de los tres:

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 

Y si ejecuta esto se obtiene

iH 
elloH 
Too slow! 
+0

Gracias por eso! También investigué un poco y encontré esto: http://java.dzone.com/articles/scala-threadless-concurrent que a la fecha sugiere que los operadores no son nuevos en 2.8, incluso si el rasgo CanReply es. – pdbartlett

+1

@pdbartlett: Eso es correcto. El código anterior también funcionará en 2.7, excepto que '.reverse' no produce una cadena en 2.7, por lo que el ejemplo no funcionará a menos que haga' .reverse.toString'. Pero todo el actor/futuro funciona bien. –

Cuestiones relacionadas