Scala _ Заполнители (Как работает этот код?) - PullRequest
6 голосов
/ 30 июля 2011

Я изучаю Scala (в основном из Java). Я пытаюсь обернуть голову вокруг следующего кода:

object Main {
  def main(args : Array[String]) {
    for (file <- filesEnding(".txt"))
      println(file.getName)
  }

  private val filesHere = (new java.io.File(".")).listFiles

  def filesMatching(matcher: String => Boolean) =
    for (file <- filesHere; if matcher(file.getName))
        yield file

  def filesEnding(query: String) = filesMatching(_.endsWith(query))
  /* Other matcher functions */
}

В частности, я запутался, когда Scala получает значение для _ в каждой из функций сопоставления. Я вижу, что filesEnding вызывается с аргументом .txt. Этот аргумент присваивается query. filesEnding затем вызывает filesMatching с аргументом, согласующимся с функцией String => Boolean. Наконец, я вижу, что file.getName - это то, что в конечном итоге заменяет заполнитель _.

Что я не понимаю, так это то, как Скала знает, как поставить file.getName вместо _. У меня возникают проблемы с отслеживанием этого кода в моей голове, и отладчик затмения не очень помогает в этой ситуации. Может кто-нибудь рассказать мне, что происходит в этом коде?

Ответы [ 2 ]

17 голосов
/ 30 июля 2011

_ - это просто сокращение для создания анонимной функции:

_.endsWith(query)

аналогично анонимной функции

fileName => fileName.endsWith(query)

Эта функция затем подается в качестве аргумента от matcher до filesMatching. Внутри этой функции вы можете увидеть вызов

matcher(file.getName)

Это вызывает анонимную функцию с file.getName в качестве аргумента _ (который я назвал fileName в явном примере).

13 голосов
/ 30 июля 2011

Если вы пишете _.someMethod(someArguments), это десугар до x => x.someMethod(someArguments), поэтому filesMatching(_.endsWith(query)) десугар до filesMatching(x => x.endsWith(query)).

Таким образом, filesMatching вызывается с matcher, являющимся функцией x => x.endsWith(query), то есть функцией, которая принимает один аргумент x и вызывает x.endsWith(query) для этого аргумента.

...