Вопрос: Отправка сообщений в функции Scala


Я прокладываю себе путь через Брюса Тейта Семь языков за семь недель  и я с трудом понимаю его реализацию sizer.scala (Скала: День 3). В частности, рассмотрим следующий объект Singleton

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

и следующий метод, который, используя участников, вычисляет количество символов на каждой веб-странице, заданную 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. Что значит сам  Ссылаться на? getPageSizeConcurrently? Возможно ли это для сам  обратиться к функции?
  2. При условии, что сам   делает  Ссылаться на getPageSizeConcurrently, считается ли это довольно стандартным в мире Scala? Зачем отправлять сообщения функции вместо объекта или наоборот?

ОБНОВИТЬ:  В рассматриваемом коде используется только сам  один раз, но он начинается со следующего import заявления.

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

Просматривая API Scala , кажется, что Actor Объект singleton имеет self метод , Даже если это self присвоенный caller, однако, я не понимаю, почему receive блок будет выполнен.


5


источник


Ответы:


Существует собственный метод на объекте компаньона Актера. Из scaladoc :

Возвращает действующего исполнителя. Следует использовать вместо этого во всех блоках кода, исполняемых участниками.

Я предполагаю, что ваш код импортировал объект Actor и что это сам метод на объекте Actor, который вызывает ваш код. Таким образом вы получите ссылку на основную тему вашего актера, и анонимные актеры, с которых вы начинаете получать размер страницы, можете отправить сообщение обратно в поток, в котором вы находитесь.


4



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 черта. Таким образом, вы могли фактически послать сообщение функции (объект функции, а не метод). Но синтаксис не будет похож на то, что вы получили выше.)


2



Хотя актеры не привязаны к нитям, как в ранних версиях Scala, self сопоставим с Thread.current, Вы используете его, потому что Thread.current не имеет необходимых методов для просмотра текущего потока в качестве актера.

«Какой класс или объект имеет getPageSizeConcurrently как один из его методов?»  - Рекс Керр

«Ничего, насколько я могу судить ...»  - Крис

Я предполагаю self пытается рассматривать текущую нить как актера.

Примечание: будьте осторожны при использовании selfв REPL.


1