2

你们中的任何人都可以帮助我理解使用 Actor 模型在 scala 中传递的基本消息吗?

我正在尝试用 3 个演员编写一个简单的程序。

  1. 演员“BossActor”创建了 2 个演员“Actor1”和“Actor2”

  2. “Actor1”接受 2 个整数参数 -> 找到它们的总和 -> 将总和传递给 Actor2

  3. “Actor2”打印总和

package actorsSum

import scala.actors.Actor
import scala.actors.Actor._

case object BossActor
case object Actor1
case object Actor2

object SumOf2Numbers extends App
{

    print ("Enter Num1 : ")
    val Num1 = readInt()
    print ("Enter Num2 : ")
    val Num2 = readInt()

    var Sum = 0

    val bossActor = new BossActor(Num1,Num2,Sum)
    bossActor.start

}

/** Boss Actor which creates and controls all subsequent actors */
class BossActor(Num1: Int, Num2: Int, Sum: Int) extends Actor {
    def act() {

        val act1 = new Actor1(Num1,Num2)
        val act2 = new Actor2(Sum)
        act1.start
        act2.start

    }
}

/** Actor to find sum of the numbers */

class Actor1 (Num1: Int, Num2: Int) extends Actor {
    def act() {

        val Grandtotal = Num1 + Num2

        /** send "Grandtotal" to Actor2 */
        // act2 ! Grandtotal

    }
}

/** Actor to print the sum */

class Actor2(Sum: Int) extends Actor {
    def act() {

        react{

            /** print the sum */

            case Actor1 => println ("Sum: " + Sum)

            case Sum => println ("Sum: " + Sum)


        }
    }
}
4

3 回答 3

3

我会采取不同的方法。Actor 接收消息并对其做出反应。所以你应该做的是构建一个actor,它接收对两个数字求和的请求,并将它们发送到消息中指定的接收器。这可能看起来像这样:

import scala.actors.Actor

case class Sum(x: Int, y: Int)

class SumActor extends Actor {
  def act = {
    loop {
      receive {
        case (Sum(x,y), receiver: Actor) => receiver ! x+y
      }
    }
  }
}

class Receiver extends Actor {
  def act = {
    loop {
      receive {
        case x: Int => println("Received: " + x)
      }
    }
  }
}

val sumActor = new SumActor
val receiver = new Receiver

sumActor.start
receiver.start

sumActor ! Sum(3,4) -> receiver

您还应该看看Akka,因为它将在未来的 scala 版本中取代 scala 演员,并且更强大。但是要了解演员的基础知识,从 Scala 演员开始就足够了。

于 2012-09-05T09:27:12.820 回答
1

首先是运行代码:

import scala.actors.Actor
import scala.actors.Actor._

object Main extends App {
    print("Enter first number: ")
    private[this] val num1 = readInt()
    println(num1)
    print("Enter second number: ")
    private[this] val num2 = readInt()
    println(num2)

    private[this] val boss = new BossActor(num1, num2)
    boss.start()
}

case object Stop

class BossActor(num1: Int, num2: Int) extends Actor {
    def act {
        val sumer = new SumActor()
        val printer = new PrintingActor()
        sumer.start()
        printer.start()
        sumer ! num1
        sumer ! num2
        receive {
            case i: Int => printer ! i
        }
        sumer ! Stop
        printer ! Stop
        exit()
    }
}

class SumActor extends Actor {
    private[this] var firstOption: Option[Int] = None

    def act() {
        loop {
            react {
                case i: Int => if (firstOption.isDefined) {
                    sender ! i + firstOption.get
                    firstOption = None
                } else {
                    firstOption = Some(i)
                }
                case Stop => exit()
            }
        }
    }

}

class PrintingActor extends Actor {

    def act() {
        loop {
            react {
                case Stop => exit()
                case e => println(e)
            }
        }
    }

}

我像你一样读数字。比我创建一个新的BossActor. 接下来,老板将收到的内容发送IntSumActor. sumer 将这两个值相加并返回给老板。老板把总和寄给PrintingActor. 打印机打印数字。之后,老板向他的演员发送终止消息并终止自己。这可能会通过向老板发送两个来改进Int,但在这个简单的示例中,它可能会展示如何创建一个Actorwtih 参数。

于 2012-09-05T06:13:15.630 回答
1

首先:sender(Actor1)应该知道receiver(Actor2),所以你应该在sender之前创建并启动receiver,并将receiver作为构造函数参数传递给sender。

不要var用来分享演员的状态。

使用案例对象作为消息是一个好主意,但您应该使用案例类来发送一些值。

import scala.actors.Actor
import scala.actors.Actor._

case class Sum(i: Int)

class Sender(a1: Int, a2: Int, receiver: Actor) extends Actor {
  def act() {
    receiver ! Sum(a1 + a2)
  }
}

class Receiver extends Actor {
  def act() {
    react {
      case Sum(i) => println("Sum: " + i)
    }
  }
}

val receiver = new Receiver().start()
val sender = new Sender(1, 2, receiver).start()

您可以使用对象 Actor 的一些辅助方法:

import scala.actors.Actor._

val receiver = actor { react { case i: Int => println("Sum: " + i) } }
val sender = actor { receiver ! 1 + 2 }
于 2012-09-05T06:22:13.813 回答