> For the complete documentation index, see [llms.txt](https://swift.unicorndonkeys.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://swift.unicorndonkeys.com/riferimento-del-linguaggio/istruzioni.md).

# Istruzioni (Statements)

Raggruppa le espressioni e controlla il flusso di esecuzione.

In Swift esistono tre tipi di istruzioni: istruzioni semplici, istruzioni di controllo del compilatore e istruzioni di controllo del flusso. Le istruzioni semplici sono le più comuni e sono costituite da un'espressione o da una dichiarazione. Le istruzioni di controllo del compilatore permettono al programma di modificare aspetti del comportamento del compilatore e comprendono un blocco di compilazione condizionale e un'istruzione di controllo di riga.

Le istruzioni di controllo del flusso sono usate per controllare il flusso di esecuzione in un programma. In Swift esistono diversi tipi di istruzioni di controllo del flusso, tra cui le istruzioni di ciclo, le istruzioni di diramazione e le istruzioni di trasferimento del controllo. Le istruzioni di ciclo permettono di eseguire ripetutamente un blocco di codice, le istruzioni di diramazione permettono di eseguire un certo blocco di codice solo quando sono soddisfatte determinate condizioni, e le istruzioni di trasferimento del controllo forniscono un modo per alterare l'ordine in cui il codice viene eseguito. Inoltre, Swift fornisce un'istruzione `do` per introdurre un ambito, e catturare e gestire gli errori, e un'istruzione `defer` per eseguire azioni di pulizia subito prima dell'uscita dall'ambito corrente.

Un punto e virgola (`;`) può comparire facoltativamente dopo qualsiasi istruzione e serve a separare più istruzioni se compaiono sulla stessa riga.

{% hint style="info" %}
**Grammatica di un'istruzione:**

*statement* → *expression* **`;`***?*\
*statement* → *declaration* **`;`***?*\
*statement* → *loop-statement* **`;`***?*\
*statement* → *branch-statement* **`;`***?*\
*statement* → *labeled-statement* **`;`***?*\
*statement* → *control-transfer-statement* **`;`***?*\
*statement* → *defer-statement* **`;`***?*\
*statement* → *do-statement* **`;`***?*\
*statement* → *compiler-control-statement*\
*statements* → *statement* *statements?*
{% endhint %}

## Istruzioni di ciclo <a href="#istruzioni-di-ciclo" id="istruzioni-di-ciclo"></a>

Le istruzioni di ciclo permettono di eseguire ripetutamente un blocco di codice, a seconda delle condizioni specificate nel ciclo. Swift ha tre istruzioni di ciclo: un'istruzione `for`-`in`, un'istruzione `while` e un'istruzione `repeat`-`while`.

Il flusso di controllo in un'istruzione di ciclo può essere modificato da un'istruzione `break` e da un'istruzione `continue`, ed è discusso più avanti in [Istruzione break](/riferimento-del-linguaggio/istruzioni.md#istruzione-break) e in [Istruzione continue](/riferimento-del-linguaggio/istruzioni.md#istruzione-continue).

{% hint style="info" %}
**Grammatica di un'istruzione di ciclo:**

*loop-statement* → *for-in-statement*\
*loop-statement* → *while-statement*\
*loop-statement* → *repeat-while-statement*
{% endhint %}

### Istruzione for-in <a href="#istruzione-for-in" id="istruzione-for-in"></a>

Un'istruzione `for`-`in` permette di eseguire un blocco di codice una volta per ciascun elemento di una collezione (o di qualsiasi tipo) conforme al protocollo [`Sequence`](https://developer.apple.com/documentation/swift/sequence).

Un'istruzione `for`-`in` ha la forma seguente:

```swift
for <#item#> in <#collection#> {
   <#statements#>
}
```

Sull'espressione *collection* viene chiamato il metodo `makeIterator()` per ottenere un valore di un tipo iteratore — cioè, un tipo conforme al protocollo [`IteratorProtocol`](https://developer.apple.com/documentation/swift/iteratorprotocol). Il programma inizia a eseguire un ciclo chiamando il metodo `next()` sull'iteratore. Se il valore restituito non è `nil`, viene assegnato al pattern *item*, il programma esegue le *statements* (istruzioni), e poi prosegue l'esecuzione dall'inizio del ciclo. Altrimenti, il programma non esegue l'assegnamento né le *statements*, e ha terminato l'esecuzione dell'istruzione `for`-`in`.

{% hint style="info" %}
**Grammatica di un'istruzione for-in:**

*for-in-statement* → **`for`** **`case`***?* *pattern* **`in`** *expression* *where-clause?* *code-block*
{% endhint %}

### Istruzione while <a href="#istruzione-while" id="istruzione-while"></a>

Un'istruzione `while` permette di eseguire ripetutamente un blocco di codice, finché una condizione rimane vera.

Un'istruzione `while` ha la forma seguente:

```swift
while <#condition#> {
   <#statements#>
}
```

Un'istruzione `while` viene eseguita come segue:

1. Viene valutata la *condition* (condizione).

   Se è `true`, l'esecuzione prosegue al passo 2. Se è `false`, il programma ha terminato l'esecuzione dell'istruzione `while`.
2. Il programma esegue le *statements*, e l'esecuzione torna al passo 1.

Poiché il valore della *condition* viene valutato prima che vengano eseguite le *statements*, le *statements* di un'istruzione `while` possono essere eseguite zero o più volte.

Il valore della *condition* deve essere di tipo `Bool` o di un tipo collegato (bridged) a `Bool`. La condizione può anche essere una dichiarazione di optional binding, come discusso in [Optional binding](/guida-al-linguaggio/le-basi.md#optional-binding).

{% hint style="info" %}
**Grammatica di un'istruzione while:**

*while-statement* → **`while`** *condition-list* *code-block*

*condition-list* → *condition* | *condition* **`,`** *condition-list*\
*condition* → *expression* | *availability-condition* | *case-condition* | *optional-binding-condition*

*case-condition* → **`case`** *pattern* *initializer*\
*optional-binding-condition* → **`let`** *pattern* *initializer?* | **`var`** *pattern* *initializer?*
{% endhint %}

### Istruzione repeat-while <a href="#istruzione-repeat-while" id="istruzione-repeat-while"></a>

Un'istruzione `repeat`-`while` permette di eseguire un blocco di codice una o più volte, finché una condizione rimane vera.

Un'istruzione `repeat`-`while` ha la forma seguente:

```swift
repeat {
   <#statements#>
} while <#condition#>
```

Un'istruzione `repeat`-`while` viene eseguita come segue:

1. Il programma esegue le *statements*, e l'esecuzione prosegue al passo 2.
2. Viene valutata la *condition*.

   Se è `true`, l'esecuzione torna al passo 1. Se è `false`, il programma ha terminato l'esecuzione dell'istruzione `repeat`-`while`.

Poiché il valore della *condition* viene valutato dopo che sono state eseguite le *statements*, le *statements* di un'istruzione `repeat`-`while` vengono eseguite almeno una volta.

Il valore della *condition* deve essere di tipo `Bool` o di un tipo collegato (bridged) a `Bool`.

{% hint style="info" %}
**Grammatica di un'istruzione repeat-while:**

*repeat-while-statement* → **`repeat`** *code-block* **`while`** *expression*
{% endhint %}

## Istruzioni di diramazione <a href="#istruzioni-di-diramazione" id="istruzioni-di-diramazione"></a>

Le istruzioni di diramazione permettono al programma di eseguire certe parti di codice a seconda del valore di una o più condizioni. I valori delle condizioni specificate in un'istruzione di diramazione controllano come il programma si dirama e, quindi, quale blocco di codice viene eseguito. Swift ha tre istruzioni di diramazione: un'istruzione `if`, un'istruzione `guard` e un'istruzione `switch`.

Il flusso di controllo in un'istruzione `if` o in un'istruzione `switch` può essere modificato da un'istruzione `break` ed è discusso più avanti in [Istruzione break](/riferimento-del-linguaggio/istruzioni.md#istruzione-break).

{% hint style="info" %}
**Grammatica di un'istruzione di diramazione:**

*branch-statement* → *if-statement*\
*branch-statement* → *guard-statement*\
*branch-statement* → *switch-statement*
{% endhint %}

### Istruzione if <a href="#istruzione-if" id="istruzione-if"></a>

Un'istruzione `if` è usata per eseguire codice in base alla valutazione di una o più condizioni.

Esistono due forme di base di un'istruzione `if`. In ciascuna forma, le parentesi graffe di apertura e di chiusura sono obbligatorie.

La prima forma permette di eseguire codice solo quando una condizione è vera e ha la forma seguente:

```swift
if <#condition#> {
   <#statements#>
}
```

La seconda forma di un'istruzione `if` fornisce una *clausola else* aggiuntiva (introdotta dalla parola chiave `else`) ed è usata per eseguire una parte di codice quando la condizione è vera e un'altra parte di codice quando la stessa condizione è falsa. Quando è presente un'unica clausola else, un'istruzione `if` ha la forma seguente:

```swift
if <#condition#> {
   <#statements to execute if condition is true#>
} else {
   <#statements to execute if condition is false#>
}
```

La clausola else di un'istruzione `if` può contenere un'altra istruzione `if` per verificare più di una condizione. Un'istruzione `if` concatenata in questo modo ha la forma seguente:

```swift
if <#condition 1#> {
   <#statements to execute if condition 1 is true#>
} else if <#condition 2#> {
   <#statements to execute if condition 2 is true#>
} else {
   <#statements to execute if both conditions are false#>
}
```

Il valore di qualsiasi condizione in un'istruzione `if` deve essere di tipo `Bool` o di un tipo collegato (bridged) a `Bool`. La condizione può anche essere una dichiarazione di optional binding, come discusso in [Optional binding](/guida-al-linguaggio/le-basi.md#optional-binding).

{% hint style="info" %}
**Grammatica di un'istruzione if:**

*if-statement* → **`if`** *condition-list* *code-block* *else-clause?*\
*else-clause* → **`else`** *code-block* | **`else`** *if-statement*
{% endhint %}

### Istruzione guard <a href="#istruzione-guard" id="istruzione-guard"></a>

Un'istruzione `guard` è usata per trasferire il controllo del programma al di fuori di un ambito se una o più condizioni non sono soddisfatte.

Un'istruzione `guard` ha la forma seguente:

```swift
guard <#condition#> else {
   <#statements#>
}
```

Il valore di qualsiasi condizione in un'istruzione `guard` deve essere di tipo `Bool` o di un tipo collegato (bridged) a `Bool`. La condizione può anche essere una dichiarazione di optional binding, come discusso in [Optional binding](/guida-al-linguaggio/le-basi.md#optional-binding).

Qualsiasi costante o variabile a cui è stato assegnato un valore da una dichiarazione di optional binding nella condizione di un'istruzione `guard` può essere usata per il resto dell'ambito che racchiude l'istruzione guard.

La clausola `else` di un'istruzione `guard` è obbligatoria, e deve chiamare una funzione con tipo di ritorno `Never` oppure trasferire il controllo del programma al di fuori dell'ambito che racchiude l'istruzione guard usando una delle istruzioni seguenti:

* `return`
* `break`
* `continue`
* `throw`

Le istruzioni di trasferimento del controllo sono discusse più avanti in [Istruzioni di trasferimento del controllo](/riferimento-del-linguaggio/istruzioni.md#istruzioni-di-trasferimento-del-controllo). Per maggiori informazioni sulle funzioni con tipo di ritorno `Never`, vedi [Funzioni che non restituiscono mai](/riferimento-del-linguaggio/dichiarazioni.md#funzioni-che-non-restituiscono-mai).

{% hint style="info" %}
**Grammatica di un'istruzione guard:**

*guard-statement* → **`guard`** *condition-list* **`else`** *code-block*
{% endhint %}

### Istruzione switch <a href="#istruzione-switch" id="istruzione-switch"></a>

Un'istruzione `switch` permette di eseguire certi blocchi di codice a seconda del valore di un'espressione di controllo.

Un'istruzione `switch` ha la forma seguente:

```swift
switch <#control expression#> {
case <#pattern 1#>:
    <#statements#>
case <#pattern 2#> where <#condition#>:
    <#statements#>
case <#pattern 3#> where <#condition#>,
    <#pattern 4#> where <#condition#>:
    <#statements#>
default:
    <#statements#>
}
```

La *control expression* (espressione di controllo) dell'istruzione `switch` viene valutata e poi confrontata con i pattern specificati in ciascun caso. Se viene trovata una corrispondenza, il programma esegue le *statements* elencate nell'ambito di quel caso. L'ambito di ciascun caso non può essere vuoto. Di conseguenza, devi includere almeno un'istruzione dopo i due punti (`:`) di ciascuna etichetta case. Usa un'unica istruzione `break` se non intendi eseguire alcun codice nel corpo di un caso corrispondente.

I valori delle espressioni su cui il tuo codice può diramarsi sono molto flessibili. Per esempio, oltre ai valori dei tipi scalari, come interi e caratteri, il tuo codice può diramarsi sui valori di qualsiasi tipo, compresi numeri in virgola mobile, stringhe, tuple, istanze di classi personalizzate e opzionali. Il valore della *control expression* può persino essere confrontato con il valore di un caso di un'enumerazione e verificato per l'inclusione in un intervallo di valori specificato. Per esempi di come usare questi vari tipi di valori nelle istruzioni `switch`, vedi [Switch](/guida-al-linguaggio/flusso-di-controllo.md#switch) in [Flusso di controllo](/guida-al-linguaggio/flusso-di-controllo.md).

Un caso `switch` può facoltativamente contenere una clausola `where` dopo ciascun pattern. Una *clausola where* è introdotta dalla parola chiave `where` seguita da un'espressione, ed è usata per fornire una condizione aggiuntiva prima che un pattern di un caso sia considerato corrispondente alla *control expression*. Se è presente una clausola `where`, le *statements* del caso pertinente vengono eseguite solo se il valore della *control expression* corrisponde a uno dei pattern del caso e l'espressione della clausola `where` restituisce `true`. Per esempio, una *control expression* corrisponde al caso dell'esempio seguente solo se è una tupla che contiene due elementi con lo stesso valore, come `(1, 1)`.

```swift
case let (x, y) where x == y:
```

Come mostra l'esempio qui sopra, i pattern di un caso possono anche associare costanti usando la parola chiave `let` (possono anche associare variabili usando la parola chiave `var`). Queste costanti (o variabili) possono poi essere referenziate in una clausola `where` corrispondente e in tutto il resto del codice nell'ambito del caso. Se il caso contiene più pattern che corrispondono all'espressione di controllo, tutti i pattern devono contenere gli stessi binding di costanti o variabili, e ciascuna variabile o costante associata deve avere lo stesso tipo in tutti i pattern del caso.

Un'istruzione `switch` può includere anche un caso predefinito, introdotto dalla parola chiave `default`. Il codice all'interno di un caso predefinito viene eseguito solo se nessun altro caso corrisponde all'espressione di controllo. Un'istruzione `switch` può includere un solo caso predefinito, che deve comparire alla fine dell'istruzione `switch`.

Sebbene l'effettivo ordine di esecuzione delle operazioni di pattern matching, e in particolare l'ordine di valutazione dei pattern nei casi, non sia specificato, il pattern matching in un'istruzione `switch` si comporta come se la valutazione venisse eseguita nell'ordine del sorgente — cioè, nell'ordine in cui i pattern compaiono nel codice sorgente. Di conseguenza, se più casi contengono pattern che restituiscono lo stesso valore, e che quindi possono corrispondere al valore dell'espressione di controllo, il programma esegue solo il codice del primo caso corrispondente nell'ordine del sorgente.

#### Le istruzioni switch devono essere esaustive <a href="#le-istruzioni-switch-devono-essere-esaustive" id="le-istruzioni-switch-devono-essere-esaustive"></a>

In Swift, ogni possibile valore del tipo dell'espressione di controllo deve corrispondere al valore di almeno un pattern di un caso. Quando questo semplicemente non è fattibile (per esempio, quando il tipo dell'espressione di controllo è `Int`), puoi includere un caso predefinito per soddisfare il requisito.

#### Switch sui casi futuri di un'enumerazione <a href="#switch-sui-casi-futuri-di-unenumerazione" id="switch-sui-casi-futuri-di-unenumerazione"></a>

Un'*enumerazione non congelata* (nonfrozen) è un tipo speciale di enumerazione che potrebbe acquisire nuovi casi in futuro — anche dopo che hai compilato e distribuito un'app. Eseguire uno switch su un'enumerazione non congelata richiede un'attenzione particolare. Quando gli autori di una libreria contrassegnano un'enumerazione come non congelata, si riservano il diritto di aggiungere nuovi casi all'enumerazione, e qualsiasi codice che interagisce con quell'enumerazione *deve* essere in grado di gestire quei casi futuri senza essere ricompilato. Il codice compilato in modalità library evolution, il codice della libreria standard di Swift, gli overlay Swift per i framework Apple e il codice C e Objective-C possono dichiarare enumerazioni non congelate. Per informazioni sulle enumerazioni congelate e non congelate, vedi [frozen](/riferimento-del-linguaggio/attributi.md#frozen).

Quando esegui uno switch sul valore di un'enumerazione non congelata, devi sempre includere un caso predefinito, anche se ogni caso dell'enumerazione ha già un caso switch corrispondente. Puoi applicare l'attributo `@unknown` al caso predefinito, il che indica che il caso predefinito deve corrispondere solo ai casi dell'enumerazione che verranno aggiunti in futuro. Swift produce un avviso se il caso predefinito corrisponde a un qualsiasi caso dell'enumerazione noto in fase di compilazione. Questo avviso futuro ti informa che l'autore della libreria ha aggiunto all'enumerazione un nuovo caso che non ha un caso switch corrispondente.

L'esempio seguente esegue uno switch su tutti e tre i casi esistenti dell'enumerazione [`Mirror.AncestorRepresentation`](https://developer.apple.com/documentation/swift/mirror/ancestorrepresentation) della libreria standard di Swift. Se in futuro vengono aggiunti altri casi, il compilatore genera un avviso per indicare che devi aggiornare l'istruzione switch per tenere conto dei nuovi casi.

```swift
let representation: Mirror.AncestorRepresentation = .generated
switch representation {
case .customized:
    print("Use the nearest ancestor’s implementation.")
case .generated:
    print("Generate a default mirror for all ancestor classes.")
case .suppressed:
    print("Suppress the representation of all ancestor classes.")
@unknown default:
    print("Use a representation that was unknown when this code was compiled.")
}
// Stampa "Generate a default mirror for all ancestor classes."
```

#### L'esecuzione non prosegue implicitamente da un caso all'altro <a href="#lesecuzione-non-prosegue-implicitamente-da-un-caso-allaltro" id="lesecuzione-non-prosegue-implicitamente-da-un-caso-allaltro"></a>

Dopo che il codice all'interno di un caso corrispondente ha terminato l'esecuzione, il programma esce dall'istruzione `switch`. L'esecuzione del programma non continua né "prosegue" (fall through) al caso successivo o al caso predefinito. Detto questo, se vuoi che l'esecuzione continui da un caso al successivo, includi esplicitamente un'istruzione `fallthrough`, costituita semplicemente dalla parola chiave `fallthrough`, nel caso da cui vuoi che l'esecuzione continui. Per maggiori informazioni sull'istruzione `fallthrough`, vedi più avanti [Istruzione fallthrough](/riferimento-del-linguaggio/istruzioni.md#istruzione-fallthrough).

{% hint style="info" %}
**Grammatica di un'istruzione switch:**

*switch-statement* → **`switch`** *expression* **`{`** *switch-cases?* **`}`**\
*switch-cases* → *switch-case* *switch-cases?*\
*switch-case* → *case-label* *statements*\
*switch-case* → *default-label* *statements*\
*switch-case* → *conditional-switch-case*

*case-label* → *attributes?* **`case`** *case-item-list* **`:`**\
*case-item-list* → *pattern* *where-clause?* | *pattern* *where-clause?* **`,`** *case-item-list*\
*default-label* → *attributes?* **`default`** **`:`**

*where-clause* → **`where`** *where-expression*\
*where-expression* → *expression*

*conditional-switch-case* → *switch-if-directive-clause* *switch-elseif-directive-clauses?* *switch-else-directive-clause?* *endif-directive*\
*switch-if-directive-clause* → *if-directive* *compilation-condition* *switch-cases?*\
*switch-elseif-directive-clauses* → *elseif-directive-clause* *switch-elseif-directive-clauses?*\
*switch-elseif-directive-clause* → *elseif-directive* *compilation-condition* *switch-cases?*\
*switch-else-directive-clause* → *else-directive* *switch-cases?*
{% endhint %}

## Istruzione etichettata <a href="#istruzione-etichettata" id="istruzione-etichettata"></a>

Puoi anteporre a un'istruzione di ciclo, a un'istruzione `if`, a un'istruzione `switch` o a un'istruzione `do` un'*etichetta di istruzione*, costituita dal nome dell'etichetta seguito immediatamente da due punti (:). Usa le etichette di istruzione con le istruzioni `break` e `continue` per essere espliciti su come vuoi modificare il flusso di controllo in un'istruzione di ciclo o in un'istruzione `switch`, come discusso più avanti in [Istruzione break](/riferimento-del-linguaggio/istruzioni.md#istruzione-break) e in [Istruzione continue](/riferimento-del-linguaggio/istruzioni.md#istruzione-continue).

L'ambito di un'istruzione etichettata è l'intera istruzione che segue l'etichetta di istruzione. Puoi annidare istruzioni etichettate, ma il nome di ciascuna etichetta di istruzione deve essere univoco.

Per maggiori informazioni e per vedere esempi di come usare le etichette di istruzione, vedi [Istruzioni etichettate](/guida-al-linguaggio/flusso-di-controllo.md#istruzioni-etichettate) in [Flusso di controllo](/guida-al-linguaggio/flusso-di-controllo.md).

{% hint style="info" %}
**Grammatica di un'istruzione etichettata:**

*labeled-statement* → *statement-label* *loop-statement*\
*labeled-statement* → *statement-label* *if-statement*\
*labeled-statement* → *statement-label* *switch-statement*\
*labeled-statement* → *statement-label* *do-statement*

*statement-label* → *label-name* **`:`**\
*label-name* → *identifier*
{% endhint %}

## Istruzioni di trasferimento del controllo <a href="#istruzioni-di-trasferimento-del-controllo" id="istruzioni-di-trasferimento-del-controllo"></a>

Le istruzioni di trasferimento del controllo possono cambiare l'ordine in cui viene eseguito il codice del tuo programma trasferendo incondizionatamente il controllo del programma da una porzione di codice a un'altra. Swift ha cinque istruzioni di trasferimento del controllo: un'istruzione `break`, un'istruzione `continue`, un'istruzione `fallthrough`, un'istruzione `return` e un'istruzione `throw`.

{% hint style="info" %}
**Grammatica di un'istruzione di trasferimento del controllo:**

*control-transfer-statement* → *break-statement*\
*control-transfer-statement* → *continue-statement*\
*control-transfer-statement* → *fallthrough-statement*\
*control-transfer-statement* → *return-statement*\
*control-transfer-statement* → *throw-statement*
{% endhint %}

### Istruzione break <a href="#istruzione-break" id="istruzione-break"></a>

Un'istruzione `break` termina l'esecuzione di un ciclo, di un'istruzione `if` o di un'istruzione `switch`. Un'istruzione `break` può essere costituita dalla sola parola chiave `break`, oppure dalla parola chiave `break` seguita dal nome di un'etichetta di istruzione, come mostrato di seguito.

```swift
break
break <#label name#>
```

Quando un'istruzione `break` è seguita dal nome di un'etichetta di istruzione, termina l'esecuzione del ciclo, dell'istruzione `if` o dell'istruzione `switch` indicata da quell'etichetta.

Quando un'istruzione `break` non è seguita dal nome di un'etichetta di istruzione, termina l'esecuzione dell'istruzione `switch` o dell'istruzione di ciclo più interna che la racchiude. Non puoi usare un'istruzione `break` non etichettata per uscire da un'istruzione `if`.

In entrambi i casi, il controllo del programma viene poi trasferito alla prima riga di codice che segue il ciclo o l'istruzione `switch` che la racchiude, se presente.

Per esempi di come usare un'istruzione `break`, vedi [Break](/guida-al-linguaggio/flusso-di-controllo.md#break) e [Istruzioni etichettate](/guida-al-linguaggio/flusso-di-controllo.md#istruzioni-etichettate) in [Flusso di controllo](/guida-al-linguaggio/flusso-di-controllo.md).

{% hint style="info" %}
**Grammatica di un'istruzione break:**

*break-statement* → **`break`** *label-name?*
{% endhint %}

### Istruzione continue <a href="#istruzione-continue" id="istruzione-continue"></a>

Un'istruzione `continue` termina l'esecuzione dell'iterazione corrente di un'istruzione di ciclo ma non interrompe l'esecuzione dell'istruzione di ciclo. Un'istruzione `continue` può essere costituita dalla sola parola chiave `continue`, oppure dalla parola chiave `continue` seguita dal nome di un'etichetta di istruzione, come mostrato di seguito.

```swift
continue
continue <#label name#>
```

Quando un'istruzione `continue` è seguita dal nome di un'etichetta di istruzione, termina l'esecuzione dell'iterazione corrente dell'istruzione di ciclo indicata da quell'etichetta.

Quando un'istruzione `continue` non è seguita dal nome di un'etichetta di istruzione, termina l'esecuzione dell'iterazione corrente dell'istruzione di ciclo più interna che la racchiude.

In entrambi i casi, il controllo del programma viene poi trasferito alla condizione dell'istruzione di ciclo che la racchiude.

In un'istruzione `for`, l'espressione di incremento viene comunque valutata dopo l'esecuzione dell'istruzione `continue`, perché l'espressione di incremento viene valutata dopo l'esecuzione del corpo del ciclo.

Per esempi di come usare un'istruzione `continue`, vedi [Continue](/guida-al-linguaggio/flusso-di-controllo.md#continue) e [Istruzioni etichettate](/guida-al-linguaggio/flusso-di-controllo.md#istruzioni-etichettate) in [Flusso di controllo](/guida-al-linguaggio/flusso-di-controllo.md).

{% hint style="info" %}
**Grammatica di un'istruzione continue:**

*continue-statement* → **`continue`** *label-name?*
{% endhint %}

### Istruzione fallthrough <a href="#istruzione-fallthrough" id="istruzione-fallthrough"></a>

Un'istruzione `fallthrough` è costituita dalla parola chiave `fallthrough` e compare solo nel blocco di un caso di un'istruzione `switch`. Un'istruzione `fallthrough` fa sì che l'esecuzione del programma prosegua da un caso di un'istruzione `switch` al caso successivo. L'esecuzione del programma prosegue al caso successivo anche se i pattern dell'etichetta case non corrispondono al valore dell'espressione di controllo dell'istruzione `switch`.

Un'istruzione `fallthrough` può comparire ovunque all'interno di un'istruzione `switch`, non solo come ultima istruzione del blocco di un caso, ma non può essere usata nel blocco dell'ultimo caso. Inoltre non può trasferire il controllo nel blocco di un caso il cui pattern contiene pattern di value binding.

Per un esempio di come usare un'istruzione `fallthrough` in un'istruzione `switch`, vedi [Istruzioni di trasferimento del controllo](/guida-al-linguaggio/flusso-di-controllo.md#istruzioni-di-trasferimento-del-controllo) in [Flusso di controllo](/guida-al-linguaggio/flusso-di-controllo.md).

{% hint style="info" %}
**Grammatica di un'istruzione fallthrough:**

*fallthrough-statement* → **`fallthrough`**
{% endhint %}

### Istruzione return <a href="#istruzione-return" id="istruzione-return"></a>

Un'istruzione `return` compare nel corpo della definizione di una funzione o di un metodo e fa sì che l'esecuzione del programma torni alla funzione o al metodo chiamante. L'esecuzione del programma prosegue nel punto immediatamente successivo alla chiamata della funzione o del metodo.

Un'istruzione `return` può essere costituita dalla sola parola chiave `return`, oppure dalla parola chiave `return` seguita da un'espressione, come mostrato di seguito.

```swift
return
return <#expression#>
```

Quando un'istruzione `return` è seguita da un'espressione, il valore dell'espressione viene restituito alla funzione o al metodo chiamante. Se il valore dell'espressione non corrisponde al valore del tipo di ritorno dichiarato nella dichiarazione della funzione o del metodo, il valore dell'espressione viene convertito nel tipo di ritorno prima di essere restituito alla funzione o al metodo chiamante.

{% hint style="info" %}
**Nota:** Come descritto in [Inizializzatori failable](/riferimento-del-linguaggio/dichiarazioni.md#inizializzatori-failable), una forma speciale dell'istruzione `return` (`return nil`) può essere usata in un inizializzatore failable per indicare il fallimento dell'inizializzazione.
{% endhint %}

Quando un'istruzione `return` non è seguita da un'espressione, può essere usata solo per restituire il controllo da una funzione o da un metodo che non restituisce un valore (cioè, quando il tipo di ritorno della funzione o del metodo è `Void` o `()`).

{% hint style="info" %}
**Grammatica di un'istruzione return:**

*return-statement* → **`return`** *expression?*
{% endhint %}

### Istruzione throw <a href="#istruzione-throw" id="istruzione-throw"></a>

Un'istruzione `throw` compare nel corpo di una funzione o di un metodo che lancia errori, o nel corpo di un'espressione closure il cui tipo è contrassegnato con la parola chiave `throws`.

Un'istruzione `throw` fa sì che un programma termini l'esecuzione dell'ambito corrente e inizi la propagazione dell'errore all'ambito che lo racchiude. L'errore lanciato continua a propagarsi finché non viene gestito da una clausola `catch` di un'istruzione `do`.

Un'istruzione `throw` è costituita dalla parola chiave `throw` seguita da un'espressione, come mostrato di seguito.

```swift
throw <#expression#>
```

Il valore dell'*expression* deve avere un tipo conforme al protocollo `Error`. Se l'istruzione `do` o la funzione che contiene l'istruzione `throw` dichiara il tipo degli errori che lancia, il valore dell'*expression* deve essere un'istanza di quel tipo.

Per un esempio di come usare un'istruzione `throw`, vedi [Propagare gli errori usando funzioni che lanciano errori](/guida-al-linguaggio/gestione-degli-errori.md#propagare-gli-errori-usando-funzioni-che-lanciano-errori) in [Gestione degli errori](/guida-al-linguaggio/gestione-degli-errori.md).

{% hint style="info" %}
**Grammatica di un'istruzione throw:**

*throw-statement* → **`throw`** *expression*
{% endhint %}

## Istruzione defer <a href="#istruzione-defer" id="istruzione-defer"></a>

Un'istruzione `defer` è usata per eseguire del codice subito prima di trasferire il controllo del programma al di fuori dell'ambito in cui compare l'istruzione `defer`.

Un'istruzione `defer` ha la forma seguente:

```swift
defer {
    <#statements#>
}
```

Le istruzioni all'interno dell'istruzione `defer` vengono eseguite indipendentemente da come viene trasferito il controllo del programma. Ciò significa che un'istruzione `defer` può essere usata, per esempio, per eseguire una gestione manuale delle risorse come la chiusura dei descrittori di file, e per eseguire azioni che devono avvenire anche se viene lanciato un errore.

Le *statements* dell'istruzione `defer` vengono eseguite alla fine dell'ambito che racchiude l'istruzione `defer`.

```swift
func f(x: Int) {
  defer { print("First defer") }

  if x < 10 {
    defer { print("Second defer") }
    print("End of if")
  }

  print("End of function")
}
f(x: 5)
// Stampa "End of if".
// Stampa "Second defer".
// Stampa "End of function".
// Stampa "First defer".
```

Nel codice qui sopra, il `defer` nell'istruzione `if` viene eseguito prima del `defer` dichiarato nella funzione `f` perché l'ambito dell'istruzione `if` termina prima dell'ambito della funzione.

Se più istruzioni `defer` compaiono nello stesso ambito, l'ordine in cui compaiono è l'inverso dell'ordine in cui vengono eseguite. Eseguire per prima l'ultima istruzione `defer` di un dato ambito significa che le istruzioni all'interno di quell'ultima istruzione `defer` possono fare riferimento a risorse che verranno ripulite da altre istruzioni `defer`.

```swift
func f() {
    defer { print("First defer") }
    defer { print("Second defer") }
    print("End of function")
}
f()
// Stampa "End of function".
// Stampa "Second defer".
// Stampa "First defer".
```

Le istruzioni all'interno dell'istruzione `defer` non possono trasferire il controllo del programma al di fuori dell'istruzione `defer`.

{% hint style="info" %}
**Grammatica di un'istruzione defer:**

*defer-statement* → **`defer`** *code-block*
{% endhint %}

## Istruzione do <a href="#istruzione-do" id="istruzione-do"></a>

L'istruzione `do` è usata per introdurre un nuovo ambito e può facoltativamente contenere una o più clausole `catch`, che contengono pattern confrontati con condizioni di errore definite. Le variabili e le costanti dichiarate nell'ambito di un'istruzione `do` sono accessibili solo all'interno di quell'ambito.

Un'istruzione `do` in Swift è simile alle parentesi graffe (`{}`) usate in C per delimitare un blocco di codice, e non comporta alcun costo in termini di prestazioni in fase di esecuzione.

Un'istruzione `do` ha la forma seguente:

```swift
do {
    try <#expression#>
    <#statements#>
} catch <#pattern 1#> {
    <#statements#>
} catch <#pattern 2#> where <#condition#> {
    <#statements#>
} catch <#pattern 3#>, <#pattern 4#> where <#condition#> {
    <#statements#>
} catch {
    <#statements#>
}
```

Un'istruzione `do` può facoltativamente specificare il tipo di errore che lancia, con la forma seguente:

```swift
do throws(<#type#>) {
    try <#expression#>
} catch <#pattern> {
    <#statements#>
} catch {
    <#statements#>
}
```

Se l'istruzione `do` include una clausola `throws`, il blocco `do` può lanciare solo errori del *type* (tipo) specificato. Il *type* deve essere un tipo concreto conforme al protocollo `Error`, un tipo opaco conforme al protocollo `Error`, oppure il tipo protocollo boxed `any Error`. Se l'istruzione `do` non specifica il tipo di errore che lancia, Swift inferisce il tipo di errore come segue:

* Se ogni istruzione `throws` ed espressione `try` nel blocco di codice `do` è annidata all'interno di un meccanismo esaustivo di gestione degli errori, allora Swift inferisce che l'istruzione `do` non lancia errori.
* Se il blocco di codice `do` contiene codice che lancia errori di un solo tipo al di fuori di una gestione esaustiva degli errori, diverso dal lancio di `Never`, allora Swift inferisce che l'istruzione `do` lancia quel tipo di errore concreto.
* Se il blocco di codice `do` contiene codice che lancia errori di più di un tipo al di fuori di una gestione esaustiva degli errori, allora Swift inferisce che l'istruzione `do` lancia `any Error`.

Per maggiori informazioni su come lavorare con errori che hanno tipi espliciti, vedi [Specificare il tipo di errore](/guida-al-linguaggio/gestione-degli-errori.md#specificare-il-tipo-di-errore).

Se una qualsiasi istruzione nel blocco di codice `do` lancia un errore, il controllo del programma viene trasferito alla prima clausola `catch` il cui pattern corrisponde all'errore. Se nessuna delle clausole corrisponde, l'errore si propaga all'ambito circostante. Se un errore non viene gestito al livello più alto, l'esecuzione del programma si interrompe con un errore in fase di esecuzione.

Come per un'istruzione `switch`, il compilatore tenta di inferire se le clausole `catch` sono esaustive. Se è possibile stabilirlo, l'errore è considerato gestito. Altrimenti, l'errore può propagarsi al di fuori dell'ambito che lo contiene, il che significa che l'errore deve essere gestito da una clausola `catch` che lo racchiude oppure che la funzione che lo contiene deve essere dichiarata con `throws`.

Una clausola `catch` che ha più pattern corrisponde all'errore se uno qualsiasi dei suoi pattern corrisponde all'errore. Se una clausola `catch` contiene più pattern, tutti i pattern devono contenere gli stessi binding di costanti o variabili, e ogni variabile o costante vincolata deve avere lo stesso tipo in tutti i pattern della clausola `catch`.

Per garantire che un errore venga gestito, usa una clausola `catch` con un pattern che corrisponde a tutti gli errori, come un pattern wildcard (`_`). Se una clausola `catch` non specifica un pattern, la clausola `catch` corrisponde a qualsiasi errore e lo vincola a una costante locale chiamata `error`. Per maggiori informazioni sui pattern che puoi usare in una clausola `catch`, vedi [Pattern](/riferimento-del-linguaggio/pattern.md).

Per vedere un esempio di come usare un'istruzione `do` con diverse clausole `catch`, vedi [Gestire gli errori](/guida-al-linguaggio/gestione-degli-errori.md#gestire-gli-errori).

{% hint style="info" %}
**Grammatica di un'istruzione do:**

*do-statement* → **`do`** *throws-clause?* *code-block* *catch-clauses?*\
*catch-clauses* → *catch-clause* *catch-clauses?*\
*catch-clause* → **`catch`** *catch-pattern-list?* *code-block*\
*catch-pattern-list* → *catch-pattern* | *catch-pattern* **`,`** *catch-pattern-list*\
*catch-pattern* → *pattern* *where-clause?*
{% endhint %}

## Istruzioni di controllo del compilatore <a href="#istruzioni-di-controllo-del-compilatore" id="istruzioni-di-controllo-del-compilatore"></a>

Le istruzioni di controllo del compilatore consentono al programma di modificare alcuni aspetti del comportamento del compilatore. Swift ha tre istruzioni di controllo del compilatore: un blocco di compilazione condizionale un'istruzione di controllo della riga e un'istruzione di diagnostica in fase di compilazione.

{% hint style="info" %}
**Grammatica di un'istruzione di controllo del compilatore:**

*compiler-control-statement* → *conditional-compilation-block*\
*compiler-control-statement* → *line-control-statement*\
*compiler-control-statement* → *diagnostic-statement*
{% endhint %}

### Blocco di compilazione condizionale <a href="#blocco-di-compilazione-condizionale" id="blocco-di-compilazione-condizionale"></a>

Un blocco di compilazione condizionale consente di compilare del codice in modo condizionale a seconda del valore di una o più condizioni di compilazione.

Ogni blocco di compilazione condizionale inizia con la direttiva di compilazione `#if` e termina con la direttiva di compilazione `#endif`. Un semplice blocco di compilazione condizionale ha la forma seguente:

```swift
#if <#compilation condition#>
    <#statements#>
#endif
```

A differenza della condizione di un'istruzione `if`, la *compilation condition* (condizione di compilazione) viene valutata in fase di compilazione. Di conseguenza, le *statements* vengono compilate ed eseguite solo se la *compilation condition* viene valutata come `true` in fase di compilazione.

La *compilation condition* può includere i letterali booleani `true` e `false`, un identificatore usato con il flag da riga di comando `-D`, oppure una qualsiasi delle condizioni di piattaforma elencate nella tabella seguente.

| Condizione di piattaforma | Argomenti validi                                                  |
| ------------------------- | ----------------------------------------------------------------- |
| `os()`                    | `macOS`, `iOS`, `watchOS`, `tvOS`, `visionOS`, `Linux`, `Windows` |
| `arch()`                  | `arm`, `arm64`, `i386`, `wasm32`, `x86_64`,                       |
| `swift()`                 | `>=` o `<` seguito da un numero di versione                       |
| `compiler()`              | `>=` o `<` seguito da un numero di versione                       |
| `canImport()`             | Il nome di un modulo                                              |
| `targetEnvironment()`     | `simulator`, `macCatalyst`                                        |

Il numero di versione per le condizioni di piattaforma `swift()` e `compiler()` è costituito da un numero principale, un numero secondario facoltativo, un numero di patch facoltativo e così via, con un punto (`.`) a separare ciascuna parte del numero di versione. Non devono esserci spazi tra l'operatore di confronto e il numero di versione. La versione per `compiler()` è la versione del compilatore, indipendentemente dall'impostazione della versione di Swift passata al compilatore. La versione per `swift()` è la versione del linguaggio attualmente in compilazione. Per esempio, se compili il tuo codice usando il compilatore di Swift 5 in modalità Swift 4.2, la versione del compilatore è 5 e la versione del linguaggio è 4.2. Con queste impostazioni, il codice seguente stampa tutti e tre i messaggi:

```swift
#if compiler(>=5)
print("Compiled with the Swift 5 compiler or later")
#endif
#if swift(>=4.2)
print("Compiled in Swift 4.2 mode or later")
#endif
#if compiler(>=5) && swift(<5)
print("Compiled with the Swift 5 compiler or later in a Swift mode earlier than 5")
#endif
// Stampa "Compiled with the Swift 5 compiler or later".
// Stampa "Compiled in Swift 4.2 mode or later".
// Stampa "Compiled with the Swift 5 compiler or later in a Swift mode earlier than 5".
```

L'argomento della condizione di piattaforma `canImport()` è il nome di un modulo che potrebbe non essere presente su tutte le piattaforme. Il nome del modulo può includere dei punti (`.`). Questa condizione verifica se è possibile importare il modulo, ma non lo importa effettivamente. Se il modulo è presente, la condizione di piattaforma restituisce `true`; altrimenti, restituisce `false`.

La condizione di piattaforma `targetEnvironment()` restituisce `true` quando il codice viene compilato per l'ambiente specificato; altrimenti, restituisce `false`.

{% hint style="info" %}
**Nota:** La condizione di piattaforma `arch(arm)` non restituisce `true` per i dispositivi ARM a 64 bit. La condizione di piattaforma `arch(i386)` restituisce `true` quando il codice viene compilato per il simulatore iOS a 32 bit.
{% endhint %}

Puoi combinare e negare le condizioni di compilazione usando gli operatori logici `&&`, `||` e `!` e usare le parentesi per raggrupparle. Questi operatori hanno la stessa associatività e precedenza degli operatori logici usati per combinare le normali espressioni booleane.

Analogamente a un'istruzione `if`, puoi aggiungere più rami condizionali per verificare diverse condizioni di compilazione. Puoi aggiungere un numero qualsiasi di rami aggiuntivi usando clausole `#elseif`. Puoi anche aggiungere un ultimo ramo aggiuntivo usando una clausola `#else`. I blocchi di compilazione condizionale che contengono più rami hanno la forma seguente:

```swift
#if <#compilation condition 1#>
    <#statements to compile if compilation condition 1 is true#>
#elseif <#compilation condition 2#>
    <#statements to compile if compilation condition 2 is true#>
#else
    <#statements to compile if both compilation conditions are false#>
#endif
```

{% hint style="info" %}
**Nota:** Ogni istruzione nel corpo di un blocco di compilazione condizionale viene analizzata anche se non viene compilata. Esiste tuttavia un'eccezione se la condizione di compilazione include una condizione di piattaforma `swift()` o `compiler()`: le istruzioni vengono analizzate solo se la versione del linguaggio o del compilatore corrisponde a quella specificata nella condizione di piattaforma. Questa eccezione garantisce che un compilatore meno recente non tenti di analizzare una sintassi introdotta in una versione più recente di Swift.
{% endhint %}

Per informazioni su come racchiudere espressioni membro esplicite in blocchi di compilazione condizionale, vedi [Espressione membro esplicita](/riferimento-del-linguaggio/espressioni.md#espressione-membro-esplicita).

{% hint style="info" %}
**Grammatica di un blocco di compilazione condizionale:**

*conditional-compilation-block* → *if-directive-clause* *elseif-directive-clauses?* *else-directive-clause?* *endif-directive*

*if-directive-clause* → *if-directive* *compilation-condition* *statements?*\
*elseif-directive-clauses* → *elseif-directive-clause* *elseif-directive-clauses?*\
*elseif-directive-clause* → *elseif-directive* *compilation-condition* *statements?*\
*else-directive-clause* → *else-directive* *statements?*\
*if-directive* → **`#if`**\
*elseif-directive* → **`#elseif`**\
*else-directive* → **`#else`**\
*endif-directive* → **`#endif`**

*compilation-condition* → *platform-condition*\
*compilation-condition* → *identifier*\
*compilation-condition* → *boolean-literal*\
*compilation-condition* → **`(`** *compilation-condition* **`)`**\
*compilation-condition* → **`!`** *compilation-condition*\
*compilation-condition* → *compilation-condition* **`&&`** *compilation-condition*\
*compilation-condition* → *compilation-condition* **`||`** *compilation-condition*

*platform-condition* → **`os`** **`(`** *operating-system* **`)`**\
*platform-condition* → **`arch`** **`(`** *architecture* **`)`**\
*platform-condition* → **`swift`** **`(`** **`>=`** *swift-version* **`)`** | **`swift`** **`(`** **`<`** *swift-version* **`)`**\
*platform-condition* → **`compiler`** **`(`** **`>=`** *swift-version* **`)`** | **`compiler`** **`(`** **`<`** *swift-version* **`)`**\
*platform-condition* → **`canImport`** **`(`** *import-path* **`)`**\
*platform-condition* → **`targetEnvironment`** **`(`** *environment* **`)`**

*operating-system* → **`macOS`** | **`iOS`** | **`watchOS`** | **`tvOS`** | **`visionOS`** | **`Linux`** | **`Windows`**\
*architecture* → **`arm`** | **`arm64`** | **`i386`** | **`wasm32`** | **`x86_64`**\
*swift-version* → *decimal-digits* *swift-version-continuation?*\
*swift-version-continuation* → **`.`** *decimal-digits* *swift-version-continuation?*\
*environment* → **`simulator`** | **`macCatalyst`**
{% endhint %}

### Istruzione di controllo della riga <a href="#istruzione-di-controllo-della-riga" id="istruzione-di-controllo-della-riga"></a>

Un'istruzione di controllo della riga è usata per specificare un numero di riga e un nome di file che possono essere diversi dal numero di riga e dal nome di file del codice sorgente in compilazione. Usa un'istruzione di controllo della riga per cambiare la posizione nel codice sorgente usata da Swift a scopo di diagnostica e di debug.

Un'istruzione di controllo della riga ha le forme seguenti:

```swift
#sourceLocation(file: <#file path#>, line: <#line number#>)
#sourceLocation()
```

La prima forma di un'istruzione di controllo della riga cambia i valori delle espressioni letterali `#line`, `#file`, `#fileID` e `#filePath`, a partire dalla riga di codice che segue l'istruzione di controllo della riga. Il *line number* (numero di riga) cambia il valore di `#line` ed è un qualsiasi letterale intero maggiore di zero. Il *file path* (percorso del file) cambia il valore di `#file`, `#fileID` e `#filePath` ed è un letterale stringa. La stringa specificata diventa il valore di `#filePath`, e l'ultimo componente del percorso della stringa è usato dal valore di `#fileID`. Per informazioni su `#file`, `#fileID` e `#filePath`, vedi [Espressione letterale](/riferimento-del-linguaggio/espressioni.md#espressione-letterale).

La seconda forma di un'istruzione di controllo della riga, `#sourceLocation()`, reimposta la posizione nel codice sorgente sulla numerazione delle righe e sul percorso del file predefiniti.

{% hint style="info" %}
**Grammatica di un'istruzione di controllo della riga:**

*line-control-statement* → **`#sourceLocation`** **`(`** **`file:`** *file-path* **`,`** **`line:`** *line-number* **`)`**\
*line-control-statement* → **`#sourceLocation`** **`(`** **`)`**\
*line-number* → A decimal integer greater than zero\
*file-path* → *static-string-literal*
{% endhint %}

### Istruzione di diagnostica in fase di compilazione <a href="#istruzione-di-diagnostica-in-fase-di-compilazione" id="istruzione-di-diagnostica-in-fase-di-compilazione"></a>

Prima di Swift 5.9, le istruzioni `#warning` e `#error` emettono una diagnostica durante la compilazione. Questo comportamento è ora fornito dalle macro [`warning(_:)`](https://developer.apple.com/documentation/swift/warning\(_:\)) ed [`error(_:)`](https://developer.apple.com/documentation/swift/error\(_:\)) della libreria standard di Swift.

## Condizione di disponibilità <a href="#condizione-di-disponibilita" id="condizione-di-disponibilita"></a>

Una *condizione di disponibilità* è usata come condizione di un'istruzione `if`, `while` e `guard` per interrogare la disponibilità delle API in fase di esecuzione, in base agli argomenti di piattaforma specificati.

Una condizione di disponibilità ha la forma seguente:

```swift
if #available(<#platform name#> <#version#>, <#...#>, *) {
    <#statements to execute if the APIs are available#>
} else {
    <#fallback statements to execute if the APIs are unavailable#>
}
```

Usi una condizione di disponibilità per eseguire un blocco di codice a seconda che le API che vuoi usare siano disponibili o meno in fase di esecuzione. Il compilatore usa le informazioni della condizione di disponibilità quando verifica che le API in quel blocco di codice siano disponibili.

La condizione di disponibilità accetta un elenco di nomi di piattaforma e versioni separati da virgole. Usa `iOS`, `macOS`, `watchOS`, `tvOS` e `visionOS` per i nomi delle piattaforme, e includi i numeri di versione corrispondenti. L'argomento `*` è obbligatorio e specifica che, su qualsiasi altra piattaforma, il corpo del blocco di codice protetto dalla condizione di disponibilità viene eseguito sul target di distribuzione minimo specificato dal tuo target.

A differenza delle condizioni booleane, non puoi combinare le condizioni di disponibilità usando operatori logici come `&&` e `||`. Invece di usare `!` per negare una condizione di disponibilità, usa una condizione di indisponibilità, che ha la forma seguente:

```swift
if #unavailable(<#platform name#> <#version#>, <#...#>) {
    <#fallback statements to execute if the APIs are unavailable#>
} else {
    <#statements to execute if the APIs are available#>
}
```

La forma `#unavailable` è zucchero sintattico che nega la condizione. In una condizione di indisponibilità, l'argomento `*` è implicito e non deve essere incluso. Ha lo stesso significato dell'argomento `*` in una condizione di disponibilità.

{% hint style="info" %}
**Grammatica di una condizione di disponibilità:**

*availability-condition* → **`#available`** **`(`** *availability-arguments* **`)`**\
*availability-condition* → **`#unavailable`** **`(`** *availability-arguments* **`)`**\
*availability-arguments* → *availability-argument* | *availability-argument* **`,`** *availability-arguments*\
*availability-argument* → *platform-name* *platform-version*\
*availability-argument* → **`*`**

*platform-name* → **`iOS`** | **`iOSApplicationExtension`**\
*platform-name* → **`macOS`** | **`macOSApplicationExtension`**\
*platform-name* → **`macCatalyst`** | **`macCatalystApplicationExtension`**\
*platform-name* → **`watchOS`** | **`watchOSApplicationExtension`**\
*platform-name* → **`tvOS`** | **`tvOSApplicationExtension`**\
*platform-name* → **`visionOS`** | **`visionOSApplicationExtension`**\
*platform-version* → *decimal-digits*\
*platform-version* → *decimal-digits* **`.`** *decimal-digits*\
*platform-version* → *decimal-digits* **`.`** *decimal-digits* **`.`** *decimal-digits*
{% endhint %}
