Le Espressioni Lambda

Un’espressione lambda è una funzione anonima e top level, ma anche molto simile ad un metodo. Essa fornisce un elenco di parametri formali e un corpo (che può essere un’espressione o un blocco di codice). Abbiamo, quindi, un nuovo approccio al codice, possiamo cioè scrivere codice funzionale: passare funzioni a funzioni così come adesso passiamo oggetti ad oggetti, restituire funzioni da funzioni, come adesso restituiamo oggetti a partire da oggetti ma soprattutto possiamo usare oggetti e funzioni assieme semplificando il codice. Detta così non è ancora chiara la portata della novità, per cui codice, codice, codice! Le espressioni lambda risolvono il problema della verbosità delle classi interne permettendo una riduzione delle linee di codice da scrivere.

La sintassi generale è la seguente:

{ Lista degli argomenti -> Espressione }

Oppure, se neccessitiamo di avere più istruzioni da racchiudere in un blocco di codice:

{ Lista degli argomenti-> {

istruzione1

istruzione2

}}

Per esempio:

  • Espressione che prende in input una stringa e restituisce se stessa concatenata a se stessa: { x: String -> x + x }
  • Espressione che prende in input due interi e restituisce la somma: { x: Int, y: Int -> x + y }
  • Espressione che prende in input una stringa e restituisce la sua lunghezza: { s: String -> s.length }
  • Espressione senza argomenti che restituisce il valore 50: { -> 50 }
  • Espressione che prende in input una stringa e non restituisce nulla:

{ s: String -> {

print("Benvenuto ")

println(s)

}

Si ok, ora sappiamo la sintassi ma cosa c'è ne facciamo? Le assegnamo ad una variabile e la richiamo tramite l'operatore ():

fun main(args: Array<String>) {

val sum = { x: Int, y: Int -> x + y }


println(sum(10,20))

}

Kotlin permette di spostare la dichiarazione dei tipi all'esterno delle espressioni lambda:

fun main(args: Array<String>) {

val sum: (Int, Int) -> Int = { x, y -> x + y }

println(sum(10,20))

}

Se c'è un solo parametro è possibile utilizzate la keyword it: esso è il nome implicito e si può usare solo e solo se la lambda ha un solo parametro, che si chiamerà it, analizzando questo caso ci accorgiamo che entriamo all'interno dei requisiti:

fun main(args: Array<String>) {

val string = "Ciao!"

val doubleString : (String) -> String = {x -> x + x}

println(doubleString(string))

}

Infatti ecco come diventa con la keyword it:

fun main(args: Array<String>) {

val string = "Ciao!"

val doubleString : (String) -> String = {it + it}

println(doubleString(string))

}

Adesso non vediamo l'utilità, ma tranquilli c'è. Le espressioni lambda, a seconda dei casi, si possono ridurre all'osso:

{ x: String -> x + x } può diventare: { x -> x + x } e { it + it }

{ x: Int, y: Int -> x + y } può diventare: { x, y -> x + y }

{ s: String -> s.length } può diventare: { s -> s.length } e { it.length }

{ -> 50 } può diventare: { 50 }

Inoltre è possibile usare l’underscore per le variabili inutilizzate: { , value : String -> println("$value!") }_

Le istruzioni di break e continue non si possono usare all’interno del blocco anche se sono permessi all’interno di cicli. Se il corpo produce un risultato, ogni possibile ramo del flusso del codice deve restituire qualcosa o lanciare un’eccezione.

In questa prima parte della lezione facciamo un unico esempio che andremo via via a modificare introducendo le lambda expression: abbiamo una lista di stringhe e vogliamo stamparla su console. Scriviamo il primo codice che ci viene in mente:

fun main(args : Array<String>) {

val strings = listOf("Lambda ", "expressions ", "are ", "cool")

for (element in strings) {

print(element)

}

}

Questo codice è sicuramente familiare e a colpo d’occhio sappiamo cosa fa. Siamo sicuri però che sia il codice più semplice da scrivere e quello più performante? Prima di procedere riflettiamo per un attimo su quello che abbiamo di fronte, siamo davanti ad un caso di iterazione esterna, cioè stiamo dicendo alla collezione di stringhe: dammi una stringa, poi dammene un’altra e un’altra ancora, è il codice client che chiede alla lista un elemento alla volta e poi decide cosa farne, in pieno stile imperativo.

results matching ""

    No results matching ""