Scala演员示例:预期类型是:?

时间:2013-01-22 15:13:00

标签: scala actor

在一些教程的指导下我一直试图让一个简单的Scala Actor示例工作,我向一个actor发送一个(String-)消息,并且该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: ?

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

3 个答案:

答案 0 :(得分:5)

看起来你对actor的实现有点困惑。您的testActor代码对Akka actor有效,但您使用的是Scala actors库。

Akka和scala.actors是actor模型的两个不同实现。 Scala actor是最初的实现,但Akka现在更受欢迎(并且远远优于IMO),而Scala 2.10是与Scala捆绑的标准实现(scala.actors存在但在2.10中已弃用)。

我实际上不知道如何正确实现一个scala 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收到PoisonPill消息时发生。

答案 1 :(得分:3)

receive不是您实施的方法。当您致电 act时,您需要实施receive

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

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

(有关部分函数如何等同于一堆case语句的详细解释,请参阅Twitters'Scala School。

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

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

虽然尚未弃用, 大多数人(正如其他答案所指出的那样)倾向于Akka演员。 自Scala 2.10起,scala.actors.Actor被弃用,转而支持Akka actor。

(作为旁注,如果您希望该代码有效,您还需要将ProtTest声明为扩展App或将调用t ! "you"移至使用main方法的类(或对象)

答案 2 :(得分:0)

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