创建一个角色(Actor)

9
这可能是一个非常简单的错误,但我无法使其正常工作。我正在使用akka 2.2.3在scala中创建基于actor的应用程序。
简化的设置如下:
object Main {
  def main(args: Array[String]) = {
    val system = ActorSystem("Test")
    val discoverer = system.actorOf(Props[Discoverer], "discoverer")

    implicit val timeout = Timeout(5.seconds)

    val not = discoverer ? Messages.Find(something)

    not.onComplete {
      case Success(va) => println(va)
      case Failure(err) => println(err)
    }
    ...
  }
}

而主角

class Discoverer extends Actor {
  override def preStart() = {
    val refresher = context.actorOf(Props[Refresher], "refresher")
    refresher ! Refresh
  }

  def receive = {
    case _ => sender ! Answer
  }
}

同时,Refresher 演员

 class Refresher extends Actor {
   ...
 }

你需要了解的是,我的所有演员都没有参数化构造函数。
然而,如果我尝试运行我的应用程序,它会失败并显示以下错误:
[ERROR] [12/09/2013 13:17:06.893] [Test-akka.actor.default-dispatcher-3] 
 [akka://Test/user/discoverer] no matching constructor found on 
  class Discoverer$Refresher for arguments []

我在这里出了什么错误?我是否不应该使用.actorOf(Props[Class], "actorname")来创建我的Actor呢?


3
我很确定问题出在你将内部类用作Refresher类。不知道具体原因。 - om-nom-nom
1
@om-nom-nom 那就是问题所在。谢谢你。不过知道为什么会这样会更好。 - mgttlinger
2个回答

12

如果你想让这个功能适用于嵌套类,你需要实例化嵌套的actor,并将封闭actor的引用作为构造函数参数传递进去。你看到的错误提示说没有no-args构造函数,这是一个提示。让代码运行起来的方法如下:

object InnerTest {
  def main(args: Array[String]) {
    val sys = ActorSystem("test")
    sys.actorOf(Props[OuterActor])
  }
}

class OuterActor extends Actor{

  override def preStart = {
    context.actorOf(Props(classOf[InnerActor], this), "my-inner-actor")
  }

  def receive = {
    case _ =>
  }

  class InnerActor extends Actor{
    def receive = {
      case _ =>
    }
  }
}

我猜测这与尝试通过反射实例化非静态内部类(未给出外部类引用)有关。我通过阅读这篇帖子确定了这一点:

https://www.assembla.com/spaces/akka/tickets/3675#/activity/ticket


好的提示,尽管所提供的解决方案对我没有用。我在伴生对象中定义了一个props方法。 - Mahdi
这样做是不安全的吗?它会破坏封装性吗? - SwiftMango

0

RefresherDiscoverer 的内部类,因此,如果您想创建 Refresher 的实例,您需要在 Discoverer 的实例上下文中执行它。

以这个例子为例:

class A{
  class B{}
}

我可以执行new A,但是new B会返回一个错误。我必须这样做:

val a = new A
val b = new a.B

这就是为什么akka无法创建此actor的原因。

你能展示一下应该如何构建 actor 以避免这个问题吗?由于问题中没有 new,因此我不清楚如何将这个回答应用到它上面。 - Suma
@suma在我回答问题后,问题的内容可能已经发生了变化。根据评论,很明显有一些代码片段展示了一个内部类。而且,根据2013年9月12日的评论,这就是问题所在。 - vptheron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接