将消息发送到Scala中的函数

时间:2011-07-19 06:36:27

标签: scala concurrency actor

我正在通过Bruce Tate的Seven Languages in Seven Weeks工作,并且很难理解他对sizer.scala(Scala:第3天)的实施情况。特别要考虑以下Singleton对象

object PageLoader {
    def getPageSize(url : String) = Source.fromURL(url).mkString.length
}

以下方法,使用actor计算urls数组给出的每个网页中的字符数。

def getPageSizeConcurrently() = {
    val caller = self

    for(url <- urls) {
        actor { caller ! (url, PageLoader.getPageSize(url)) }
    }

    for(i <- 1 to urls.size) {
        receive {
            case (url, size) =>
                println("Size for " + url + ": " + size)
        }
    }
}
  1. self 是指什么? getPageSizeConcurrently自我是否可以引用某个功能?
  2. 假设 self 确实引用getPageSizeConcurrently,这在Scala世界中被认为是非常标准的吗?为什么要将消息发送到函数而不是对象,反之亦然?
  3. 更新:相关代码仅使用 self 一次,但确实以下列import语句开头。

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

    通过the Scala API查看the Actor singleton object has a self method。即使这是分配给self的{​​{1}},我也不明白为什么caller块会被执行。

3 个答案:

答案 0 :(得分:4)

Actor伴侣对象上有一个self方法。来自scaladoc

  

返回当前正在执行的actor。应该在演员执行的所有代码块中使用它代替。

我猜你的代码已经导入了Actor对象,并且它是你的代码正在调用的Actor对象上的self方法。通过这种方式,您可以获得对所在主动作线程的引用,并且您开始获取页面大小的匿名actor可以将消息发送回您所在的线程。

答案 1 :(得分:2)

self不是Scala关键字。

虽然我没有这本书,但Scala课程允许自己使用别名;通常会选择self。这就是您可能想要这样做的原因(不计算您在指定别名时可以限制类的类型):

class A {
  self =>
  val a = 7
  class B {
    val a = 7             // Uh-oh, we've shadowed the parent class a.
    val outerA = self.a   // Whew, we haven't lost it!
  }
}

因此,self几乎肯定是实现getPageSizeConcurrently方法的类。

在没有看到更多代码的情况下,我没有深入了解为什么它以这种方式编写(对我来说有点奇怪)。但是这里没有奇怪的消息传递方法。

(顺便提一下,请注意,正式可以定义扩展Function特征的actor。事实上,你可以向函数发送消息(函数对象,而不是方法)。但是语法看起来不像你上面的那样。)

答案 2 :(得分:1)

虽然演员没有像早期版本的Scala那样绑定线程,但selfThread.current相当。你使用它,因为Thread.current没有必要的方法来查看作为actor的当前线程。

“什么类或对象将getPageSizeConcurrent当作其方法之一?” - Rex Kerr

“就我所知,没什么......” - Chris

我假设self尝试将当前线程视为演员。

注意:在REPL中使用self时要小心。