【问题标题】:Scala Actor Example: Expected Type was:?Scala Actor 示例:预期类型为:?
【发布时间】:2013-01-05 20:57:05
【问题描述】:

在一些教程的指导下,我一直在尝试获得一个简单的 Scala Actor 示例,在该示例中,我将(字符串)消息发送给演员,并且演员回复控制台的输出。 我的代码是:

import scala.io.Source
import scala.actors.Actor

object ProtTest {

  class testActor extends Actor {
    def receive = { 
      case "you" => Console.println("Hello you!")
      case _ => Console.println ("Hello ???")
    }
  }

  val t = new testActor
  t ! "you"
}

不幸的是,我在“def receive = {”上收到以下错误消息,并且现在卡住了很长一段时间:

Missing parameter type for expanded function 
The argument types of an anonymous function must be fully known (SLS 8.5)
Expected Type was: ?

我真的不知道错误消息中的问号是什么意思以及如何修复示例以使其正常工作?!

【问题讨论】:

  • 几乎没有理由使用旧的 Scala 标准库演员。使用 Akka 角色( Scala 2.10 及更高版本中的新标准库角色)。 Akka 的演员在各方面都比旧演员有所进步。

标签: scala actor


【解决方案1】:

您似乎对演员的实现有些困惑。您的 testActor 代码对 Akka 演员有效,但您使用的是 Scala 演员库。

Akka 和 scala.actors 是 Actor 模型的两个不同实现。 Scala actor 是最初的实现,但 Akka 现在更受欢迎(并且在 IMO 上更出色),并且从 Scala 2.10 开始,它是与 Scala 捆绑在一起的标准实现(scala.actors 存在,但在 2.10 中已弃用)。

我实际上不知道如何正确实现 scala actor,但这里是如何让您的 actor 在 Akka 中运行:

import akka.actor._

object ProtTest {

  class testActor extends Actor {
    def receive = { 
      case "you" => Console.println("Hello you!")
      case _ => Console.println ("Hello ???")
    }

    override def postStop() {
      context.system.shutdown
    }
  }

  val system = ActorSystem("test")
  val t = system.actorOf(Props[testActor])
  t ! "you"
  t ! PoisonPill
  system.awaitTermination

}

如您所见,Akka 需要一些样板来正确设置和关闭 Actor 系统,但您的主要 Actor 代码没有改变。 postStop方法在actor关闭后调用,当actor收到PoisonPill消息时发生。

【讨论】:

  • 你好,是的,我猜我对这两种实现有点混淆了。我正在阅读 Akka 文档并将其与一些关于 Scala Actors 的教程混合在一起。感谢您指出我的错误!
【解决方案2】:

receive 不是您实现的方法。你需要实现act,当你调用 receive:

  class testActor extends Actor {
    def act = {
      while (true) {
        receive {
          case "you" => Console.println("Hello you!")
          case _ => Console.println ("Hello ???")
        }
      }
    }
  }

所以receive 是您调用的方法。您传递给它的参数是带有 {..} 的代码块,其中包含 case 子句。这个参数的类型是一个 partial function - 在你的例子中,一个来自 String 的函数(scala 推断是因为“你” 是一个字符串)到Unit(scala 的void 版本,这是println 返回的内容)。

(请参阅 Twitters 的 Scala School,了解偏函数如何等效于一堆 case 语句)。

一旦你了解了基本的 scala 概念,编译错误消息就很容易理解了——在这种情况下,知道匿名函数和_ 速记的行为可能是必要的。

此外,如果您希望 Actor 实例接收消息,您需要使用 t.start 启动它。

虽然还没有被弃用, 大多数人(正如另一个答案所指出的那样)喜欢 Akka 演员。 从 Scala 2.10 开始,scala.actors.Actor 已被弃用,转而支持 Akka actor。

(作为旁注,如果您希望该代码工作,您还需要将 ProtTest 声明为扩展 App 或将调用 t ! "you" 移动到一个类(或对象)主要方法)

【讨论】:

    【解决方案3】:

    我使用 Akka 比使用 Scala 的 actor 系统更多,但是... here's a short tutorial;您可以从那里的示例中看到 receive 块应该在循环内(例如 while (true) {...}),在 def act() 方法内。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-10
      • 1970-01-01
      • 2017-04-17
      • 1970-01-01
      • 1970-01-01
      • 2019-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多