2015-10-18 6 views
-1

Я новичок в Scala (Акка Актеры. Я знаю, что есть преимущества избегать изменчивого состояния у актеров, но найдено решение для увеличения количества ванов аналогично тому, что дается SO вопрос:.не может увеличивать «общую» переменную внутри receive() в Akka Actor

Alternatives to using "var" for state with actors?

Мой код находится ниже

решение представляется простой: мой калькулятор актер поддерживает локальную общей Var, и соответствующий матч на случай класса в receive() => увеличивает эту сумму с суммой, извлеченной из случая соответствия cl жопа.

Мои заявления о действиях работают. В println показано, что каждый раз, когда мой ввод совпадает с оператором case, сумма, добавляемая к сумме (amt), дается совпадением. То есть это работает, как ожидалось:

случай MyCaseClass (_, АМТ) => Println (АМТ)

Но эта линия:

случай MyCaseClass (_, АМТ) => общая + = амт

не работает. Локальная сумма var никогда не увеличивается. Я попытался использовать список и добавив новый amt в качестве нового члена в список var, но это также не удается. В каждом случае приращение локального 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") 
    } 
} 
+2

Можете вставить свой код? – curious

+0

В таких случаях я предпочел бы использовать состояние. – Ashalynd

+0

@curious Вот часть моего кода - сокращенная встретить комментарий предел: 'класса CostingActor расширяет Actor { частного вар bedroomTotal = 0.0 уаг bathroomTotal = 0,0 Защиту получить = { случая RoomPojo ("Спальня" , p) => bedroomTotal + = p; кейс RoomPojo ("Ванная комната", p) => bathroomTotal + = p; случая "всего" => Println (bedroomTotal + bathroomTotal) } } ', а также класс' RoomActor расширяет Actor { VAL кассы = context.actorOf (Реквизит [CostingActor]) Защиты получить: Прием = { случая " Спальня "=> выписка! новый RoomPojo («Спальня», 25.0) ... } ' } –

ответ

1

system.actorOf(Props[CostingActor], name = "costingactor") от вашего Main является другой актер, чем context.actorOf(Props[CostingActor]) от RoomActor. Каждый actorOf создает новый экземпляр этого актера, каждый со своим собственным состоянием. Вы отправляете сообщения RoomPojo экземпляру одного актера и задаете совершенно другой экземпляр для состояния, которое вообще не обнаружило сообщений RoomPojo.

Вы можете изменить RoomActor, чтобы взять actorRef в качестве параметра и передать costingActor реквизитам, таким образом, вы используете один и тот же экземпляр актера для состояния.

var costingActor = system.actorOf(Props[CostingActor], name = "costingactor") 
var roomActor = system.actorOf(Props(classOf[RoomActor], costingActor), name = "roomactor") 

// ... 

class RoomActor(checkout: ActorRef) extends Actor 

Кроме того, поскольку все асинхронные, то «общее» сообщение может быть потеряно, если вы выключить систему сразу же после отправки сообщения.

+0

Спасибо, knutwalker, это выглядит очень полезно. Я попробую это. –

 Смежные вопросы

  • Нет связанных вопросов^_^