无法在 Akka Actor 的 receive() 中增加 'total' 变量
cannot increment a 'total' variable inside receive() in Akka Actor
我是 Scala 的新手(Akka Actors。我知道避免 actors 中的可变状态有好处,但是我找到了增加 var 总数的解决方案
类似于 SO 问题给出的问题:
Alternatives to using "var" for state with actors?
我的代码如下。
解决方案看起来很简单:我的 Calculator actor 维护一个本地 var 总计,并且在 receive() 中对案例 class 的适当匹配 => 使用从匹配案例中提取的金额来增加这个总计 class.
我的案例陈述有效。 println 显示每次我的输入与 case 语句匹配时,要添加到总数 (amt) 的金额由匹配产生。 IE。这按预期工作:
case MyCaseClass(_, amt) => println(amt)
但是这一行:
案例 MyCaseClass(_, amt) => 总计 += amt
失败。本地 var total 永远不会递增。我尝试使用列表,并将新的 amt 作为新成员添加到 var 列表中,但这也失败了。在每种情况下,局部变量的增量,无论是类型 Double 还是 List[Double] 都会失败。为什么是这样?我该怎么做才能让增量在 receive() 中工作?
代码:
import akka.actor.ActorSystem
import akka.actor.Props
class CostingActor extends Actor {
var bedrooms:Double = 0.0
var bathrooms: Double = 0.0
def receive = {
//THIS IS THE OFFENDING LINE OF CODE--PRINTS OUT P FINE, EACH TIME A MATCH IS MADE
case RoomPojo("Bedroom", p) => bedrooms += p //println(p)
case RoomPojo("Bathroom", p) => bathrooms += p //println(p)
case "total" => println(bedrooms + bathrooms)
}
}
object Main extends App {
val system = ActorSystem("CostingSystem")
var costingActor = system.actorOf(Props[CostingActor], name = "costingactor")
var roomActor = system.actorOf(Props[RoomActor], name = "roomactor")
for (i <- 0 until args.length)
roomActor ! args(i)
//the following line of code may be wrong; (I also tried a future) but should n't the variables bedrooms
// and bathrooms still show at least some incrementation?
costingActor ! "total"
system.shutdown()
}
object RoomActor {
case class RoomPojo(name:String, price:Double) {}
}
class RoomActor extends Actor {
val checkout = context.actorOf(Props[CostingActor])
def receive: Receive = {
case "Bedroom" => checkout ! new RoomPojo("Bedroom", 45.0)
case "Bathroom" => checkout ! new RoomPojo("Bathroom", 90.0)
case _ => println("missed in room")
}
}
您的 Main
中的 system.actorOf(Props[CostingActor], name = "costingactor")
与 RoomActor
中的 context.actorOf(Props[CostingActor])
是不同的演员。每个 actorOf
创建该 actor 的一个新实例,每个都有自己的状态。您将 RoomPojo
消息发送到一个 actor 实例,并向一个完全不同的实例请求状态,该实例根本没有看到任何 RoomPojo
消息。
您可以修改 RoomActor 以将 actorRef 作为参数并将 costingActor
传递给 Props,这样您就可以为状态使用相同的 actor 实例。
var costingActor = system.actorOf(Props[CostingActor], name = "costingactor")
var roomActor = system.actorOf(Props(classOf[RoomActor], costingActor), name = "roomactor")
// ...
class RoomActor(checkout: ActorRef) extends Actor
此外,由于一切都是异步的,如果您在发送消息后立即关闭系统,'total'消息可能会丢失。
我是 Scala 的新手(Akka Actors。我知道避免 actors 中的可变状态有好处,但是我找到了增加 var 总数的解决方案 类似于 SO 问题给出的问题:
Alternatives to using "var" for state with actors?
我的代码如下。
解决方案看起来很简单:我的 Calculator actor 维护一个本地 var 总计,并且在 receive() 中对案例 class 的适当匹配 => 使用从匹配案例中提取的金额来增加这个总计 class.
我的案例陈述有效。 println 显示每次我的输入与 case 语句匹配时,要添加到总数 (amt) 的金额由匹配产生。 IE。这按预期工作:
case MyCaseClass(_, amt) => println(amt)
但是这一行:
案例 MyCaseClass(_, amt) => 总计 += amt
失败。本地 var total 永远不会递增。我尝试使用列表,并将新的 amt 作为新成员添加到 var 列表中,但这也失败了。在每种情况下,局部变量的增量,无论是类型 Double 还是 List[Double] 都会失败。为什么是这样?我该怎么做才能让增量在 receive() 中工作?
代码:
import akka.actor.ActorSystem
import akka.actor.Props
class CostingActor extends Actor {
var bedrooms:Double = 0.0
var bathrooms: Double = 0.0
def receive = {
//THIS IS THE OFFENDING LINE OF CODE--PRINTS OUT P FINE, EACH TIME A MATCH IS MADE
case RoomPojo("Bedroom", p) => bedrooms += p //println(p)
case RoomPojo("Bathroom", p) => bathrooms += p //println(p)
case "total" => println(bedrooms + bathrooms)
}
}
object Main extends App {
val system = ActorSystem("CostingSystem")
var costingActor = system.actorOf(Props[CostingActor], name = "costingactor")
var roomActor = system.actorOf(Props[RoomActor], name = "roomactor")
for (i <- 0 until args.length)
roomActor ! args(i)
//the following line of code may be wrong; (I also tried a future) but should n't the variables bedrooms
// and bathrooms still show at least some incrementation?
costingActor ! "total"
system.shutdown()
}
object RoomActor {
case class RoomPojo(name:String, price:Double) {}
}
class RoomActor extends Actor {
val checkout = context.actorOf(Props[CostingActor])
def receive: Receive = {
case "Bedroom" => checkout ! new RoomPojo("Bedroom", 45.0)
case "Bathroom" => checkout ! new RoomPojo("Bathroom", 90.0)
case _ => println("missed in room")
}
}
您的 Main
中的 system.actorOf(Props[CostingActor], name = "costingactor")
与 RoomActor
中的 context.actorOf(Props[CostingActor])
是不同的演员。每个 actorOf
创建该 actor 的一个新实例,每个都有自己的状态。您将 RoomPojo
消息发送到一个 actor 实例,并向一个完全不同的实例请求状态,该实例根本没有看到任何 RoomPojo
消息。
您可以修改 RoomActor 以将 actorRef 作为参数并将 costingActor
传递给 Props,这样您就可以为状态使用相同的 actor 实例。
var costingActor = system.actorOf(Props[CostingActor], name = "costingactor")
var roomActor = system.actorOf(Props(classOf[RoomActor], costingActor), name = "roomactor")
// ...
class RoomActor(checkout: ActorRef) extends Actor
此外,由于一切都是异步的,如果您在发送消息后立即关闭系统,'total'消息可能会丢失。