Lambdas y Variables función en Kotlin

video[Tutorial Lambdas y variables función en Kotlin

Una expresión Lambda es una subrutina de código a la que normalmente no se ha asignado un identificador.
Una expresión Lambda suele ser pasada como argumento a otra función para parametrizar su ejecución. A la función que recibe como parámetro una expresión Lambda se le conoce como función de orden superior.
La mayoría de lenguajes modernos las incorporan. Java dispone de expresiones Lambdas desde la versión 8.
Una expresión Lambda siempre se escribe entre llaves. Si tiene parámetros estos se escriben al principio seguidos de ->. Veamos algunos ejemplos:

{ toast("Mensaje") }           //Llama aun método
{ x: Int, y: Int -> x + y }    //Suma dos enteros
{ x, y -> x + y }              //Suma dos valores
{ x -> x * 2 }                 //Multiplica por dos
{ it * 2 }                     //Si solo hay un parámetro puede usarse it
{ x, _ -> x * 2 }              //_ indica un parámetro que no usamos 
Una expresión Lambda puede ser pasada como parámetro de una función de orden superior. Veamos primero un ejemplo de función de orden superior:
fun opera(lista: List, valor: Int, funcion:(Int, Int)->Int ): List {
   val result = arrayListOf()
   for (item in lista)
      result.add(funcion(item, valor))
   return result
} 
La función opera tiene tres parámetros una lista, un valor y una funcion.  Se va a recorrer todos los elementos de lista y va a utilizar funcion, para realizar un cálculo de cada elemento de la lista y con valor. El resultado obtenido es almacenado en cada posición de la lista de salida.
Para utilizar opera podríamos declarar primero funcion como una variable:
val funcion =  fun (x: Int, y:Int ):Int = x + y
lista = opera(lista, 2, funcion)  
También podemos usar una función anónima, directamente en el parámetro
lista = opera(lista, 2, fun (x, y):Int = x + y)  
Observa como en este caso ya no es necesario indicar los tipos de x e y. Estos pueden ser inferidos del parámetro que están reemplazando.
Esta función también puede ser declarada usando una expresión Lambda:
val lambda =  { x: Int, y:Int -> x + y }
lista = opera(lista, 2, lambda) 
Pero resulta más legible si utilizamos una expresión Lambda:
lista = opera(lista, 2, { x, y -> x + y }) 
Cuando el último parámetro para una función es una Lambda, esta puede especificarse fuera de paréntesis:
lista = opera(lista, 2) { 
    x, y -> x + y
}  
Como acabamos de ver las expresiones Lambda tienen varias utilidades, pero dentro del ámbito de Android nos van a ser de gran utilidad para escribir el código de los escuchadores de eventos.
Como seguramente ya conozcas, escribir un escuchador en Java es muy laborioso. Se suele crear un objeto anónimo que implementa una interfaz con todos sus métodos. Como puedes ver en el código de la derecha, con Kotlin, va a ser mucho más sencillo:
boton.setOnClickListener(
  new View.OnClickListener(){
    @Override
    public void onClick(View v){
       hazAlgo();
    }
});
boton.setOnClickListener { hazAlgo() } 
Esto es posible gracias a que Kotlin hace la siguiente optimización sobre la librería Java de Android. Cada vez que encuentra un parámetro cuyo tipo es una interfaz con una única función, el método es sobrecargado reemplazando el parámetro por una función:
fuc setOnClickListener( escuchador: (View) –> Unit ) 
Nota: Unit es un tipo con un solo valor, el objeto unidad. Corresponde con void en Java.
Es decir, el parámetro escuchador ha de ser reemplazado por una función o expresión Lambda que tenga como parámetro un objeto View y que no devuelva nada.
Si necesitamos conocer la vista que ha causado el evento, escribiríamos:
boton.setOnClickListener { vista -> hazAlgo(vista) }
Preguntas de repaso: Lambdas