【发布时间】:2014-02-21 17:46:46
【问题描述】:
我正在使用 Akka 调度程序来错开列表中消息的发送,该列表是通过读取文件的行而构建的。这是一些代码:
def startClock {
val filename = "conf/my_file.json"
val lines = scala.io.Source.fromFile(filename).getLines.toList
var linePtr = 0
if(linePtr == lines.length) {
clock.cancel()
}
else {
Logger.info(s"num: $linePtr")
default ! Message(lines(linePtr))
linePtr = linePtr + 1
}
}
lazy val clock: Cancellable = Akka.system.scheduler.schedule(Duration.Zero, Duration.create(5000, TimeUnit.MILLISECONDS))(startClock)
val x = clock
现在为了解决前向引用编译器错误,如下所示:play.PlayExceptions$CompilationException: Compilation error[forward reference extends over definition of value clock]
我必须将时钟设置为lazy,然后在下一行引用它以触发startClock,它可以很好地完成这部分。我在这里遇到的问题是,linePtr 始终是0。它永远不会增加,但else {} 块中的代码被确认总是命中。我基本上在这里只有无限递归,而且我对 Scala 不够熟悉,无法确定我在这里做错了什么。我也尝试在startClock 之前定义val clock,但是在反向场景中我也有一个前向引用。这里似乎是鸡和蛋的问题。
【问题讨论】:
-
我可以看到的一个问题是
linePtr被定义为startClock函数的本地。每次调度程序调用startClock时,它总是将linePtr设置为0,这就是它总是命中你的else 语句的原因。如果您想正确递增,那么您可能应该在startClock函数之外定义filename、lines和linePtr。这将是混乱的代码,因为它非常“副作用”,但对于您想要做的事情来说,这将是朝着正确方向迈出的一步。
标签: scala playframework akka