Я не понимаю, почему авторы сказали, что в листинге 9.1 из «Программирование в Scala» используется закрытие. В главе 9, они показывают, как реорганизовать код в более менее дублированные формы, от этого оригинального кода:Вопрос о закрытии Scala (от «Программирование в Scala»)
object FileMatcher {
private def filesHere = (new java.io.File(".")).listFiles
def filesEnding(query: String) =
for (file <- filesHere; if file.getName.endsWith(query))
yield file
def filesContaining(query: String) =
for (file <- filesHere; if file.getName.contains(query))
yield file
def filesRegex(query: String) =
for (file <- filesHere; if file.getName.matches(query))
yield file
}
Для второй версии:
object FileMatcher {
private def filesHere = (new java.io.File(".")).listFiles
def filesMatching(query: String,
matcher: (String, String) => Boolean) = {
for (file <- filesHere; if matcher(file.getName, query))
yield file
}
def filesEnding(query: String) =
filesMatching(query, _.endsWith(_))
def filesContaining(query: String) =
filesMatching(query, _.contains(_))
def filesRegex(query: String) =
filesMatching(query, _.matches(_))
}
Что они сказали, что нет никакого смысла закрытия Вот. Теперь я понимаю до этого момента. Однако они ввели использование закрытия реорганизовать даже немного, показанную в листинге 9.1:
object FileMatcher {
private def filesHere = (new java.io.File(".")).listFiles
private def filesMatching(matcher: String => Boolean) =
for (file <- filesHere; if matcher(file.getName))
yield file
def filesEnding(query: String) =
filesMatching(_.endsWith(query))
def filesContaining(query: String) =
filesMatching(_.contains(query))
def filesRegex(query: String) =
filesMatching(_.matches(query))
}
Теперь они сказали, что запрос является свободным переменным, но я действительно не понимаю, почему они так сказали? Так как «запрос» «кажется, передается от верхнего метода до функции сопоставления строк явно.
Я правильно понял, что, поскольку метод «сопоставления» захватывает переменную «запрос», поэтому она использует закрытие. – Ekkmanz
Да, в этом коде «def filesEnding (query: String) = filesMatching (_. EndsWith (query))« есть лямбда »_.endsWith (query)», который при уменьшении бит выглядит «{x => x .endsWith (запрос)}». В обозначениях схемы будет выглядеть «(lambda (x) (endwith x query))». Как вы можете видеть, в лямбда-запросе есть свободная переменная. Он не связан как аргумент или с let в лямбда, поэтому, когда замыкание сформировано, запрос захватывается из среды, содержащей среду, например. вызовы таких методов, как «filesEnding». –