【问题标题】:Basic Scala Actors: examples from books not "acting" at allBasic Sc​​ala Actors:书中的例子根本不是“表演”
【发布时间】:2011-04-13 07:39:07
【问题描述】:

我对 Scala 非常陌生,而且对 Java 太生疏了,我认为自己除了是一个完整的新手之外什么都不是。所以我正在采取简单的步骤来学习它。

在查看演员时,我尝试了一些方法,但遇到了许多 NoClassDefFound 错误。最终,我决定以书本示例为基础,而不是调试我的第一次尝试。惊喜:书中的示例没有按预期工作!

这是 O'Reilly 的 Programming Scala 中的示例:

import scala.actors.Actor

class Redford extends Actor {
  def act() {
    println("A lot of what acting is, is paying attention.")
  }
}

val robert = new Redford
robert.start

应该在执行时打印雷德福报价。但是当我启动它时,什么也没有发生,我回到命令行:

D:\prog\scala-2.8.1.final\pierric>scala testactors.scala

D:\prog\scala-2.8.1.final\pierric>

另一个例子来自七周内的七种编程语言。是这样的(我只是懒得换弦了):

import scala.actors._
import scala.actors.Actor._

case object Poke;
case object Feed;

class Kid() extends Actor {
    def act() {
        loop {
            react {
                case Poke => {
                    println("Ow")
                    println("Quit it")
                }
                case Feed => {
                    println("gurgle")
                    println("burp")
                }
            }
        }
    }
}

var bart = new Kid().start
var lisa = new Kid().start
println("starting")
bart ! Poke
lisa ! Poke
bart ! Feed
lisa ! Feed

这一次它应该返回一个随机排序的“ow quit it”和“gurgle burp”序列。但是,当我运行它时:

D:\prog\scala-2.8.1.final\pierric>scala testkids.scala
starting

D:\prog\scala-2.8.1.final\pierric>

现在,另一个有趣的事情。如果我在我的 act 方法的开头添加一个简单的 println 行:

class Kid() extends Actor {
    def act() {
        println("Kid initializing")
        loop {
            react {
                ...

然后我得到了大部分时间:

D:\prog\scala-2.8.1.final\pierric>scala testkids.scala
starting
Kid initializing
Kid initializing

D:\prog\scala-2.8.1.final\pierric>

但有时也:

starting
Kid initializing
Kid initializing
scala.actors.Actor$$anon$1@5a9de6: caught java.lang.NoClassDefFoundError: Main$$anon$1$Fee
    java.lang.NoClassDefFoundError: Main$$anon$1$Feed$
            at Main$$anon$1.Main$$anon$$Feed(testkids.scala:5)
            at Main$$anon$1$$anonfun$1.apply$mcV$sp(testkids.scala:31)
            at scala.actors.Actor$$anon$1.act(Actor.scala:135)
            at scala.actors.Reactor$$anonfun$dostart$1.apply(Reactor.scala:222)
            at scala.actors.Reactor$$anonfun$dostart$1.apply(Reactor.scala:222)
            at scala.actors.ReactorTask.run(ReactorTask.scala:36)
            at scala.concurrent.forkjoin.ForkJoinPool$AdaptedRunnable.exec(ForkJoinPool.java:6
            at scala.concurrent.forkjoin.ForkJoinTask.quietlyExec(ForkJoinTask.java:422)
            at scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.ja
            at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:32
    Caused by: java.lang.ClassNotFoundException: Main$$anon$1$Feed$
            at java.net.URLClassLoader$1.run(Unknown Source)

所以我在这里,一无所知......因为这些是“书外”的例子,实际上是两本书!并且似乎不起作用。我在 2 台不同的机器上试过,它们很可能有不同的 JVM。在这两种情况下,我都运行了 scala 2.8.1.final。一台机器运行 Windows XP 32 位,另一台运行 Windows 7 64 位。通过谷歌搜索,我没有找到与此类问题相关的任何内容...

提前感谢任何能对此有所了解的人!

皮埃尔。

【问题讨论】:

    标签: scala actor


    【解决方案1】:

    这是因为运行的 scala 脚本一旦在主线程中完成就会硬退出。这在具有多个线程的设置中非常糟糕(请参阅Can Actors in Scala fail to process messages? (example in O'Reilly's Programming Scala))。相反,如果您启动 scala 并像这样加载脚本:

    # scala
    scala> :load testactors.scala
    Loading testactors.scala...
    import scala.actors.Actor
    defined class Redford
    robert: Redford = Redford@29e07d3e
    res0: scala.actors.Actor = Redford@29e07d3e
    
    scala> A lot of what acting is, is paying attention.
    

    【讨论】:

    • 谢谢!确实,它以这种方式工作。请注意,我真的希望能够构建 Scala 脚本,就像我习惯使用 Ruby 脚本一样。即使 Ruby 更适合小型 hack,它也是通过实践学习语言的好方法...
    • 从您的链接看来,同步和等待是可以提供帮助的关键字。我尝试在孩子们的例子中为其中一个孩子添加同步等待,它奏效了。但是,需要等待 2 个孩子导致脚本完全运行但最后挂起。由于我不明白这里到底发生了什么,我想我需要关于这个同步的东西的更多信息(似乎是一个 Java 概念,但我不知道,因为在学习了许多基础知识之后我从未真正使用过 Java几年前)。你认为我会通过阅读 Programming Scala 或其他 Scala 书籍来找到关于这个概念的解释吗?
    • 除了等待其他线程之外,您还必须要求它们停止处理。如果不是,他们将继续等待新消息。您可以通过在退出消息上运行演员退出方法来做到这一点。
    • 谢谢 thoredge。实际上,我还修改了 Kids 示例以在收到 Feed 消息时调用 exit 方法(在打印“对话框”行之后)。当我等待一个演员时,它通常已经收到了 Feed 消息,并且应该调用 exit 方法。然而,这只在我等待其中一个时才有效......好吧,无论如何,我想现在我已经完成了基本示例,我会再学习一点,希望我能尽快理解这一点!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-20
    相关资源
    最近更新 更多