【问题标题】:Create an actor创建演员
【发布时间】:2013-12-26 13:46:35
【问题描述】:

这可能是一个非常简单的错误,但我无法让它正常工作。 我正在使用 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") 创建我的演员吗?

【问题讨论】:

  • 我非常确定问题在于您将内部类用于 Refresher 类。说不出为什么。
  • @om-nom-nom 这就是问题所在。谢谢你。不过很高兴知道为什么会这样。

标签: scala akka


【解决方案1】:

如果您想使用嵌套类进行此操作,您将需要实例化嵌套actor,并将对封闭actor 的引用作为构造函数arg 传递。您看到的错误是说没有 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 方法。
  • 这样做有危险吗?它会破坏封装吗?
【解决方案2】:

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 我回答后问题的内容可能已经改变。根据评论,很明显有一些 sn-ps 显示了一个内部类。同样,根据 2013 年 9 月 12 日的评论,这就是问题所在。
猜你喜欢
  • 2021-02-11
  • 1970-01-01
  • 2015-09-25
  • 1970-01-01
  • 1970-01-01
  • 2022-11-07
  • 2022-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多