Swift From Scratch Introduzione alle funzioni

Per fare qualcosa in Swift, devi imparare i dettagli delle funzioni. Le funzioni sono straordinariamente potenti e flessibili in Swift. Le basi sono semplici, specialmente se hai già lavorato con altri linguaggi di programmazione. Ma a causa della sintassi flessibile di Swift, le funzioni possono diventare confuse se non si ha familiarità con le basi. 

In questo articolo, ci concentriamo innanzitutto sulle basi. Poi andremo a esplorare la sintassi più complessa e casi d'uso nel prossimo articolo. È importante non scremare le basi perché sono essenziali per capire da dove viene il potere di una funzione. Iniziamo con la dissezione dell'anatomia di una funzione in Swift con un esempio.

1. Impara dall'esempio

Una funzione non è altro che un blocco di codice che può essere eseguito ogni volta che è necessario. Diamo un'occhiata ad un esempio dell'anatomia di base di una funzione Swift. Accendi Xcode e crea un nuovo parco giochi. Aggiungi la seguente definizione di funzione al campo da giuoco.

func printHelloWorld () print ("Hello World!")

Una funzione inizia con func parola chiave ed è seguito dal nome della funzione, printHelloWorld nel nostro esempio. Come in molti altri linguaggi, il nome della funzione è seguito da una coppia di parentesi che contengono i parametri della funzione: l'input della funzione.

Il corpo della funzione è avvolto in un paio di parentesi graffe. Il printHelloWorld () la funzione contiene una singola istruzione che stampa la stringa Ciao mondo! allo standard output. Ecco come appare una funzione di base in Swift. La sintassi è semplice, pulita e minimalista.

È possibile richiamare la funzione digitando il nome della funzione, seguito da una coppia di parentesi.

printHelloWorld ()

2. Parametri

Rendiamo l'esempio sopra un po 'più complesso aggiungendo parametri alla definizione della funzione. Ciò significa semplicemente che forniamo alla funzione valori di input che può utilizzare nel corpo della funzione. Nell'esempio seguente, definiamo il printMessage (messaggio :) funzione, che accetta un parametro, Messaggio, di tipo Stringa.

func printMessage (message: String) print (messaggio)

Una funzione può accettare più parametri o valori di input. I parametri sono racchiusi tra parentesi che seguono il nome della funzione. Il nome del parametro è seguito da due punti e dal tipo del parametro. Come ricordi, è molto simile alla dichiarazione di una variabile o di una costante. Semplicemente dice che il Messaggio il parametro è di tipo Stringa.

Invece di stampare una stringa hard-coded come abbiamo fatto nel printHelloWorld () funzione, stampiamo il Messaggio il valore del parametro. Questo rende la funzione flessibile e più utile.

Invocare la funzione è molto simile a ciò che abbiamo visto in precedenza. L'unica differenza è che passiamo a un argomento quando invochiamo la funzione.

printMessage (messaggio: "Hello World!")

Si noti che i termini parametri e argomenti sono spesso usati in modo intercambiabile, ma c'è una sottile differenza semantica in Swift. In Swift, i parametri sono i valori specificati nella definizione della funzione, mentre gli argomenti sono i valori passati alla funzione quando viene richiamata.

Parametri multipli

Come accennato in precedenza, la sintassi delle funzioni è molto flessibile e non dovrebbe sorprendere che sia perfettamente possibile passare più argomenti a una funzione. Nel prossimo esempio, creiamo una variazione su printMessage (message: volte :) funzione che ci consente di stampare il messaggio più volte.

func printMessage (message: String, times: Int) per i in 0 ... 

Mentre il nome della funzione è identico a quello dell'originale printMessage (messaggio :) funzione, il tipo di funzione è diverso. 

È importante che tu capisca la frase precedente. Leggi di nuovo.

Ogni funzione ha un tipo, costituito dai tipi di parametri e dal tipo di ritorno. Esploreremo i tipi di ritorno in un attimo. Le funzioni possono avere lo stesso nome purché il loro tipo sia diverso, come mostrato dalle precedenti due definizioni di funzione.

Il tipo della prima funzione è (Stringa) -> (), mentre il tipo della seconda funzione è(String, Int) -> (). Il nome di entrambe le funzioni è lo stesso. Non preoccuparti per il -> simbolo. Il suo significato diventerà chiaro in alcuni momenti in cui discuteremo dei tipi di ritorno.

Il secondo printMessage (message: volte :) la funzione definisce due parametri, Messaggio di tipo Stringa e volte di tipo Int. Questa definizione illustra una delle caratteristiche che Swift ha adottato da Objective-C, funzione leggibile e nomi di metodi. Mentre il nome della funzione è printMessage, è facile capire cosa dovrebbe fare la funzione leggendo i nomi dei parametri della funzione.

Nel secondo printMessage (message: volte :) funzione, creiamo a per-nel loop per stampare il Messaggio stringa volte volte. Usiamo l'operatore della gamma semiaperta, ... <, come abbiamo visto in precedenza in questa serie.

Quando iniziamo a digitare printMessage nel parco giochi, Xcode visualizza entrambe le funzioni nel menu di completamento automatico. Grazie al tipo di funzione, è facile scegliere la funzione a cui siamo interessati. Chiamare il secondo printMessage (message: volte :) la funzione è semplice come:

printMessage (messaggio: "Hello World", orari: 3)

Valori standard

Una delle mie caratteristiche preferite è la possibilità di definire i valori predefiniti per i parametri. Questo può sembrare sciocco se provieni da una lingua che ha avuto questa funzione per anni, ma questo è molto bello se hai lavorato con C e Objective-C per molti anni.

In breve, Swift consente agli sviluppatori di definire i valori predefiniti per i parametri di una funzione. Definiamo una nuova funzione che stampa la data corrente in un formato specifico. Assicurati di aggiungere la seguente istruzione di importazione nella parte superiore del tuo parco giochi per importare il framework UIKit.

importa UIKit

Iniziamo a definire il PrintDate (data: formato :) funzione senza utilizzare i valori predefiniti per nessuno dei parametri.

func printDate (date: Date, format: String) let dateFormatter = DateFormatter () dateFormatter.dateFormat = format print (dateFormatter.string (from: date))

Se non hai familiarità con il framework Foundation e non capisci cosa sta succedendo nel corpo della funzione, allora va bene. L'obiettivo di questo esempio non è l'implementazione della formattazione di una data. Nel PrintDate (data: formato :), usiamo il valore del formato parametro per formattare il valore di Data. Se non passiamo in un valore per il formato parametro, il compilatore genera un errore.

Possiamo rimediare definendo un valore predefinito per il secondo parametro della funzione, come mostrato nella seguente definizione di funzione aggiornata.

func printDate (data: Date, format: String = "YY / MM / dd") let dateFormatter = DateFormatter () dateFormatter.dateFormat = format print (dateFormatter.string (from: date))

La definizione di un valore predefinito è semplice come specificare un valore nell'elenco di parametri nella definizione della funzione. Il risultato è che il compilatore non si lamenta più e l'errore scompare.

printDate (date: Date ())

Anche se abbiamo specificato un valore predefinito per formato parametro, possiamo ancora passare un valore se vogliamo.

printDate (data: Date (), formato: "dd / MM / YY")

Nota che Apple consiglia di posizionare i parametri con un valore predefinito alla fine dell'elenco di parametri. Questa è certamente una buona idea e comune nella maggior parte degli altri linguaggi di programmazione che supportano i parametri opzionali.

3. Tipo di reso

Le funzioni che abbiamo visto finora non ci restituiscono nulla quando le invochiamo. Facciamo il PrintDate (data: formato :) funzione più utile restituendo la data formattata come una stringa, invece di stampare la data formattata nel corpo della funzione. Ciò richiede due cambiamenti, come puoi vedere di seguito.

func printDate (data: Date, format: String = "YY / MM / dd") -> String let dateFormatter = DateFormatter () dateFormatter.dateFormat = format return dateFormatter.string (from: date)

La prima cosa che cambiamo è la definizione della funzione. Dopo l'elenco dei parametri, specifichiamo il tipo di ritorno, Stringa. Il tipo di ritorno è preceduto dal -> simbolo. Se hai lavorato con CoffeeScript, questo sembrerà familiare.

Invece di stampare la data formattata usando il stampa (_: separatore: Terminator :) funzione, usiamo il ritorno parola chiave per restituire il valore dalla funzione. Questo è tutto ciò che dobbiamo fare. Proviamolo.

let formattedDate = printDate (data: Date (), formato: "dd / MM / YY") print (formattedDate)

Invochiamo il PrintDate (data: formato :) funzione, memorizza il valore restituito nella costante formattedDate, e stampare il valore di formattedDate nell'output standard. Si noti che il nome del PrintDate (data: formato :) la funzione non riflette più ciò che fa, quindi potresti volerlo cambiare FormatoData anziché.

Nessun tipo di reso

Le altre funzioni che abbiamo definito in questo tutorial non avevano un tipo di ritorno. Quando una funzione non ha un tipo restituito, non è necessario includere il -> simbolo nella definizione della funzione.

Qualche paragrafo prima, ti ho detto che nessuna delle funzioni che avevamo definito ci restituiva un valore. Questo in realtà non è del tutto vero. Lascia che ti spieghi i dettagli nitidi con un esperimento. Aggiungi la seguente riga al tuo parco giochi e guarda cosa succede.

Questo è interessante. Swift non ha un problema che memorizziamo il valore di ritorno del printHelloWorld () funzione in una costante, ma ci avvisa che il tipo di valore restituito non è quello che potremmo pensare che sia.

Cosa sta succedendo qui? Ogni funzione in Swift restituisce un valore, anche se non definiamo un tipo di ritorno nella definizione della funzione. Quando una funzione non specifica esplicitamente un tipo di ritorno, la funzione restituisce implicitamente vuoto, che è equivalente a una tupla vuota, o () in breve. Puoi vederlo nel riquadro di output del playground e viene anche menzionato nell'avvertimento delle uscite del compilatore.

Possiamo sbarazzarci di questo avviso dichiarando esplicitamente il tipo di valore, una tupla vuota. Sono d'accordo che non è molto utile memorizzare una tupla vuota in una costante, ma ti illustra che ogni funzione ha un valore di ritorno.

let value: () = printHelloWorld ()

Le tuple

Un'altra grande caratteristica di Swift è la possibilità di restituire più valori da una funzione restituendo una tupla. Il seguente esempio illustra come funziona. Permettetemi di ripetere che non è importante capire come timeComponentsForDate (data :) la funzione fa il suo lavoro. Il focus è il valore di ritorno della funzione, una tupla con tre elementi.

func timeComponentsForDate (_ date: Date) -> (hour: Int, minute: Int, second: Int) let dateComponents = Calendar.current.dateComponents ([. hour, .minute, .second], from: date) let ora = dateComponents.hour let minute = dateComponents.minute let second = dateComponents.second return (hour ?? 0, minute ?? 0, second ?? 0)

La funzione accetta un argomento, a Data istanza e restituisce una tupla con tre valori etichettati. Etichettare i valori della tupla è solo per comodità; è possibile omettere le etichette.

func timeComponentsForDate (_ date: Date) -> (Int, Int, Int) let dateComponents = Calendar.current.dateComponents ([. hour, .minute, .second], da: date) let hour = dateComponents.hour let minute = dateComponents.minute let second = dateComponents.second return (hour ?? 0, minute ?? 0, second ?? 0)

Tuttavia, come illustrato nel seguente esempio, l'etichettatura dei valori della tupla restituita dalla funzione è molto comoda e facilita la comprensione del codice.

let timeComponents = timeComponentsForDate (Date ()) print (timeComponents.hour) print (timeComponents.minute) print (timeComponents.second)

È anche possibile restituire un valore facoltativo da una funzione se ci sono scenari in cui la funzione non ha valore da restituire. Questo è semplice come definire il tipo di ritorno della funzione come facoltativo, come mostrato di seguito.

func timeComponentsForDate (_ date: Date) -> (hour: Int, minute: Int, second: Int)? let dateComponents = Calendar.current.dateComponents ([. hour, .minute, .second], from: date) guardia let hour = dateComponents.hour else return nil guardia let minute = dateComponents.minute else return nil guardia let second = dateComponents.second else return nil return (hour, minute, second)

Conclusione

In questo tutorial, abbiamo esplorato le basi delle funzioni in Swift. È importante comprendere la sintassi delle funzioni, perché nel prossimo articolo esploreremo funzioni più avanzate che si basano su ciò che abbiamo trattato in questo tutorial.

Vi incoraggio a leggere di nuovo l'articolo se necessario e, soprattutto, a scrivere alcune funzioni in un parco giochi per familiarizzare con la sintassi. Le nozioni di base sono facili da capire, ma puoi solo impararle praticando.

Se vuoi imparare come usare Swift 3 per codificare le applicazioni del mondo reale, consulta il nostro corso Crea app per iOS con Swift 3. Che tu sia nuovo nello sviluppo di app per iOS o che stia cercando di passare da Objective-C, questo corso ti consentirà di iniziare con Swift per lo sviluppo di app.