CONTROL FLOW Flashcards

1
Q

Control Flow

A

Swift offre tutti i classici controlli di flusso utilizzati nei linguaggi C-like. Questi includono “for” “and” “while” che servono per eseguire un’istruzione più volte; “if” e “switch” per eseguire diversi rami di codice in base a determinate condizioni; “break” e “continue” per trasferire il flusso in esecuzione in un altro punto del codice.

Oltre al tradizionale ciclo for che si trova in C, Swift aggiunge un ciclo for-in che rende più semplice scorrere gli array, dizionari, intervalli, stringhe e altre sequenze di dati.

“Switch” in Swift è anche molto più potente rispetto al suo omologo in C. I casi di un’istruzione switch non continuano attraverso il prossimo “case”, evitando gli errori più comuni in C causati dalla mancanza di istruzioni “break”. I valori che corrispondono in un “case” possono essere associati a costanti o variabili temporanee per essere utilizzati all’interno del corpo del case.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

For-In

A

Si utilizza il for-in loop per iterare in un “insieme di dati”, come può essere un range di numeri, valori in una lista o caratteri in una stringa.

In questo esempio vengono stampati i primi 5 elementi di una lista:

for index in 1…5 {<br></br>println(“(index) times 5 is (index * 5)”)<br></br>}<br></br>// 1 times 5 is 5<br></br>// 2 times 5 is 10<br></br>// 3 times 5 is 15<br></br>// 4 times 5 is 20<br></br>// 5 times 5 is 25

Il numero di valori che vengono richiamati vanno dalla posizione 1 alla 5, come indicato dall’operatore range racchiuso tra parentesi (…). Il valore di indice è impostato sul primo numero nell’intervallo (1) e le istruzioni all’interno del ciclo vengono eseguite. In questo caso, il loop contiene una sola istruzione, che stampa una voce recuperandola dalla lista, per 5 volte (incrementando il numero dell’indice). Dopo l’esecuzione dell’istruzione, il valore dell’ indice viene aggiornato per contenere il secondo valore nell’intervallo (2), e la funzione println viene chiamata di nuovo. Questo processo continua fino a quando viene raggiunta la fine del range.

Nell’esempio precedente, l’indice è una costante il cui valore è impostato automaticamente all’inizio di ogni iterazione del ciclo. Come tale, essa non deve essere dichiarata prima di essere utilizzata. Si è implicitamente dichiarata la sua inclusione nella dichiarazione loop.

let names = [“Anna”, “Alex”, “Brian”, “Jack”]

for name in names {<br></br>println(“Hello, (name)!”)<br></br>}<br></br>// Hello, Anna!<br></br>// Hello, Alex!<br></br>// Hello, Brian!<br></br>// Hello, Jack!

Si può iterare all’interno di un dizionario attraverso le sue chiavi, per accedere ai diversi valori. Ogni elemento del dizionario viene restituito con la tupla (key, value) e, se necessario, si possono scomporre queste tuple per utilizzarle come costanti nel corpo del loop “for-in”. In questo esempio, le tuple vengono decomposte in questo modo: la costante animalName e il valore del dizionario vengono scomposti in una costante chiamata legCount:

let numberOfLegs = [“spider”: 8, “ant”: 6, “cat”: 4]<br></br>for (animalName, legCount) in numberOfLegs {<br></br>println(“(animalName)s have (legCount) legs”)<br></br>}<br></br>// spiders have 8 legs<br></br>// ants have 6 legs<br></br>// cats have 4 legs

I valori in un dizionario non devono necessariamente essere restituiti nello stesso ordine in cui sono stati inseriti. Il contenuto di un dizionario, infatti, non è mai ordinato quindi iterare nel dizionario non garantisce una restituzione ordinata dei valori.

In aggiunta alle liste o ai dizionari, si può utilizzare il for-in per iterare nei caratteri di una stringa:

for character in “Hello” {<br></br>println(character)<br></br>}<br></br>// H<br></br>// e<br></br>// l<br></br>// l<br></br>// o

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

While Loops

A

Un ciclo while esegue un insieme di istruzioni fino a quando una condizione diventa falsa. Questi tipi di cicli sono usati quando il numero di iterazioni non è noto prima dell’inizio del ciclo stesso. Swift offre due tipi di cicli while:while valuta la condizione all’inizio di ogni passaggio attraverso il ciclo.
do-while valuta la sua condizione alla fine di ogni passaggio attraverso il ciclo.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

While

A

While
Un ciclo while inizia la valutazione di una singola condizione. Se la condizione è vera, un insieme di istruzioni viene ripetuto fino a quando la condizione diventa falsa.

Ecco la forma generale di un ciclo while:

while condition {<br></br>statements<br></br>}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Repeat-While

A

L’altra variante di while, cioè repeat-while, esegue prima un singolo passaggio attraverso il blocco, prima di considerare la condizione. Dopo aver preso in considerazione la condizione continua a ripetere il ciclo finché la condizione risulta falsa.

Ecco la forma generale di un ciclo do-while:

repeat {

statements

} while condition

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

istruzioni condizionali

A

Spesso sono utili per eseguire diversi pezzi di codice in base a determinate condizioni. Potrebbe essere utile eseguire un ulteriore porzione di codice quando si verifica un errore, o per visualizzare un messaggio quando un valore diventa troppo elevato o troppo basso. Per fare questo, si possono utilizzare le istruzioni condizionali.

Swift offre due modi per aggiungere rami condizionali al tuo codice, noti come istruzioni if e switch. In genere, si utilizza l’istruzione if per valutare le condizioni semplici con pochi risultati possibili. L’istruzione switch è più adatta alle condizioni più complesse con più permutazioni.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

if

A

Nella sua forma più semplice, l’istruzione if ha una sola condizione. Si esegue un insieme di istruzioni solo se tale condizione è vera:

var temperatureInFahrenheit = 30<br></br>if temperatureInFahrenheit <= 32 {<br></br>println(“It’s very cold. Consider wearing a scarf.”)<br></br>}<br></br>// prints “It’s very cold. Consider wearing a scarf.”

L’esempio precedente controlla se la temperatura è inferiore o uguale a 32 gradi Fahrenheit (il punto di congelamento dell’acqua). Se lo è, viene stampato un messaggio. Altrimenti, nessun messaggio viene stampato, e l’esecuzione di codice continua dopo la chiusura.

L’istruzione if in grado di fornire un insieme alternativo di dichiarazioni, note come else, nel caso in cui la condizione dell’if sia falsa. Tali dichiarazioni sono indicate dalla parola chiave else:

temperatureInFahrenheit = 40<br></br>if temperatureInFahrenheit <= 32 {<br></br>println(“It’s very cold. Consider wearing a scarf.”)<br></br>} else {<br></br>println(“It’s not that cold. Wear a t-shirt.”)<br></br>}<br></br>// prints “It’s not that cold. Wear a t-shirt.”

Una di queste due porzioni di codice viene sempre eseguito. Poiché la temperatura è aumentata di 40 gradi Fahrenheit, non è più abbastanza freddo per avvisarlo di indossare una sciarpa, così scatta il ramo else.

È possibile concatenare più istruzioni if ​​insieme, che verranno considerate come clausole addizionali:

temperatureInFahrenheit = 90<br></br>if temperatureInFahrenheit <= 32 {<br></br>println(“It’s very cold. Consider wearing a scarf.”)<br></br>} else if temperatureInFahrenheit >= 86 {<br></br>println(“It’s really warm. Don’t forget to wear sunscreen.”)<br></br>} else {<br></br>println(“It’s not that cold. Wear a t-shirt.”)<br></br>}<br></br>// prints “It’s really warm. Don’t forget to wear sunscreen.”

Qui, un ulteriore if si aggiunge per restituire un messaggio quando si trattano temperature particolarmente calde. La clausola else finale rimane e stampa una risposta per tutte le temperature che non possono essere considerate né troppo calde né troppo fredde.

La clausola else finale è facoltativa e può essere quindi esclusa se l’insieme di condizioni non ha bisogno di essere completa:

temperatureInFahrenheit = 72<br></br>if temperatureInFahrenheit <= 32 {<br></br>println(“It’s very cold. Consider wearing a scarf.”)<br></br>} else if temperatureInFahrenheit >= 86 {<br></br>println(“It’s really warm. Don’t forget to wear sunscreen.”)<br></br>}

In questo esempio, la temperatura non è né troppo fredda né troppo calda, quindi non viene stampato nessun messaggio.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Switch

A

Un’istruzione switch considera un valore e lo confronta con diversi modelli corrispondenti possibili. Quindi, esegue un blocco di codice appropriato, in base al primo modello che corrisponde alla condizione data. Un’istruzione switch fornisce un’alternativa per l’istruzione if per rispondere a più stati possibili.

Nella sua forma semplice, un’istruzione switch confronta un valore con uno o più valori dello stesso tipo:

switch some value to consider {<br></br>case value 1:<br></br>respond to value 1<br></br>case value 2,<br></br>value 3:<br></br>respond to value 2 or 3<br></br>default:<br></br>otherwise, do something else<br></br>}

Ogni switch è costituito da più casi possibili, ognuno dei quali inizia con la parola chiave case. Oltre al confronto con i valori specifici, Swift fornisce diversi modi per ogni case di specificare i modelli corrispondenti più complessi.

Il corpo di ciascun switch-case rappresenta un ramo separato di codice, in modo simile a quelli di un if. L’istruzione switch determina quale ramo deve essere selezionato.

Ogni switch deve essere esaustivo. Cioè, ogni valore possibile del tipo in esame deve essere accompagnato da un case. Se non è opportuno prevedere un case per ogni valore possibile, si può definire un case di default per coprire eventuali valori che non vengono affrontati in modo esplicito.

Questo esempio utilizza un’istruzione switch per prendere in considerazione un singolo carattere minuscolo chiamato someCharacter:

let someCharacter: Character = “e”<br></br>switch someCharacter {<br></br>case “a”, “e”, “i”, “o”, “u”:<br></br>println(“(someCharacter) is a vowel”)<br></br>case “b”, “c”, “d”, “f”, “g”, “h”, “j”, “k”, “l”, “m”,<br></br>“n”, “p”, “q”, “r”, “s”, “t”, “v”, “w”, “x”, “y”, “z”:<br></br>println(“(someCharacter) is a consonant”)<br></br>default:<br></br>println(“(someCharacter) is not a vowel or a consonant”)<br></br>}<br></br>// prints “e is a vowel”

Il primo caso di switch corrisponde a tutte e cinque le vocali minuscole in lingua inglese. Allo stesso modo, il suo secondo caso corrisponde a tutte le consonanti inglesi minuscole.

Non risulta pratico scrivere tutti gli altri caratteri possibili nell’ambito di uno switch-case, e così questa affermazione switch fornisce un caso predefinito per abbinare tutti gli altri caratteri che non sono vocali o consonanti. Questa fa si che l’istruzione switch sia esaustiva.

L’intera istruzione switch termina la sua esecuzione non appena il primo switch-case adatto è completato, senza richiedere un’istruzione break esplicita. Questo rende l’istruzione switch più sicura e facile da usare rispetto a C ed evita di dover ricorrere ad altri “case”.

Il corpo di ogni singolo case deve contenere almeno un’istruzione eseguibile. AND non è valida per scrivere il codice seguente, in quanto il primo case è vuoto:

let anotherCharacter: Character = “a”<br></br>switch anotherCharacter {<br></br>case “a”:<br></br>case “A”:<br></br>println(“The letter A”)<br></br>default:<br></br>println(“Not the letter A”)<br></br>}<br></br>// this will report a compile-time error

A Differenza di C, in un’istruzione switch non corrisponde sia “a” e “A”. Piuttosto, si segnala un errore di compilazione quel caso “a”: non contiene istruzioni eseguibili. Questo approccio rende il codice più sicuro e molto più chiaro e scorrevole.

Più corrispondenze per un singolo switch-case possono essere separate da virgole, e possono essere scritti su più righe se la lista è lunga:

switch some value to consider {<br></br>case value 1,<br></br>value 2:<br></br>statements<br></br>}


Nei case possono essere utilizzati anche dati contenuti in un intervallo:

let count = 3_000_000_000_000<br></br>let countedThings = “stars in the Milky Way”<br></br>var naturalCount: String<br></br>switch count {<br></br>case 0:<br></br>naturalCount = “no”<br></br>case 1…3:<br></br>naturalCount = “a few”<br></br>case 4…9:<br></br>naturalCount = “several”<br></br>case 10…99:<br></br>naturalCount = “tens of”<br></br>case 100…999:<br></br>naturalCount = “hundreds of”<br></br>case 1000…999_999:<br></br>naturalCount = “thousands of”<br></br>default:<br></br>naturalCount = “millions and millions of”<br></br>}<br></br>println(“There are (naturalCount) (countedThings).”)<br></br>// prints “There are millions and millions of stars in the Milky Way.

A differenza di C, Swift permette di utilizzare diverse volte “case” anche per gli stessi valori. Ad esempio, se parliamo di coordinate di un punto, (0, 0) può rientrare in deversi “case”. In ogni modo, quando arriverà il punto (0,0) nell’iterazione, verrà preso in considerazione solo quello ed eventuali match successivi verranno ignorati.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Value Bindings (switch)

A

Un case switch può associare il valore o i valori che corrispondono a costanti o variabili temporanee, per l’uso nel corpo del case. Questo è noto come valore vincolante, in quanto i valori sono “legati” a costanti temporanee o variabili contenute esclusivamente all’interno del corpo del case.

L’esempio che segue prende un punto (x, y), espresso come una tupla di tipo (Int, Int) e lo inserisce in un grafico:

let anotherPoint = (2, 0)<br></br>switch anotherPoint {<br></br>case (let x, 0):<br></br>println(“on the x-axis with an x value of (x)”)<br></br>case (0, let y):<br></br>println(“on the y-axis with a y value of (y)”)<br></br>case let (x, y):<br></br>println(“somewhere else at ((x), (y))”)<br></br>}<br></br>// prints “on the x-axis with an x value of 2

L’istruzione switch determina se il punto si trova sull’ asse x, y o altrove (cioè su nessuno dei 2 assi cartesiani).

I tre case dichiarano le costanti temporanee x e y, che assumono valori di una o entrambe le tuple da “anotherPoint”. Il primo caso, (sia x, 0), corrisponde a qualsiasi punto con valore y di 0 e assegna il valore x del punto alla costante x temporanea. Analogamente, il secondo caso, (0, sia y), corrisponde a qualsiasi punto con un valore di x 0 e assegna il valore y del punto alla costante y temporaneo.

Una volta che le costanti temporanee sono dichiarate, possono essere utilizzate unicamente entro il blocco di codice del case. Qui sono utilizzate come scorciatoia per la stampa dei valori con la funzione println.

Si noti che questa istruzione switch non ha un caso di default. L’ultimo caso, caso let (x, y), dichiara una tupla di due costanti segnaposto che possono abbinare qualsiasi valore. Di conseguenza, esso corrisponde a tutti i possibili valori rimanenti, e un caso di default non è necessario per rendere l’istruzione switch esaustivo.

Nell’esempio precedente, x ed y sono dichiarate come costanti con la parola chiave let, perché non vi è alcuna necessità di modificare i loro valori all’interno del corpo del case.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Where

A

Un case switch può utilizzare una clausola WHERE per verificare ulteriori condizioni.

L’esempio che segue suddivide un punto (x, y) sul grafico:

let yetAnotherPoint = (1, -1)

switch yetAnotherPoint {<br></br>case let (x, y) where x == y:<br></br>println(“((x), (y)) is on the line x == y”)<br></br>case let (x, y) where x == -y:<br></br>println(“((x), (y)) is on the line x == -y”)<br></br>case let (x, y):<br></br>println(“((x), (y)) is just some arbitrary point”)<br></br>}<br></br>// prints “(1, -1) is on the line x == -y”

L’istruzione switch determina se il punto si trova sulla linea diagonale dove x == y, sulla linea diagonale viola dove x == y, o nessuno dei due.

I tre casi di commutazione dichiarano costanti x e y, che assumono temporaneamente i due valori del punto. Queste costanti sono utilizzate come parte di una clausola in cui, per creare un filtro dinamico, Il case switch corrisponde al valore corrente del punto solo se la condizione della clausola WHERE restituisce true per quel valore.

Come nell’esempio precedente, il case finale corrisponde a tutti i possibili valori restanti, e quindi non è necessario l’impiego di un case di default per rendere l’istruzione switch esaustiva.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Dichiarazioni Transfer Control

A

Le Dichiarazioni “transfer control” cambiano l’ordine in cui viene eseguito il codice, trasferendo il controllo da un pezzo di codice ad un altro. Swift ha quattro dichiarazioni di trasferimento di controllo:

continue
break
fallthrough
return‌

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

continue

A

L’istruzione continue indica un ciclo per fermare l’azione corrente e ricominciare all’inizio della prossima iterazione del ciclo, senza lasciare del tutto il ciclo stesso.

L’esempio seguente rimuove tutte le vocali e gli spazi da una stringa per creare una frase criptica:

let puzzleInput = “great minds think alike”

var puzzleOutput = “”
for character in puzzleInput {
switch character {
case “a”, “e”, “i”, “o”, “u”, ” “:
continue
default:
puzzleOutput += character
}
}
println(puzzleOutput)
// prints “grtmndsthnklk

Il codice qui sopra richiama la parola continue ogniqualvolta si imbatte in una vocale o uno spazio, saltando direttamente all’inizio della successiva iterazione. Questo comportamento consente il blocco dello switch in modo che corrisponda solo i caratteri vocali e di spazio,senza controllarli tutti.
Break
L’istruzione break termina immediatamente l’esecuzione di un intero flusso di controllo. L’istruzione break può essere utilizzata all’interno di un’istruzione switch quando si desidera terminare l’esecuzione dello stesso, prima che avvenga il controllo di tutti i case.
Break in una dichiarazione Loop
Quando viene utilizzato all’interno di un’istruzione ciclo, break termina l’esecuzione del ciclo immediatamente, e trasferisce il controllo alla prima riga di codice dopo la parentesi graffa di chiusura del loop (}). Nessun ulteriore codice della corrente iterazione del ciclo viene eseguito.
Break in un’istruzione switch
Quando viene utilizzato all’interno di un’istruzione switch, break provoca l’interruzione dell’esecuzione del ciclo, per trasferire il controllo alla prima riga di codice dopo la parentesi graffa di chiusura della istruzione switch (}).

Questa funzione può essere utilizzata per abbinare e ignorare uno o più casi in un’istruzione switch. Perché un’istruzione switch di Swift sia esaustiva e non permetta case vuoti,è necessario abbinare deliberatamente e ignorare un case. A tale scopo, si può scrivere l’istruzione break come l’intero corpo del case in cui si desidera ignorare. Quando questo case si trova insieme ad un’istruzione switch, l’istruzione break all’interno del case termina immediatamente l’esecuzione dell’istruzione switch.

L’esempio seguente inserisce un valore in caratteri e determina se esso rappresenta un simbolo numerico in una delle quattro lingue. I valori multipli sono coperti in un singolo case swutch per sintetizzare il tutto:

let numberSymbol: Carattere = “三” // cinese semplificato per il numero 3

var possibleIntegerValue: Int?
switch numberSymbol {
case “1”, “١”, “一”, “๑”:
possibleIntegerValue = 1
case “2”, “٢”, “二”, “๒”:
possibleIntegerValue = 2
case “3”, “٣”, “三”, “๓”:
possibleIntegerValue = 3
case “4”, “٤”, “四”, “๔”:
possibleIntegerValue = 4
default:
break
}
if let integerValue = possibleIntegerValue {
println(“The integer value of \(numberSymbol) is \(integerValue).”)
} else {
println(“An integer value could not be found for \(numberSymbol).”)
}
// prints “The integer value of 三 is 3.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly