【问题标题】:how to solve an equation in scala using actors?如何使用演员解决scala中的方程?
【发布时间】:2012-09-08 04:00:21
【问题描述】:

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

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

即总和 = a2 + b2

我有两个演员。 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)
  } 
}

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

【问题讨论】:

  • 我对符号数学非常感兴趣,这段代码对于方程求解器来说看起来非常优雅和简洁,但我看不到它如何求解方程?在我看来它只是计算一个基本函数?

标签: scala actor message-passing


【解决方案1】:

使用阿卡

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

使用期货

还请注意,使用Futures 可以更轻松、更好地实现您想要的目标(组合更好)。 Future[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 理解中会序列化它们的执行,而不是使用可能的并发。

你在for理解中使用Future-s,mapflatMapzipsequence它们,最后,你可以使用Await得到计算值,这是一个阻塞操作,或者使用注册的回调。

将期货与演员一起使用

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

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

注意需要使用mapTo,因为actor的消息传递接口没有类型化(不过有typed actors)。

底线

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

【讨论】:

    【解决方案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))
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-07
      • 2012-09-02
      • 2011-08-31
      • 2013-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多