【问题标题】:Sending messages to functions in Scala向 Scala 中的函数发送消息
【发布时间】:2011-07-19 06:36:27
【问题描述】:

我正在研究 Bruce Tate 的 Seven Languages in Seven Weeks,我很难理解他对 sizer.scala 的实现(Scala:第 3 天)。特别是考虑下面的 Singleton 对象

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

下面的方法使用actors计算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? self 是否可以引用函数?
  2. 假设 self 确实 引用 getPageSizeConcurrently,这在 Scala 世界中被认为是相当标准的吗?为什么要将消息发送到函数而不是对象,反之亦然?

更新:有问题的代码只使用了一次 self,但它确实以以下 import 语句开头。

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

查看the Scala API,似乎是the Actor singleton object has a self method。即使这是分配给callerself,但我不明白为什么会执行receive 块。

【问题讨论】:

  • 哪个类或对象将getPageSizeConcurrently 作为其方法之一?
  • @Rex 没有,据我所知。我在这里省略了一些其他方法(以及urls 的定义),但除此之外,这是书中逐字记录的。代码中唯一声明的类或对象是PageLoader,如上图。

标签: scala concurrency actor


【解决方案1】:

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

返回当前执行的actor。应该在演员执行的所有代码块中使用而不是 this。

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

【讨论】:

  • 有趣!那么Actor的self方法返回的主actor线程和上面代码中的匿名actor有区别吗?我会认为“当前执行的演员”实际上是开始的匿名演员之一......
  • 不,没有区别,但是在你调用self的时候,当前执行的actor就是主actor线程。因此,这就是稍后在创建匿名参与者时调用者引用所指向的内容。
  • 啊,当然,这是有道理的。所以下面对receive 的调用是在主角线程上隐式调用的,对吧?
  • 我认为隐式调用是不正确的,因为这可能被解释为隐含在这个词的特殊 scala 意义上。 “receive”是一个普通的方法调用,就像“self”一样,在同一个主线程中调用,是的。
【解决方案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。因此,实际上,您可以向函数(函数对象,而不是方法)发送消息。但是语法不会'看起来不像你上面的。)

【讨论】:

  • 感谢您为我指明正确的方向!您猜对了,我认为 self 是 Scala 关键字。我已更新我的问题以纳入这些新信息。
【解决方案3】:

虽然 Actor 不像在早期版本的 Scala 中那样绑定到线程,但 selfThread.current 相当。您使用它,因为Thread.current 没有必要的方法来将当前线程视为参与者。

“哪个类或对象将 getPageSizeConcurrently 作为其方法之一?” - Rex Kerr

“没有,据我所知……” - Chris

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

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

【讨论】:

    猜你喜欢
    • 2021-10-14
    • 1970-01-01
    • 2019-02-14
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    • 2015-07-13
    • 2014-04-25
    • 1970-01-01
    相关资源
    最近更新 更多