2

我想知道演员如何将值返回给发送者以及如何将其存储在变量中。

例如,假设我们必须找到 2 个数字的平方和并打印出来。

即总和 = a 2 + b 2

我有2个演员。1 个参与者计算传递给它的任何数字的平方(例如SquareActor)。另一个参与者将两个数字 (a , b) 发送给SquareActor并计算它们的总和(例如SumActor

/** Actor to find the square of a number */

class SquareActor (x: Int) extends Actor
{
  def act()
  {
    react{
        case x : Int => println (x * x)  
        // how to return the value of x*x to "SumActor" ?
    }
  } 
}

/** Actor to find the sum of squares of a and b */

class SumActor (a: Int, b:Int) extends Actor
{
  def act()
  {
    var a2 = 0
    var b2 = 0        

    val squareActor = new SquareActor (a : Int)   
    squareActor.start

    // call squareActor to get a*a 
    squareActor ! a 
// How to get the value returned by SquareActor and store it in the variable 'a2' ?

    // call squareActor to get b*b 
    squareActor ! b
// How to get the value returned by SquareActor and store it in the variable 'b2' ?

    println ("Sum: " + a2+b2)
  } 
}

如果以上不可能,请原谅我;我想我对演员的基本理解本身可能是错误的。

4

2 回答 2

4

使用阿卡

请注意,从 Scala 2.10 开始,Akka演员库是标准库的集成部分。它通常被认为优于标准演员库,因此熟悉它会对您有所帮助。

使用期货

另请注意,您想要使用Futures实现更容易和更好(组合更好) 。AFuture[A]代表一个可能并发的计算,最终产生一个类型的结果A

def asyncSquare(x: Int): Future[Int] = Future(x * x)
val sq1 = asyncSquare(2)
val sq2 = asyncSquare(3)

val asyncSum = 
  for {
    a <- sq1
    b <- sq2
  }
  yield (a + b)

请注意,asyncSquare提前查询结果以尽快开始其(独立)计算。将调用放在for理解中会序列化它们的执行,而不是使用可能的并发性。

您在推导中使用Future-s formapflatMapzip,最后,您可以使用(这是一个阻塞操作)或使用注册的回调sequence来获取计算值。Await

与演员一起使用期货

从演员那里可以很方便ask,这会导致Future

val futureResult: Future[Int] = (someActor ? 5).mapTo[Int]

注意需要使用,mapTo因为actors的消息传递接口是没有类型的(但是有类型的actors)。

底线

如果要并行执行无状态计算,请坚持使用 plain Futures。如果您需要有状态的本地计算,您仍然可以Future自己使用和线程化状态(或者使用 scalaz StateT monad transformer + Future 作为 monad,如果您从事该业务)。如果您需要需要全局状态的计算,则将该状态隔离到一个参与者中,并与该参与者进行交互,可能使用Futures.

于 2012-09-08T07:55:59.380 回答
2

请记住,演员通过消息传递工作。因此,要从SquareActor后端获得响应SumActor,您需要将其作为消息从 发送SquareActor,并将处理程序添加到SumActor.

此外,您的SquareActor构造函数不需要整数参数。

也就是说,在您的SquareActor,而不仅仅是打印x * x,将其传递给SumActor

class SquareActor extends Actor
{
  def act()
  {
    react{
        case x : Int => sender ! (x * x)  
    }
  } 
}

sender使其将消息发送给发送它正在响应的消息的参与者。)

在您的SumActor, 发送ab到 后SquareActor,处理收到的回复消息:

react {
  case a2 : Int => react {
    case b2 : Int => println ("Sum: " + (a2+b2))
  }
}
于 2012-09-08T04:04:51.757 回答