Si bien las características utilizadas no son poco comunes, voy a admitir que es una combinación bastante extraña de características. El truco básico es que cualquier bloque en Scala es una expresión, con tipo igual a la última expresión en el bloque. Si esa última expresión es una función, esto significa que el bloque tiene un tipo funcional y, por lo tanto, puede usarse como argumento para "mapear" o "llegar". Lo que sucede en estos casos es que cuando se llama "mapa" o "foreach", se evalúa el bloque. El bloque evalúa una función (i => i * 5 en el primer caso), y esa función luego se mapea sobre el rango.
Un posible uso de esta construcción es que el bloque defina variables mutables, y la función resultante mute las variables cada vez que se llame. Las variables serán inicializadas una vez, cerradas por la función, y sus valores actualizados cada vez que se llame a la función.
Por ejemplo, aquí está una manera un tanto sorprendente de cálculo de los primeros 6 números factoriales
(1 to 6) map {
var total = 1
i => {total *= i;total}
}
(Por cierto, lo siento por el uso factorial como un ejemplo. Era eso o funcionales reglas Progamming del gremio de Fibonacci.. Tienes problema con eso, tómalo con los chicos en la sala.)
Una razón menos imperativa para tener una función de retorno de bloque es definir las funciones auxiliares antes en el bloque. Por ejemplo, si su segundo ejemplo eran lugar
(1 to 3) foreach {
def line = Console.readLine
i => println(line)
}
El resultado sería que las tres líneas se lee y se hizo eco una vez cada uno, mientras que su ejemplo tenía la línea lee una vez y se hizo eco de tres veces.
Respuesta mucho más precisa que la mía. +1 – VonC
En el ejemplo factorial, debe usar 'total * = i' en lugar de introducir una segunda variable llamada' contador' –
Sí, me di cuenta más tarde. Editará –