2009-08-16 18 views
9

encontrado el siguiente fragmento de código en la página Closure en wikipediacierres Scala en Wikipedia

//# Return a list of all books with at least 'threshold' copies sold. 
def bestSellingBooks(threshold: Int) = bookList.filter(book => book.sales >= threshold) 
//# or 
def bestSellingBooks(threshold: Int) = bookList.filter(_.sales >= threshold) 

Corrígeme si me equivoco, pero esto no es un cierre? Es una función literal, una función anynomous, una función lambda, pero no un cierre?

+0

¿Por qué threshold es un término cerrado? Es una variable local que es capturada por la función cuando se pasa al método de filtro, ¿no? – skaffman

+0

tienes razón. umbral no es un término cerrado, su variable libre y el cierre es un término abierto. – Schildmeijer

Respuesta

14

Bien ... si quieres ser técnico, este es un literal de función que se traduce en tiempo de ejecución en un cierre, cerrando los términos abiertos (vinculándolos a un val/var en el ámbito de la función literal). Además, en el contexto de esta función literal (_.sales >= threshold), threshold es una variable gratuita, ya que la función literal no le da ningún significado. Por sí mismo, _.sales >= threshold es un término abierto En tiempo de ejecución, está ligado a la variable local de la función, cada vez que se llama a la función.

Tome esta función por ejemplo, la generación de cierres:

def makeIncrementer(inc: Int): (Int => Int) = (x: Int) => x + inc 

En tiempo de ejecución, el código siguiente produce 3 cierres. También es interesante observar que byc no son el mismo cierre (b == c da false).

val a = makeIncrementer(10) 
val b = makeIncrementer(20) 
val c = makeIncrementer(20) 

Sigo pensando que el ejemplo dado en la wikipedia es bueno, aunque no cubre por completo la historia. Es bastante difícil dar un ejemplo de cierres reales por la definición más estricta sin tener realmente un volcado de memoria de un programa en ejecución. Es lo mismo con la relación clase-objeto. Por lo general, da un ejemplo de un objeto definiendo un class Foo { ... y luego instanciando con val f = new Foo, diciendo que f es el objeto.

-- Flaviu Cipcigan

Notas:

  • Referencia: Programación en Scala, Martin Odersky, Lex cuchara, Bill Venners
  • Código compilado con Scala versión 2.7.5.final se ejecuta en Java 1.6.0_14 .
+0

excelente respuesta +1 –

1

No estoy del todo seguro, pero creo que tienes razón. ¿Un cierre no requiere estado (supongo que variables libres ...)?

O tal vez el bookList es la variable gratuita?

+0

"El sistema de inferencia de tipo de Scala reconoce automáticamente el argumento para filtrar para que sea una función que toma un libro y devuelve un valor booleano y lo convierte en un cierre". – Schildmeijer

0

Por lo que yo entiendo, esto es un cierre que contiene un parámetro formal, umbral variable de y contexto, Lista de libros, desde el ámbito que lo contiene. Por lo tanto, el valor de retorno (Lista [Cualquiera]) de la función puede cambiar al aplicar la función de predicado de filtro. Varía según los elementos de la variable List (bookList) del contexto.