1. Le basi della programmazione in Swift Flashcards
Le prime keyword di Swift: var e let
Le parole che utilizzerai in questa lezione si chiamano: var e let. Vengono anche dette variabili e costanti del linguaggio Swift. Entrambe permettono la conservazione delle informazioni ed entrambe sono due modi differenti di affrontare il problema del salvataggio dei dati.
var: Il contenuto conservato in una var o variabile può cambiare nel tempo. Per esempio, il punteggio di un giocatore è qualcosa che cambia in base ai livelli ed al tipo di gioco a cui si sta giocando.
let: Il contenuto conservato una let o costante non può cambiare nel tempo. Per esempio, il tuo codice fiscale o la tua data di nascita sono informazioni che non varieranno mai nel tempo e quindi, è consigliabile, salvare all’interno di una let/costante.
Variabile con il linguaggio Swift
Prima ti ho detto che la conservazione di un’informazione avviene tramite l’utilizzo delle variabili e costanti. Adesso ti dico che una variabile, per il linguaggio Swift, si definisce tale se il suo valore può cambiare nel tempo.
Una variabile, o var in Swift, è come un cassetto del tuo armadio. Puoi aprirlo, cambiare e togliere le magliette.
Nel linguaggio di programmazione Swift, per poter implementare una variabile, si utilizza la keyword var (var-iabile) seguita dal nome che vuoi dare alla variabile:
1
var nomeVariabile
Il processo di conservazione di un’informazione all’interno di una variabile si chiama assegnazione.
Per assegnare un valore ad una variabile si utilizza il simbolo = (uguale). In informatica il simbolo uguale sta a indicare che il valore a destra dell’uguale sarà contenuto nella variabile a sinistra dell’uguale.
Il simbolo d’uguaglianza assegna l’informazione alla sua destra ad uno spazio di memoria (cioè alla variabile).
Quindi assegnare significa: “Ehi! Vammi a conservare questo valore in uno spazio di memoria”.
Per questo motivo, il simbolo matematico d’uguaglianza ha significato completamente diverso rispetto a quando viene utilizzato in informatica. In matematica significa che il valore a sinistra dell’uguale è identico a quello di destra. Ad esempio “x = 2” equivale a dire che “2 = 2” e infine “0 = 0”.
Apri il Playground, crea la tua prima variabile e assegnagli un valore:
var laMiaVariabile = 5
print(laMiaVariabile)
Come viene eseguito il codice?
- Il compilatore scorre le righe partendo dalla numero 1 e si ferma appena trova un codice.
- Vede, come prima cosa, che hai utilizzato la parola chiave var.
- Capisce che hai dichiarato una variabile di nome laMiaVariabile.
- Vede che stai eseguendo un’assegnazione dato che c’è il simbolo =. Assegna il valore di destra alla variabile.
- Il compilatore passa alla riga 2.
- Legge print e capisce che dovrà scrivere qualcosa in console.
- Prende il valore assegnato alla laMiaVariabile.
- Stampa il valore.
Costante con il linguaggio Swift
Una costante, a differenza della variabile, una volta assegnatogli un valore non lo cambierà più per tutta la vita dell’applicazione. Ti ricordi la scatola? Bene, in questo caso, una volta che è stata riempita, viene immediatamente chiusa. Una volta chiusa non è possibile inserire o cambiare il suo contenuto.
Per creare una costante utilizza la keyword let:
let costanteNumerica = 4
print(costanteNumerica)
Aggiungi il codice immediatamente sotto a quello scritto per la variabile.
Commentare il codice
Per scrivere un commento in una linea utilizza // prima del commento.
Per scrivere un commento multi linee devi utilizzare /* prima dell’inizio del commento e */ alla fine del commento.
La prima regola
Non possono esistere variabili o costanti con lo stesso nome.
var peppe = 21
var peppe = 25 // ERROREEEEEEE
let peppe = 25 // ERROREEEE
Ma allora una volta dichiarate non le posso più utilizzare? Certo che si. Una volta che creerai una variabile o costante, dopo la potrai utilizzare senza bisogno di esplicitare nuovamente che è una var/let. Il linguaggio Swift riesce a capirlo da se.
Inizializzazione
Il processo di creazione e assegnazione di un valore, ad una variabile o costante, si chiama Inizializzazione. Definisce l’atto di creazione di una variabile e contemporaneo passaggio di un valore di partenza.
Nella pratica un’inizializzazione è la prima volta in cui mette piede, nel codice, quella variabile. Oltre a mettervi piede, deve essere accompagnato da un valore:
var ciccio = 2 // Questa è una INIZIALIZZAZIONE
let peppe = 4 // Questa è pure una INIZIALIZZAZIONE
Passaggio di valori
Ti ricordi il concetto delle scatole? Bene!
Una scatola può passare ad un’altra scatola il suo contenuto. Cioè una variabile o costante del linguaggio Swift può passare il suo valore ad un’altra var o let.
Lavoriamo sempre per esempi. Copia ed incolla il seguente codice Swift nel tuo Playground:
//prima inizializzo 3 variabili
var a = 2
var b = 5
var z = 0
//stampo il valore di tutte e 3 le variabili
print(a)
print(b)
print(z)
//poi passo il contenuto della scatola a alla scatola z
//e subito dopo della scatola b alla z
z = a
z = b
//stampo il valore di tutte e 3 le variabili
print(a)
print(b)
print(z)
Cos’è successo alla variabile z? Ricordandoti che il processo di esecuzione del codice parte sempre dall’alto, prima hai inizializzato 3 variabili con un valore numerico, poi hai stampato il valore con la print, poi qualcosa di strano…
Prima “z” prende il valore di “a” e poi alla riga successiva lo sostituisce con “b”. Se tra le due righe metti una print(z) capirai cosa voglio dire.
Esercizio 1. Passare valori da una costante ad una variabile.
let a = 4
var b = 0
b = a
var c = 0
c = b
print(a)
print(b)
print(c)
Ricordati che una costante non può cambiare il suo valore una volta che è stata inizializzata.
Le operazioni matematiche
Molte delle operazioni possibili in Swift sono uguali a quelle matematiche. Te le riporto insieme ad esempi pratici:
SimboloSpiegazione
+Somma due numeri/variabili
var a = 2
var b = a - 2
//b è = 0
*Moltiplica due numeri/variabili
var a = 2 * 2
var b = a * 1
var c = a * b
/Divide due numeri/variabili
var a = 4/2
var b = a/2
+=Somma al suo stesso valore il nuovo
var a = 2
a += 4
// il risultato è 6, che equivale ad: a = a + 4
-=Sottrae al suo stesso valore il nuovo
var a = 2
a -= 4
// il risultato è -2, che equivale ad: a = a - 4
*=Moltiplica al suo stesso valore il nuovo
var a = 2
a *= 4
// il risultato è 8, che equivale ad: a = a * 4
/=Divide al suo stesso valore il nuovo
var a = 4
a /= 2
// il risultato è 2, che equivale ad: a = a / 2
La priorità delle operazioni
Come in matematica, ogni operazione ha una priorità rispetto ad un’altra. La moltiplicazione viene eseguita prima dell’addizione e così via. Il linguaggio Swift esegue automaticamente le operazioni di ordine superiore e poi quelle minori.
Per gestire le priorità puoi utilizzare le parentesi tonde in modo da forzare un’operazione rispetto ad un’altra:
var a = 2*((4+2)/3)
//prima esegue la somma tra 4 e 2 poi divide per 3 ed infine esegue la moltiplicazione per 2
I tipi di dato del linguaggio Swift
Inizializzare significa dare un valore ad una variabile alla sua dichiarazione:
var miaVar = 2 // questa è una inizializzazione
miaVar = 3 // questo è un utilizzo della var inizializzata sopra
Ok! “miaVar” ha valore 3, ma cosa rappresenta realmente? Ora che è stata inizializzata, con un numero, posso inserigli altre cose diverse?
Purtroppo no. Se una scatola contiene patate, per tutta l’esecuzione del programma quella variabile dovrà contenere patate, stesso discorso se gli mettessi un numero o delle parole. Questa particolare proprietà, cioè che una variabile non può cambiare tipologia di dato trasportata prende il nome di Type Safe.
Per esempio, nelle variabile o costanti del linguaggio Swift, oltre ai numeri, puoi inserire del testo. Il testo deve essere racchiuso tra le doppie virgolette (sotto verrà chiarito questo concetto).
var parola = “ciao”
var numero = 2
parola = numero // ERRORE: La var “parola” non può contenere numeri
Dopo aver creato una variabile inizializzata con una frase ed una con un numero, ho provato a passare il valore della var “numero” nella variabile “parola”. Un’operazione impossibile dato che non si possono eseguire operazioni tra tipi di valore differente.
Ma allora che tipo di dato o informazione può contenere una variabile?
Il tipo di dato puoi considerarlo come gli insiemi da cui pescare i dati. Ad esempio i numeri interi, cioè quelli senza la virgola, vengono descritti dalla parola chiave Int. Grazie a questa nuova conoscenza puoi affermare che la variabile “numero” contiene un valore che fa parte della famiglia degli Int.
var altroNumero = 4 // Questo appartiene alla famiglia degli Int
I numeri con la virgola, per fare un altro esempio, vengono descritti dalla famiglia Double. Un numero come 4.0 è Double ma non è Int anche se il valore dopo la virgola, essendo zero, potrebbe farti pensare che sia un Int.
var numeroDouble = 4.5 // Questo valore appartiene alla famiglia dei Double
Le parole e le frasi appartengono alla famiglia delle String e così via. Esistono parecchi e svariati Tipi di Dato, cioè famiglie che ti permetteranno di descrivere meglio un’informazione memorizzata.
Ecco la lista dei Tipi di Dato maggiormente utilizzati nel linguaggio Swift:
Int Tutti i numeri interi positivi e negativi.
Esempio : -1, -2, +3321, 0
Float Rappresenta l’insieme dei numeri reali, (gli Int + i numeri con la virgola). Esempio : -4.2, 2.004, 55, 31, 0.1
Double Simile al Float ma con una precisione dopo la virgola maggiore. Di default quando inserisci un numero con la virgola Swift lo interpreta come Double e non come Float. Esempio 4.00000001, 33, 5.231355602
Character Rappresenta i caratteri, si può assegnare solo un carattere ad una var, altrimenti diventa una stringa. Quando lo si assegna ad una var deve essere racchiuso tra gli apici ” “. Esempio : “a” “b” “1” “4” “z” ” ” . Anche lo spazio vuoto è un carattere!
String Più caratteri formano una stringa. Esempio : “Ciao sono una stringa” , “Matteo è nato nel 1993”.
Bool Rappresenta la condizione di VERO (true) o FALSO (false). Utilizzeremo questo tipo di dato più avanti.
Ecco un esempio dei tipi di dato del linguaggio Swift:
var numeroIntero = -454 // questo è un Int
numeroIntero = 499 // questo è ancora un Int
var peso_corporeo = 65.90 // questo è un Double
peso_corporeo = 70 // sono ingrassato ma questo è ancora un Double perché era stato inizializzato con un valore double
let nome = “Giuseppe” // String
let cognome = “Sapienza” // String
var xCodingFantastica = true // questo è un Bool
var sonoBello = false // questo è un Bool
Dichiarazione Implicita
Quando inizializzi una variabile automaticamente, oltre a passare il valore, passi il tipo di dato. Alla scatola viene assegnata una categoria, da ora in poi potrà contenere solo elementi di quella categoria:
var a = 2 // INIZIALIZZAZIONE DI TIPO INT
Una volta che hai inizializzato una variabile con un tipo di dato, non potrai più cambiarglielo. Infatti se alla variabile “a” provi a mettere un valore Double, il Playground, ti mostrerà un errore:
a = 44.2 // ERRORE! POSSO CONTENERE SOLO INTERI
Stesso discorso vale anche per gli altri tipi di dato.
Esercizio 5. Esempio dichiarazione implicita tipo String.
var ciao = “ciao”
ciao = “ciao Mondo”
ciao = 2 // ERRORE! La variabile “ciao” è di tipo String e non puoi mettere un Int
// al massimo avresti potuto fare
ciao = “2”
Dichiarazione di tipo esplicita
Puoi assegnare il tipo di dato in modo esplicito. Ti basta inserire i due punti (:) dopo il nome della variabile. A seguire devi inserire il tipo di dato che vuoi assegnargli:
var variabileEsplicita: tipo
var variabileEsplicita: Float
let variabileEsplicita_1: Double // il Double è simile al Float ma con una precisione, dopo la virgola, maggiore
Senza aver inizializzato sei riuscito comunque ad etichettare la variabile, adesso il compilatore sa che da qui in avanti potrai inserirgli solo un determinato tipo di informazione.
La stessa procedura va fatta soprattutto quando un’inizializzazione non fornisce tutti i dati necessari da far capire il tipo che vuoi realmente utilizzare. Ad esempio se vuoi che una var sia di tipo Double e il primo valore che gli assegni è un 2, per non indurre in confusione il compilatore (che di default la tratterebbe come Int) devi obbligatoriamente esplicitarne il tipo:
var varDouble = 2
Nell’esempio volevo creare una variabile di tipo Double, però il primo valore che volevo assegnargli era il “2”. Se non inserivo il tipo di dato, la variabile “varDouble”, sarebbe stata costretta a trattare solo gli interi quindi sarebbe stata di tipo Int.
Per ovviare il problema avrei dovuto scrivere il tipo di dato:
var varVeroDouble: Double = 2
In questo modo il numero due, che verrebbe interpretato come Int se non ci fosse il tipo esplicitato, viene considerato come Double. Un Double, anche se viene utilizzato per rappresentare i numeri con la virgola, può rappresentare i numeri interi.
Conversione esplicita
Come faccio a stampare con la print un valore di tipo Int?
In questi casi il linguaggio Swift offre uno strumento chiamato conversione di tipo esplicita momentanea. Guarda questo esempio in cui voglio provare a stampare, dopo un opportuno calcolo, l’area di un triangolo:
let base = 4
let altezza = 2
let calcoloArea = (base * altezza)/2 //AREA DEL TRIANGOLO
let stringa = “l’area del triangolo è uguale a “
var stringaFinale = stringa + calcoloArea // ERROREEE CONVERSIONE! string + int
// unire la stringa con
// un valore intero genera errore.
// BISOGNA ESEGUIRE LA CONVERSIONE DI calcoloArea
print(stringaFinale)
L’errore che generato si chiama: Errore di conversione Implicita. Il linguaggio Swift non è in grado di convertire un tipo di dato senza che tu gliel’abbia ordinato. Il motivo è abbastanza semplice, non sa quale dei due deve convertire!
Nell’esempio, la “stringaFinale” è una stringa a cui ho provato ad aggiungere il valore intero dell’area calcolata. Ovviamente eseguire stringa + intero genera incomprensione da parte del compilatore.
Il problema è sempre quello del: come sommo patate con cipolle?
Per risolvere questo problema puoi optare per 2 opzioni:
Per tutti i tipi di dato. Scrivi il nuovo tipo di dato seguito dalle parentesi tonde che incapsulano la variabile o il valore da convertire, ad esempio String(calcoloArea):
var stringaFinale = stringa + String(calcoloArea)
Solo per le stringhe. Inserire \ seguita dal nome della variabile racchiusa tra parentesi all’interno di una stringa:
var stringaFinale = stringa + “(calcoloArea)”
Ecco che l’esempio di sopra si trasforma così:
let base = 4
let altezza = 2
let calcoloArea = (base * altezza)/2
let stringa = “l’area del rettangolo è uguale a “
//oppure con questa let stringaFinale = stringa + String(calcoloArea)
var stringaFinale = stringa + “(calcoloArea)”
print(stringaFinale)
Questa operazione la chiamo conversione di tipo esplicita momentanea perché effettivamente non viene cambiato il tipo della variabile, come erroneamente potresti pensare, bensì viene cambiato solo in quello specifico contesto o operazione.
Esercizio 6. Calcolare la media numerica di 4 numeri.
Ecco un’altro esempio e che puoi trovare utile per capire il meccanismo di passaggio da un tipo ad un altro.
Calcolare la media in float di 4 numeri di tipo diverso e stampare il risultato:
let x1: Float = 4
let x2 = 3.5 // lo considera come un DOUBLE e non come un FLOAT
let x3 = 5 // non ho specificato il tipo gli lascio intendere che sia un intero
let x4: Double = 2 // In questo caso il 2 viene considerato come Double, quindi come 2.0
var media: Float = (x1 + Float(x2) + Float(x3) + Float(x4))/4
print(“la media è : (media)”)
Perdita di informazioni passando da un tipo ad un altro
are una conversione, da un tipo di dato più grande (come il Double) ad uno più piccolo (come l’Int), comporta perdita di informazione.
Mi spiego meglio. Considera il seguente esempio:
var x: Double = 55.234
var y: Int = Int(x) //converto x in Int
print(“x trasformato in Int = (y)”)
//x trasformato in Int è uguale 55
Dov’è finito il .234? È stato perso perché un Double per diventare un Int doveva obbligatoriamente elidersi della sua parte decimale.
In definitiva, le conversioni senza perdita di dati:
da Int a Float o Double,
da Float a Double,
da Int, Float e Double in String.
Con perdita di dati:
da Double a Float o Int (in questo caso piena perdita delle parte con la virgola),
da Float a Int.
Ricordati che le stringhe fanno testo a parte e che tutti i tipi di dato possono essere convertiti a String senza perdita di dati.
let numeroA: Int = 45
let numeroB: Double = 7.7
var stringaA: String = “(numeroA)”
var stringaB: String = “(numeroB)”
Array linguaggio Swift
Puoi considerare un Array come un lungo treno dove ogni vagone contiene l’informazione da conservare. Ogni treno è una collezione potenzialmente infinita di vagoni che trasportano un’informazione. Ogni vagone, inoltre, è accessibile tramite un indice (un numero di identificazione).
Fai finta che all’interno di una scatola (una variabile) stai buttando, invece di una singola informazione, tante altre scatole tutte delle stesso tipo. I passaggi da fare per l’inizializzazione di un Array sono i seguenti:
Definire una variabile o costante.
Assegnargli un Array di valori. I valori sono racchiusi da parentesi quadre e divisi, l’uno dall’altro, da una virgola:
var array = [10, 44, 33, -1]
Adesso la variabile “vettore” rappresenta l’Array per tutta la sua interezza. Infatti se nel codice scrivi print(array), la funzione stamperà tutti i valori contenuti all’interno della variabile:
var array = [10, 44, 33, -1]
print(“La lista contenuta dall’array è “)
print(array)
// La lista contenuta dall’array è
// [10, 44, 33, -1]
Qual’è il tipo di dato del vettore? Nella lezione precedente ti ho detto che esistono delle famiglie che descrivono i valori che puoi assegnare ad una var o let. Per esempio gli Int sono la famiglia dei numeri interi e String descrive le parole.
Nel caso dell’array che hai inizializzato nell’esercizio, i valori contenuti all’interno sono degli Int. Dato che un array è descritto dalle parentesi quadre [], il tipo di un array si forma inserendo il tipo di dato all’interno delle parentesi. Esempio, se volessi creare un array di String e volessi anche assegnare il tipo in maniera esplicita, scriverei:
var array_string: [String] = [“questo”, “è”, “un array di stringhe”]
Esercizio 0. Crea ed inizializza un array di numeri Double. Definisce in maniera esplicita il suo tipo di dato.
Accedere agli elementi dell’array
Considera il seguente Array di Interi:
var punteggi: [Int] = [20, 55, 32, 100, 0]
Punteggi ormai sai che rappresenta l’intera lista degli elementi contenuti in esso, ma come accedo ad un singolo elemento della lista?
All’inizio della lezione ti ho detto che l’Array in Swift non è altro che una sorta di treno dove ogni vagone contiene l’informazione. Ogni vagone inoltre è identificato da un indice.
Nel primo vagone c’è il numero 20, nel secondo il numero 55 e così via.
L’indice parte sempre da zero fino ad arrivare ad un numero grande quanto il numero di elementi contenuti meno uno.
Perché N-1? Immagina un Array di 10 elementi.
Se il conteggio degli elementi parte da 0, per arrivare a 10 deve fermarsi al numero 9. infatti 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 sono 10 numeri e non 9 come erroneamente potresti pensare.
Con il linguaggio Swift, per poter accedere ad ogni singolo vagone dell’Array, devi utilizza questa notazione:
var punteggi = [20, 55, 32, 100, 0]
punteggi[0]
punteggi[1]
punteggi[2]
// ….
punteggi[9]
Quindi per accedere all’informazione contenuta alla posizione iesima, si esplicita vicino al nome dell’Array, la posizione dell’elemento cercato. Utilizzando la sintassi nomearray [numeroPosizione]:
var altro_array = [10, 233, 55]
var posizione = 0
altro_array[posizione]
Di fatto dichiarando la posizione non fai altro che accedere all’informazione della scatola alla posizione X contenuta nell’Array.
Un vettore può contenere diversi tipi d’informazione, cioè valori che appartengono a diversi tipi di dato:
var array_misto = [1, 2, “ciao”, 55.32]
In questa prima parte del corso gratuito non utilizzeremo questa sintassi. Cioè ti farò scrivere array che hanno tutti lo stesso tipo di dato. Il motivo di tale scelta verrà spiegata nell’ultimo modulo del corso quando arriverai alla programmazione ad oggetti.
Tipi di dato vuoti o di partenza
Se non vuoi inizializzare subito un Array, cioè non vuoi dargli un valore iniziale, il linguaggio Swift ti da la possibilità di inizializzarlo come vuoto. Per inizializzare un Array come vuoto devi:
Dichiarare una variabile.
Assegnargli il tipo di dato che dovrà contenere, tra parentesi quadre, e aggiungere due parentesi tonde.
Quindi se vuoi inizializzare un Array di interi e lasciarlo vuoto devi fare:
var arrayVuoto = Int
var arrayVuotoString = String
Il motivo delle parentesi tonde lo scoprirai quando arriverai a studiare la programmazione ad oggetti. Per il momento, quello che ti interessa sapere è che puoi assegnare il tipo di dato per rendere vuoto un vettore. Lo stesso discorso vale anche per le normali variabili infatti:
var a = Int()
var b = Double()
Prova a stampare il contenuto dell’Array, scoprirai che verranno stampate solo le parentesi quadre le quali non hanno niente al loro interno:
print(arrayVuoto)
// []
Problema nella dichiarazione
Attenzione! C’è una piccola differenza tra inizializzato e dichiarato infatti prova ad eseguire il seguente codice:
var vettore: [Int] // questa è solo una dichiarazione
print(vettore)
Cosa facilmente risolvibile così:
var vettore: [Int] // questa è solo una dichiarazione
vettore = [1, 2, 6, 111]
print(vettore)
Questo pseudo errore verrà corretto nelle prossime lezioni, tanto per il momento hai già tutti gli strumenti per creare un Array.