Las lambdas son una de las herramientas más potentes en Kotlin, y en cualquier otro lenguaje moderno, ya que permite modelar funciones de forma mucho más sencilla.
La única forma que tenemos de hacer esto en Java 6 es mediante la declaración de interfaces con un único método, y creando objetos anónimos que implemente esas interfaces.
Las lambdas, y sobre todo cómo las lambdas se definen en Kotlin, nos abren un mundo infinito de posibilidades. Iremos viendo algunos de esos casos en siguientes artículos.
Si quieres empezar hoy, te recomiendo que le eches un vistazo a mi training gratuito, donde tendrás una hora y media de contenido para saber cuáles son tus siguientes pasos a dar para convertirte en un experto en Kotlin.
Lambdas en Kotlin
Una lambda es una forma de representar una función, y ya vimos un ejemplo de ello cuando explicábamos el setOnClickListener
:
val view = findViewById(R.id.welcomeMessage) view.setOnClickListener { v -> navigateWithView(v) }
Como ves, en el lado izquierdo se definen los valores de entrada de la función (en este caso una vista v
), y en el lado derecho la operación que realiza dicha función.
Cómo definir una función que acepte lambdas
Si quisiéramos definir nosotros mismos esa función en lenguaje Kotlin, tendríamos lo siguiente:
fun setOnClickListener(listener: (view: View) -> Unit){}
Esto es lo que se conoce como una Higher-Order Function, o función de alto orden, porque es una función que recibe una función por parámetro, o que devuelve una función.
Transformación de apariencia
La forma natural de llamar a esta función sería la siguiente:
view.setOnClickListener({ v -> navigateWithView(v) })
Pero ya hemos visto que hay una forma más compacta de hacer esto, y que además nos ayudará a hacer cosas muy chulas que veremos justo después. ¿A qué se debe esto?
Esto es porque si el último parámetro de una función es a su vez una función, podemos sacarlo de los paréntesis:
view.setOnClickListener(){ v -> navigateWithView(v) }
Pero además, si sólo hay una función como parámetro, nos podemos cargar directamente los paréntesis
view.setOnClickListener { v -> navigateWithView(v) }
Creación de DSLs
Esto nos permite crearnos nuestros propios DSLs, que pueden llegar a crear mini-lenguajes. En la web de referencia de Kotlin hay un ejemplo con HTML, pero aquí vamos a poner uno más sencillo.
Imagina que quieres crear bloques de código que se ejecuten en otro hilo. Podrías tener una función que reciba a su vez la función que queremos ejecutar en segundo plano:
fun doAsync(f: () -> Unit) { Thread({ f() }).start() }
Esta función crea un hilo con un Runnable
que lo único que hace es ejecutar la función que se le pasa por parámetro. Como Runnable
es una clase con un único método en Java, se puede sustituir por una lambda. Luego ejecuta ese hilo.
Ahora en nuestro código podemos crear bloques asíncronos:
doAsync { op1() op2() op3() }
Todo lo que está entre los corchetes se ejecutará en un hilo secundario.
Funciones inline
Lo malo de crear funciones que reciban funciones, es que para ello el compilador necesita crearse clases anónimas. Pero esto se soluciona fácilmente añadiendo la palabra reservada inline
.
Una función inline no consume tantos recursos, puesto que lo que se hará en tiempo de compilación es sustituir esa función por su código en los sitios donde se llame.
La función doAsync
la podemos hacer inline
:
inline fun doAsync(crossinline f: () -> Unit) { Thread({ f() }).start() }
El crossinline
en este caso es necesario porque se está llamando a f()
desde otro contexto de ejecución (otra lambda). No te preocupes, porque el compilador te avisa cuando hace falta usarlo.
Conclusión
Como ves, con las lambdas podemos simplificar mucho nuestro código, e incluso conseguir cosas que antes eran impensables.
Además, la nomenclatura específica de Kotlin hace que podamos crear nuestro propio “lenguaje”, y crear bloques de código con sentido que hagan lo que necesitemos.
Si todo esto te apasiona tanto como a mí, te animo a que te apuntes a mi training gratuito donde te contaré todo lo que necesitas para aprender a crear tus Apps Android en Kotlin desde cero.
Y por cosas como estas me deja de gustar Kotlin, que si quieres que solo haga esto, agregale este parche, que si quieres que en lugar de esto haga esto entonces escribelo asi, entonces ya no escribas esto, entonces ya no es necesario, ahora si es necesario… Por eso prefiero Java, es mucho más consistente … Igual agradezco mucho lo que estoy aprendiendo de Kotlin por tu curso :’3
En realidad es más simple, no me queda claro por qué no te gusta. Supongo que lo dices por que se pueda sacar la lambda de los paréntesis? Esto es una de las cosas más potentes de Kotlin, en cuanto aprendas un poco más te encantará.