Vai al contenuto

CLOSURES

Cosa imparerò:

  • Cosa sono le closures
  • sorted()
  • map()
  • filter()
  • reduce()

Le closures in Swift sono blocchi di codice autocontenuti che possono essere assegnati a variabili e passati come parametri ad altre funzioni. Possono catturare e conservare riferimenti al loro stato circostante, rendendole estremamente flessibili e potenti.

Come le funzioni le closure possono avere parametri in entrata, in uscita o nessuno in entrambi i casi:

let closureSenzaParametri: () -> Void = {
    print("Questa è una closure senza parametri")
}
//Questa è una closure con parametri e valore restituito
let closureConParametri: (Int, Int) -> Int = { (a, b) in
    return a + b
}
//Questa è una closure con valore restituito
let closureConValoreDiUscita: () -> Int = {
    return 42
}
//Questa è una closure con parametro
let closureConParametro: (String) -> Void = { nome in
    print("Ciao, \(nome)!")
}

Si possono passare closure come argument di una funzione per esempio nella funzione sorted(by:)

let array = ["arancia", "fragola", "mela", "banana",]
let sortedArray = array.sorted(by: { (str1, str2) in
    return str1.count < str2.count
})
print(sortedArray)

Output

["mela", "banana", "arancia", "fragola"]

Con la Additional Syntactic Sugar possiamo rendere più leggibile ed espressivo il nostro codice:

// Utilizzo della funzione sorted(by:) con sintassi abbreviata
let sortedArray2 = array.sorted { $0.count < $1.count }
print(sortedArray2)

Output

["mela", "banana", "arancia", "fragola"]

La trailing closure syntax è una caratteristica di Swift che consente di spostare una closure fuori dalle parentesi tonde alla fine di una funzione, migliorando la leggibilità del codice.

func greet(name: String, completion: () -> Void) {
    print("Ciao, \(name)!")
    completion()
}
// Utilizzo della trailing closure syntax
greet(name: "Marco") {
    print("Buona giornata!")
}

Output

Buona giornata!

Swift include alcune funzioni per iterare sugli elementi di una collezione, che prendono una closure come argument per definire delle azioni.

La funzione map() permette di applicare una trasformazione ad ogni elemento di una sequenza, restituendo una nuova sequenza contenente i risultati della trasformazione.

let names = ["marco", "paolo", "giulia", "anna"]
// Utilizzo della funzione map() per convertire i nomi in maiuscolo
let capitalizedNames = names.map { $0.capitalized }
print(capitalizedNames)

Output

["Marco", "Paolo", "Giulia", "Anna"]

Lo $0 in una closure rappresenta il primo parametro di input passato alla closure stessa. In pratica, è un modo conciso per riferirsi al primo parametro senza doverlo nominare esplicitamente.

La funzione filter() permette di filtrare gli elementi di una sequenza basandosi su un dato criterio, restituendo un nuovo array contenente solo gli elementi che soddisfano il criterio di filtraggio.

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// Utilizzo della funzione filter() per filtrare i numeri pari
let evenNumbers = numbers.filter { $0 % 2 == 0 }
print(evenNumbers)

Output

[2, 4, 6, 8, 10]

La funzione reduce() permette di combinare tutti gli elementi di una sequenza in un unico valore, applicando una determinata operazione di riduzione.

let numbers2 = [1, 2, 3, 4, 5]
// Utilizzo della funzione reduce() per calcolare la somma degli elementi dell'array
let sum = numbers2.reduce(0) { $0 + $1 }
print(sum)

Output

15

Questi metodi, map, filter e reduce non modificano la collezione originale, ma ne producono una nuova.