No entiendo por qué los autores dijeron que el Listado de Código 9.1 de "Programación en Scala" usa el cierre. En el capítulo 9, que muestran cómo refactorizar código en más forma menos duplicada, de este código original:Pregunta sobre el cierre de Scala (de "Programación en 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
}
Para la segunda versión:
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(_))
}
que dijeron que no hay uso de cierre aquí. Ahora entiendo hasta este punto. Sin embargo introdujeron el uso de cierre refactorizar incluso un poco más, se muestra en el Listado 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))
}
Ahora se dice que consulta es una variable libre, pero yo realmente no entiendo por qué dijeron eso? Debido a que "" query "" parece pasar del método superior a la función de coincidencia de cadenas explícitamente.
Am he entendido bien que debido a que el método "coincidencias de" variable de captura de "consulta" por lo tanto, el uso de cierre. – Ekkmanz
Sí, en este código "def filesEnding (consulta: String) = filesMatching (_ endsWith (consulta).)" Hay una lambda "_.endsWith (consulta)", que cuando desazucaradas un poco se parece a "{x => x .endsWith (query)} ". En la notación esquemática se vería como "(lambda (x) (endwith x query))". Como puede ver, en la "consulta" lambda hay una variable gratuita. No está vinculado como un argumento ni con un let en el lambda, por lo que cuando se forma el cierre, la consulta se captura del entorno que lo contiene, p. invocaciones de métodos como "filesEnding". –