2015-12-03 3 views
4

У меня есть что-то вроде этого:Scala случае класс не соответствует в получить метод (в AKKA актеров)

class ProbeActor extends Actor { 
    case class Probe(messageKey: String) 
    def receiveProbe: Receive = { 
    case Probe(probeKey) => println("Good probe: "+probeKey) 
    case x => println("Bad probe: "+ x) 
    } 
    final override def receive = receiveProbe orElse receiveOther 
    def receiveOther: Receive = { 
    case _ => println("Other") 
    } 
} 

и я называю это так:

class Prober extends ProbeActor { 
    val definite = ActorSystem("ProbeTest").actorOf(Props[ProbeActor], name = "probed") 
    implicit val timeout = Timeout(5 second) 
    val future = definite ? Probe("key") 
} 

Я ожидаю, что текст "Good probe: key" РЕКОМЕНДУЕМЫМ печататься, но я получаю "Bad probe: Probe(key)".

Примечание: Если я положил класс корпуса Probe снаружи, то он отлично работает.

ответ

6

После поиска больше, я нашел ответ на scala-lang.org:

Я думаю, что основное заблуждение о тождественности вложенных типов классов.

В

класса А {В} класс

каждый новый экземпляр класса А х создает новый тип x.B. И если вы делаете , то простую комбинацию шаблонов внутри A вы ссылаетесь на конкретный экземпляр типа B this.B.

+2

Это правильно. Я думаю, по соглашению вы должны помещать свои сообщения в сопутствующий объект актера, а не в самого актера. При этом у вас не должно быть проблем с зависимой типизацией, и вам не нужно сохранять ссылку на актера, который считается плохим – Archeg

2

Способ сопоставления с образцом на Probe без перемещения его за пределы класса

case probe: ProbeActor#Probe => println("Good probe: "+probe.messageKey) 

Конечно, перемещая ее пределами (например, к объекту компаньон) является лучшим решением; особенно в Акке, как упоминает Архег, чтобы избежать прямой ссылки на актера.