Home Testo Corso Swift Introduzione alle funzioni in Swift

Introduzione alle funzioni in Swift

1643
0
Le-funzioni

In questa lezione iniziamo a parlare di un argomento più complesso. le funzioni in Swift. 

Prima di vedere come creare una funzione in Swift, facciamo un esempio pratico di vita reale così da capire meglio cosa sono.

Le funzioni in Swift o più generalmente in qualsiasi linguaggio di programmazione, formano un blocco di codice che risponde ad un determinato problema. Una funzione esegue del codice per la risoluzione di uno specifico problema.

Faccio l’esempio classico della macchina, essa è composta da tante parti senza le quali la macchina non potrebbe funzionare.

Una funzione puoi considerarla come un pezzo di una macchina. Sai che esiste, sai utilizzarlo ma, all’interno, non sai da cos’è composto. Quando giri la chiave della macchina sai che metterai in moto l’autovettura ma non sai assolutamente qual’è il meccanismo che sta dietro.

La maggior parte degli utilizzatori, non interessa sapere cosa accade nella macchina nel momento in cui viene messa in moto girando la chiave ma si aspettano che essa si metta in moto.

Le funzioni in Swift possiamo considerarle come componenti di una macchina, dove ogni funzione eseguirà un determinato compito.

Prendiamo per esempio un programma per la gestione di un conto, all’operatore non interessa come funziona il programma internamente ma sa e vuole che se clicca sul versamento il risultato finale sia la somma del saldo + quella versata poi come lo fa, dove salva i dati ecc ecc a lui non interessa.

In questo caso quindi la macro problema è la gestione del conto ma possiamo dividerlo come per la macchina in tanti componenti ed ognuno esegue un compito preciso per il raggiungimento dell’obiettivo.

Possiamo creare quindi una funzione per il versamento , una per il prelievo, una per la stampa ecc ecc dove ognuna esegue un compito preciso ma tutte insieme permettono la gestione di un conto.

Ora vediamo in Swift come rappresentare una funzione e come utilizzarla.

func nomeFunzione(<parametri>) -> <uscita> {
     <corpo funzione>
}
Definire una funzione
Facciamo subito un esempio, mettiamo di voler creare una funzione, il quale compito e semplicemente stampare un saluto.
Con il linguaggio Swift, una funzione, viene definita a partire dalla parola chiave func seguita dal nome e da delle parentesi tonde.
func saluto()


Creare corpo della funzione

Ora dobbiamo definire cosa deve fare questa funzione. Dopo le parentesi tonde vanno inserite delle parentesi graffe. All’interno delle graffe viene messo il codice della funzione.

func saluto() {
    print("Ciao, Amico")
}


Chiamare una funzione

Ora la nostra funzione è pronta, per utilizzarla basta richiamarla e rappresenta l’azione vera e propria, un po’ come quando giri la chiave per mettere in moto la macchina. Il corpo della funzione si attiva solamente quando viene chiamata.

Cosa importante è che puoi richiamarla ogni volta che ti serve, esempio mi serve un timbro con la mia firma, creo il timbro con il mio nome e cognome (rappresenta la mia funziona), una volta creato posso utilizzarlo ogni volta che mi serve (chiamata).

Per richiamare una funzione basta scrivere il nome che hai dato alla funzione seguita dalle parentesi tonde.

func saluto() {
    print("Ciao, Amico")
}

saluto() // chiamata di una funzione
saluto() // un'altra chiamata
saluto() // ancora un'altra chiamata

// Il risultato sarà la scritta video di 
// Ciao, Amico, Ciao, Amico, Ciao, Amico

 

Personalizzare una funzione in Swift. I parametri in ingresso ed uscita di una funzione

Nell’esempio precedente abbiamo visto l’utilizzo di una funziona generica chiusa ovvero che come risultato da sempre lo stesso valore “Ciao, Amico”, ma se invece volessi stampare un nome x al posto della scritta “Amico”? la Soluzione è rendere la funzione dinamico utilizzando un parametro in ingresso.

Parametro in ingresso

All’interno delle parentesi tonde di una funzione possiamo definire il tipo di dato in ingresso con cui la funzione lavorerà, nel nostro esempio dovendo inserire un nome sarà di tipo String.

func saluta(nome: String) {
    print("Ciao, \(nome)")
}

Il parametro poi viene utilizzato all’interno del corpo della funzione come se fosse una variabile qualsiasi.

In questo caso il parametro è di tipo :String perché, per il discorso fatto prima, il nome di una persona la rappresenti con le stringhe (può essere qualsiasi tipo di dato).

Ora chiamare una funzione con parametro è pressoché la stessa cosa. All’interno delle parentesi dovrai inserire una variabile o un dato uguale al tipo del parametro della funzione.

Sec prima per richiamare la funzione generica scrivevo saluta() ora dovrò scrivere saluta(“Francesco”).

func salutaPersona(nome: String) {
    print("Ciao, \(nome)") 
}
 
salutaPersona("Francesco")
 
// Oppure posso utilizzare anche un varibile
var mioNome = "Marco"
salutaPersona(mioNome)

// il risultato è uguale in entrambi i casi
// Quindi sarà stampato a video
// nel primo caso Ciao, Francesco
// nel secondo caso Ciao, Marco

Nell’esempio, all’interno delle parentesi tonde ho messo la stringa “Francesco”. Essendo di tipo String viene accettato dalla funzione perché il suo parametro era stato definito come String. La stessa cosa avviene nella chiamata successiva dove viene passata una variabile. Ovviamente il parametro di ingresso deve essere del tipo definito nella funzione altrimenti si crea un errore.

Parametro d’uscita di una funzione

Abbiamo visto nel paragrafo precedente che possiamo definire un tipo di dato in ingresso (che può essere anche più di uno) e che viene utilizzata al suo interno come una variabile locale della funzione stessa, nel nostro caso stampare a video un messaggio.  Ho definito locale perchè una variabile interna ad una funzione nasce e muore al suo interno.

Ma se avessi bisogno di fare uscire il risultato al di fuori di quella funzione per utilizzarlo in altre operazioni?

Facciamo un esempio, abbiamo una macchina per il gelato( la nostra funzione) e come parametri di ingresso i vari ingredienti.

Inserisco gli ingredienti nella macchina(non sapendo essa cosa fa) ma mi aspetto all’uscita una crema gelato che a sua volta posso utilizzarla per mangiarla o usarla per altre operazioni.

Per definire un tipo di uscita ad una funzione in Swift, dopo le parentesi tonde che definiscono il tipo in ingresso, si aggiunge una freccia “->” seguita dal tipo di dato che uscirà dalla funzione.

Riprendendo l’esempio del saluto di una persona posso definire la funzione in questo modo:

func saluta(nome: String) -> String {

 let saluto: String = "ciao \(nome)" 
//creo una stringa con l'unione di ciao + nomePersona
 return saluto //restituisco la stringa creata dentro la func
}

print (saluta("Francesco"))

In questo caso all’interno del corpo della funzione viene utilizzata una parola chiave, return, accennata nella lezione precedente la quale permette di uscire da un blocco di codice restituendo un valore.

In questo caso la funzione prende in valore contenuto nel parametro, lo unisce ad una stringa e ritorna la stringa al mondo esterno.

Il mondo esterno utilizzerà solo il tipo di ritorno fregandosene di tutto quello che accade all’interno della funzione.

Un altro esempio potrebbe essere l’addizione tra 2 numeri, tu inserisci i 2 numeri la funzione calcola e poi fa uscire il risultato che potrai utilizzare per effettuare altre operazioni.

Funzioni con più parametri in ingresso

In questo caso possiamo richiedere anche 2 o più parametri in entrata, tornando all’esempio dell’addizione, creiamo una funzione dove chiediamo 2 numeri in ingresso che restituiscono come risultato la loro somma.

func somma (numero01: Double, numero02: Double) -> Double {
    
  return numero01 + numero02   
}

print ("la somma dei 2 numeri inseriti è: \(somma(numero01:5,numero02:3))")

Funzioni con più parametri in Uscita

Come per i parametri in ingresso che posso essere uno o più di uno anche in uscita potremmo avere la necessità di avere uno più parametri.

func calcoloMinMax(array: [Int] ) -> (min: Int, max: Int) {
    
//setto minimo e massimo uguali al primo valore
    var minimo = array [0] 
    var massimo = array [0]
    
    
    for valore in array {
        
        if valore < minimo {
            minimo = valore
        
        } else if valore > massimo {
            massimo = valore
        }
    }
    
    return (minimo, massimo)
}

let minMax = calcoloMinMax(array: [1,2,3,4,5,6,7,23,8,9])
print("il minimo è \(minMax.min) e il massimo è \(minMax.max)")

In questo esempio ho creato una funzione che ci permette di verificare quale sia il numero minimo e il numero massimo contenuto in una Array di numeri interi.

Quindi in entrata abbiamo in singolo parametro di tipo array e in uscita una tuple contenente 2 valori, minimo e massimo.

Funzioni con più parametri in Entra di tipi inout

Non so se ci hai fatto caso ma fino ad ora nei nostri esempi abbiamo visto che i parametri in ingresso vengo utilizzati per effettuare altre operazioni e restituire più o meno un valore in uscita o eseguire il tutto all’interno della funzione con le funzioni di tipo Void.

Ma se invece avessimo la necessità di modificare il volare del parametro in ingresso?

var a = 2
 
func modifica(variabile: Int) {
   variabile = 4 // Errore!!! Il parametro è considerato come let
}

Se proviamo come nell’esempio il compilatore ci restituisce errore perché il parametro inserito viene considerato come una costante.

Il sistema per modificare il valore del parametro e di conseguenza il valore della variabile esterna è quello di utilizzare il parametro in ingresso come inout, vediamo come:

// Utilizzo parametro inout
var a = 1

func modifica( variabile: inout Int){
    
    variabile += 5
}

modifica(variabile: &a)

print(a) // Uguale a 6

Come puoi vedere ho inserito il parametro inout  prima della definizione del tipo di dato del parametro e quando richiamo la mia funzione prima di indicare la variabile ho inserito una “&”.

Per qualunque dubbio o domanda scrivi un commento in questa lezione.