Non capisco perché gli autori dicano che il Codice 9.1 da "Programmazione in Scala" utilizza la chiusura. Nel capitolo 9, che mostrano come il refactoring del codice in più forma meno duplicato, da questo codice originale:Domanda su Scala Closure (da "Programmazione in 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
}
Per la seconda versione:
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(_))
}
che hanno detto che non c'è nessun uso di chiusura Qui. Ora capisco fino a questo punto. Tuttavia hanno introdotto l'uso di chiusura di refactoring anche un po 'di più, mostrato nel Listato 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))
}
Ora hanno detto che interrogazione è una variabile libera, ma io non capisco il motivo per cui hanno detto così? Poiché "" query "" sembra essere passato esplicitamente dal metodo top down alla funzione di corrispondenza delle stringhe.
Sono a conoscenza del fatto che, poiché il metodo "matcher" acquisisce la variabile "query", quindi utilizza la chiusura. – Ekkmanz
Sì, in questo codice "def filesEnding (query: String) = filesMatching (_. EndsWith (query))" c'è un lambda "_.endsWith (query)" che quando desugared assomiglia a "{x => x .endsWith (query)}". Nella notazione schematica sembrerebbe "(lambda (x) (endwith x query))". Come puoi vedere, nella "query" lambda è una variabile libera. Non è vincolato come argomento né con una let in lambda, quindi quando la chiusura è formata la query viene catturata dall'ambiente di contenimento, ad es. invocazioni di metodi come "filesEnding". –