Una funció lambda (o expressió lambda) és una funció anònima, és a dir, una funció que es defineix sense un nom explícit i que es pot tractar com un valor: assignar-la a una variable, passar-la com a argument, retornar-la d’una altra funció o desar-la en una estructura de dades. Sovint també capturen variables del context on es defineixen, cosa que les converteix en clausures (closures).
Una interfície funcional és un concepte de Java (formalitzat a Java 8) que designa una interfície amb un únic mètode abstracte. Això permet que una expressió lambda, una referència a mètode o una classe anònima la puguin implementar directament, sense necessitat de crear una classe completa.
Actualment les funcions lambda ens resulten molt útils per implementar interfícies funcionals de forma concisa i llegible. En desenvolupaments amb moltes callbacks com en les interfícies gràfiques en general, i Android en particular, son molt pràctiques per reduir el codi.
Característiques principals:
Sintaxi bàsica en Java:
(paràmetres) -> { cos de la funció }
Sintaxi bàsica en Kotlin:
{ paràmetres -> cos de la funció }
Per implementar una callback en un botó ens cal crear un objecte View.OnClickListener i particularitzar (sobreescrivint) la funció onClick, que és l'únic mètode abstracte que té. Per tant, la lambda, sense explicitar-ho farà referència a aquest mètode.
Aquest seria el codi explícit per a Android en Java, creant l'objecte OnClickListener i sobreescrivint la seva funció onClick:
Button myButton = findViewById(R.id.my_button); myButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Codi a executar quan es fa clic Toast.makeText(MainActivity.this, "Clic rebut!", Toast.LENGTH_SHORT).show(); } });
Si ho implementem en versió lambda ens quedaria molt mes concís:
Button myButton = findViewById(R.id.my_button); myButton.setOnClickListener(v -> { // Codi a executar quan es fa clic Toast.makeText(MainActivity.this, "Clic rebut!", Toast.LENGTH_SHORT).show(); });
Podem utilitzar punters a MainActivity (MainActivity.this) sempre que implementem aquest codi a dins d'ella, que és el més habitual. Aquest codi en concret sol estar dins el mètode MainActivity.onCreate.
La definició explícita, sense lambda, seria aquesta:
val myButton = findViewById<Button>(R.id.my_button) myButton.setOnClickListener ( object : View.OnClickListener { override fun onClick(v : View?) { Toast.makeText(this@MainActivity, "Clic rebut!", Toast.LENGTH_SHORT).show() } })
La peculiaritat en Kotlin és que una interfície com View.OnClickListener s'instancia amb object : View.OnClickListener, sense parèntesis (com sí que es fa en Java).
Si emprem lambda:
val myButton = findViewById<Button>(R.id.my_button) myButton.setOnClickListener { v -> Toast.makeText(this@MainActivity, "Clic rebut!", Toast.LENGTH_SHORT).show() }
En kotlin, fins i tot podriem eliminar el paràmetre v → si no el fem servir (com en aquest cas).