「Scalaのプログラミング」のコードリスト9.1がクロージャを使用している理由を著者が言った理由はわかりません。Scala Closureに関する質問(「Scalaのプログラミング」から)
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(_))
}
彼らは閉鎖のない使用がないことを言った:第二版に
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
}
:第9章では、彼らはこの元のコードから、より少ない重複フォームにコードをリファクタリングする方法を示していますここに。今私はこの点まで理解しています。しかし彼らは、リスト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))
}
を今、彼らはクエリは自由変数であるが、彼らはそう言った理由は、私は本当に理解していないと言いましたか? ""クエリ ""はトップメソッドから文字列マッチング関数に明示的に渡されているようです。
"matcher"メソッドは変数 "query"をキャプチャするため、クロージャを使用するため、正しく理解していますか? – Ekkmanz
はい、このコードでは、 "def filesEnding(query:String)= filesMatching(_。endsWith(query))"という名前のラムダ "_.endsWith(query)"があります。 .endsWith(クエリ)} " schemey表記では、 "(lambda(x)(endwith x query))"のようになります。あなたが見ることができるように、ラムダ "クエリ"は自由変数です。それは引数としてもラムダのletでもバインドされていないので、クロージャが形成されるときに、クエリーが格納環境からキャプチャされます。 "filesEnding"のようなメソッドの呼び出し。 –