> 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/guida-al-linguaggio/le-basi.md).

# Le basi (The Basics)

Lavora con i tipi di dati comuni e scrivi la sintassi di base.

Swift fornisce molti tipi di dati fondamentali, tra cui `Int` per gli interi, `Double` per i valori in virgola mobile, `Bool` per i valori booleani, e `String` per il testo. Swift fornisce anche versioni potenti dei tre tipi collezione principali, `Array`, `Set` e `Dictionary`, come descritto in [Tipi collezione](/guida-al-linguaggio/tipi-collezione.md).

Swift usa le variabili per memorizzare valori e farvi riferimento tramite un nome identificativo. Swift fa anche largo uso di variabili i cui valori non possono essere modificati. Queste sono note come costanti, e sono usate ovunque in Swift per rendere il codice più sicuro e più chiaro nelle intenzioni quando lavori con valori che non hanno bisogno di cambiare.

Oltre ai tipi familiari, Swift introduce tipi avanzati come le tuple. Le tuple ti permettono di creare raggruppamenti di valori e di passarli da una parte all'altra. Puoi usare una tupla per restituire più valori da una funzione come un unico valore composto.

Swift gestisce l'assenza di un valore usando i tipi opzionali. Gli opzionali dicono o “*c'è* un valore, ed è *x*” oppure “*non c'è* alcun valore”. Gli opzionali garantiscono che il codice verifichi sempre se un valore manca prima di usarlo, e per i valori non opzionali è garantito che non manchino mai.

Swift è un linguaggio sicuro, il che significa che ti rende più facile individuare e correggere diverse categorie di bug il prima possibile durante il processo di sviluppo, e ti permette di garantire che certi tipi di bug non possano verificarsi. La sicurezza dei tipi ti permette di essere chiaro riguardo ai tipi dei valori con cui lavora il tuo codice. Se una parte del tuo codice richiede una `String`, la sicurezza dei tipi ti impedisce di passarle per errore un `Int`. La sicurezza della memoria garantisce che tu lavori solo con dati validi, non con memoria non inizializzata od oggetti deinizializzati, e garantisce che tu lavori con quei dati in modo sicuro — anche nei programmi che eseguono più porzioni di codice nello stesso momento. Swift esegue la maggior parte dei suoi controlli di sicurezza mentre compila il tuo codice, e in alcuni casi esegue controlli aggiuntivi mentre il tuo codice è in esecuzione.

## Costanti e variabili <a href="#costanti-e-variabili" id="costanti-e-variabili"></a>

Costanti e variabili associano un nome (come `maximumNumberOfLoginAttempts` o `welcomeMessage`) a un valore di un tipo particolare (come il numero `10` o la stringa `"Hello"`). Il valore di una *costante* non può essere cambiato una volta impostato, mentre una *variabile* può essere impostata a un valore diverso in futuro.

### Dichiarare costanti e variabili <a href="#dichiarare-costanti-e-variabili" id="dichiarare-costanti-e-variabili"></a>

Costanti e variabili devono essere dichiarate prima di essere usate. Dichiari le costanti con la parola chiave `let` e le variabili con la parola chiave `var`. Ecco un esempio di come costanti e variabili possono essere usate per tenere traccia del numero di tentativi di accesso effettuati da un utente:

```swift
let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0
```

Questo codice può essere letto come:

“Dichiara una nuova costante chiamata `maximumNumberOfLoginAttempts`, e dalle un valore di `10`. Poi, dichiara una nuova variabile chiamata `currentLoginAttempt`, e dalle un valore iniziale di `0`.”

In questo esempio, il numero massimo di tentativi di accesso consentiti è dichiarato come costante, perché il valore massimo non cambia mai. Il contatore del tentativo di accesso corrente è dichiarato come variabile, perché questo valore deve essere incrementato dopo ogni tentativo di accesso fallito.

Se un valore memorizzato nel tuo codice non cambierà, dichiaralo sempre come costante con la parola chiave `let`. Usa le variabili solo per memorizzare valori che cambiano.

Quando dichiari una costante o una variabile, puoi darle un valore come parte di quella dichiarazione, come negli esempi qui sopra. In alternativa, puoi assegnare il suo valore iniziale più avanti nel programma, purché sia garantito che abbia un valore prima della prima volta in cui lo leggi.

```swift
var environment = "development"
let maximumNumberOfLoginAttempts: Int
// maximumNumberOfLoginAttempts non ha ancora un valore.

if environment == "development" {
    maximumNumberOfLoginAttempts = 100
} else {
    maximumNumberOfLoginAttempts = 10
}
// Ora maximumNumberOfLoginAttempts ha un valore, e può essere letta.
```

In questo esempio, il numero massimo di tentativi di accesso è costante, e il suo valore dipende dall'ambiente. Nell'ambiente di sviluppo, ha un valore di 100; in qualsiasi altro ambiente, il suo valore è 10. Entrambi i rami dell'istruzione `if` inizializzano `maximumNumberOfLoginAttempts` con un qualche valore, garantendo che la costante riceva sempre un valore. Per informazioni su come Swift controlla il tuo codice quando imposti un valore iniziale in questo modo, vedi [Dichiarazione di costante](/riferimento-del-linguaggio/dichiarazioni.md#dichiarazione-di-costante).

Puoi dichiarare più costanti o più variabili su un'unica riga, separate da virgole:

```swift
var x = 0.0, y = 0.0, z = 0.0
```

### Annotazioni di tipo <a href="#annotazioni-di-tipo" id="annotazioni-di-tipo"></a>

Puoi fornire un'*annotazione di tipo* quando dichiari una costante o una variabile, per essere chiaro sul tipo di valori che la costante o la variabile può memorizzare. Scrivi un'annotazione di tipo collocando i due punti dopo il nome della costante o della variabile, seguiti da uno spazio, seguito dal nome del tipo da usare.

Questo esempio fornisce un'annotazione di tipo per una variabile chiamata `welcomeMessage`, per indicare che la variabile può memorizzare valori `String`:

```swift
var welcomeMessage: String
```

I due punti nella dichiarazione significano “…di tipo…”, quindi il codice qui sopra può essere letto come:

“Dichiara una variabile chiamata `welcomeMessage` di tipo `String`.”

L'espressione “di tipo `String`” significa “può memorizzare qualsiasi valore `String`”. Pensala come se significasse “il tipo di cosa” (o “il genere di cosa”) che può essere memorizzato.

La variabile `welcomeMessage` può ora essere impostata a qualsiasi valore stringa senza errori:

```swift
welcomeMessage = "Hello"
```

Puoi definire più variabili correlate dello stesso tipo su un'unica riga, separate da virgole, con un'unica annotazione di tipo dopo il nome dell'ultima variabile:

```swift
var red, green, blue: Double
```

{% hint style="info" %}
**Nota:** In pratica è raro che tu abbia bisogno di scrivere annotazioni di tipo. Se fornisci un valore iniziale per una costante o una variabile nel punto in cui viene definita, Swift può quasi sempre inferire il tipo da usare per quella costante o variabile, come descritto in [Sicurezza dei tipi e inferenza di tipo](/guida-al-linguaggio/le-basi.md#sicurezza-dei-tipi-e-inferenza-di-tipo). Nell'esempio `welcomeMessage` qui sopra, non viene fornito alcun valore iniziale, e quindi il tipo della variabile `welcomeMessage` è specificato con un'annotazione di tipo anziché essere inferito da un valore iniziale.
{% endhint %}

### Denominare costanti e variabili <a href="#denominare-costanti-e-variabili" id="denominare-costanti-e-variabili"></a>

I nomi di costanti e variabili possono contenere quasi qualsiasi carattere, compresi i caratteri Unicode:

```swift
let π = 3.14159
let 你好 = "你好世界"
let 🐶🐮 = "dogcow"
```

I nomi di costanti e variabili non possono contenere caratteri di spaziatura, simboli matematici, frecce, valori scalari Unicode a uso privato, o caratteri per il disegno di linee e riquadri. Né possono iniziare con un numero, anche se i numeri possono essere inclusi in altri punti del nome.

Una volta dichiarata una costante o una variabile di un certo tipo, non puoi dichiararla di nuovo con lo stesso nome, né modificarla per memorizzare valori di un tipo diverso. Né puoi trasformare una costante in una variabile o una variabile in una costante.

{% hint style="info" %}
**Nota:** Se hai bisogno di dare a una costante o a una variabile lo stesso nome di una parola chiave riservata di Swift, racchiudi la parola chiave tra backtick (`` ` ``) quando la usi come nome. Tuttavia, evita di usare parole chiave come nomi a meno che tu non abbia assolutamente altra scelta.
{% endhint %}

Puoi cambiare il valore di una variabile esistente con un altro valore di un tipo compatibile. In questo esempio, il valore di `friendlyWelcome` viene cambiato da `"Hello!"` a `"Bonjour!"`:

```swift
var friendlyWelcome = "Hello!"
friendlyWelcome = "Bonjour!"
// friendlyWelcome ora è "Bonjour!"
```

A differenza di una variabile, il valore di una costante non può essere cambiato dopo essere stato impostato. Tentare di farlo viene segnalato come errore quando il tuo codice viene compilato:

```swift
let languageName = "Swift"
languageName = "Swift++"
// Questo è un errore in fase di compilazione: languageName non può essere cambiata.
```

### Stampare costanti e variabili <a href="#stampare-costanti-e-variabili" id="stampare-costanti-e-variabili"></a>

Puoi stampare il valore corrente di una costante o di una variabile con la funzione `print(_:separator:terminator:)`:

```swift
print(friendlyWelcome)
// Stampa "Bonjour!"
```

La funzione `print(_:separator:terminator:)` è una funzione globale che stampa uno o più valori su un output appropriato. In Xcode, per esempio, la funzione `print(_:separator:terminator:)` stampa il suo output nel pannello “console” di Xcode. I parametri `separator` e `terminator` hanno valori predefiniti, quindi puoi ometterli quando chiami questa funzione. Per impostazione predefinita, la funzione termina la riga che stampa aggiungendo un'interruzione di riga. Per stampare un valore senza un'interruzione di riga dopo di esso, passa una stringa vuota come terminatore — per esempio, `print(someValue, terminator: "")`. Per informazioni sui parametri con valori predefiniti, vedi [Valori predefiniti dei parametri](/guida-al-linguaggio/funzioni.md#valori-predefiniti-dei-parametri).

Swift usa l'*interpolazione di stringhe* per includere il nome di una costante o di una variabile come segnaposto in una stringa più lunga, e per indurre Swift a sostituirlo con il valore corrente di quella costante o variabile. Racchiudi il nome tra parentesi e fanne l'escape con una barra rovesciata prima della parentesi di apertura:

```swift
print("The current value of friendlyWelcome is \(friendlyWelcome)")
// Stampa "The current value of friendlyWelcome is Bonjour!"
```

{% hint style="info" %}
**Nota:** Tutte le opzioni che puoi usare con l'interpolazione di stringhe sono descritte in [Interpolazione di stringhe](/guida-al-linguaggio/stringhe-e-caratteri.md#interpolazione-di-stringhe).
{% endhint %}

## Commenti <a href="#commenti" id="commenti"></a>

Usa i commenti per includere testo non eseguibile nel tuo codice, come nota o promemoria per te stesso. I commenti vengono ignorati dal compilatore Swift quando il tuo codice viene compilato.

I commenti in Swift sono molto simili ai commenti in C. I commenti su una sola riga iniziano con due barre (`//`):

```swift
// Questo è un commento.
```

I commenti su più righe iniziano con una barra seguita da un asterisco (`/*`) e terminano con un asterisco seguito da una barra (`*/`):

```swift
/* Anche questo è un commento
ma è scritto su più righe. */
```

A differenza dei commenti su più righe in C, i commenti su più righe in Swift possono essere annidati all'interno di altri commenti su più righe. Scrivi commenti annidati iniziando un blocco di commento su più righe e poi iniziando un secondo commento su più righe all'interno del primo blocco. Viene poi chiuso il secondo blocco, seguito dal primo:

```swift
/* Questo è l'inizio del primo commento su più righe.
    /* Questo è il secondo commento su più righe, annidato. */
Questa è la fine del primo commento su più righe. */
```

I commenti su più righe annidati ti permettono di commentare rapidamente e facilmente grandi blocchi di codice, anche se il codice contiene già commenti su più righe.

## Punti e virgola <a href="#punti-e-virgola" id="punti-e-virgola"></a>

A differenza di molti altri linguaggi, Swift non richiede di scrivere un punto e virgola (`;`) dopo ogni istruzione del tuo codice, anche se puoi farlo se lo desideri. Tuttavia, i punti e virgola *sono* obbligatori se vuoi scrivere più istruzioni separate su un'unica riga:

```swift
let cat = "🐱"; print(cat)
// Stampa "🐱".
```

## Interi <a href="#interi" id="interi"></a>

Gli *interi* sono numeri interi privi di componente frazionaria, come `42` e `-23`. Gli interi sono *con segno* (positivi, zero o negativi) oppure *senza segno* (positivi o zero), e il loro valore massimo e minimo dipende dalla loro *dimensione* (il numero di bit usati per memorizzare i valori). I tipi interi includono nel nome la loro dimensione e il loro segno — per esempio, un intero senza segno a 8 bit è di tipo `UInt8`, e un intero con segno a 32 bit è di tipo `Int32`. Come tutti i tipi in Swift, questi tipi interi hanno nomi con l'iniziale maiuscola. Nella maggior parte dei casi, quando non hai bisogno di specificare la dimensione esatta dell'intero, usi il tipo `Int` descritto più avanti.

I tipi interi si comportano come la maggior parte dell'aritmetica che fai a mano; la matematica con gli interi produce risultati senza approssimazioni. Queste caratteristiche rendono gli interi adatti al conteggio e ad altri calcoli che rappresentano quantità esatte — per esempio, trovare la riga più lunga di un file di testo, applicare un moltiplicatore di punteggio in un gioco, o sommare i prezzi su uno scontrino.

Sebbene gli interi non abbiano una componente frazionaria, puoi usarli per rappresentare quantità con frazioni contando una parte frazionaria. Per esempio, puoi rappresentare $1.23 memorizzando il numero `123` in un intero che conta i centesimi. Questo approccio è noto come *aritmetica a virgola fissa* perché il punto decimale si trova in una posizione fissa nel numero. Nell'esempio qui sopra, si intende che il numero `123` abbia il punto decimale prima delle ultime due cifre.

{% hint style="info" %}
**Nota:** Per i calcoli in un ambito regolamentato come la finanza o l'edilizia, o in un dominio in cui ci si aspettano risultati di alta precisione, potresti aver bisogno di un tipo numerico specifico che implementi comportamenti come l'arrotondamento e il troncamento, secondo i requisiti di quell'ambito.
{% endhint %}

### Limiti degli interi <a href="#limiti-degli-interi" id="limiti-degli-interi"></a>

Puoi accedere ai valori minimo e massimo di ciascun tipo intero con le sue proprietà `min` e `max`:

```swift
let minValue = UInt8.min  // minValue è uguale a 0, ed è di tipo UInt8
let maxValue = UInt8.max  // maxValue è uguale a 255, ed è di tipo UInt8
```

I valori di queste proprietà sono del tipo numerico della dimensione appropriata (come `UInt8` nell'esempio qui sopra) e possono quindi essere usati nelle espressioni insieme ad altri valori dello stesso tipo.

I calcoli che producono risultati fuori dai limiti, come un numero più grande della proprietà `max`, interrompono l'esecuzione del programma invece di memorizzare un risultato non valido. Puoi invece far andare esplicitamente l'operazione in overflow, come descritto in [Operatori di overflow](/guida-al-linguaggio/operatori-avanzati.md#operatori-di-overflow).

### Int <a href="#int" id="int"></a>

Nella maggior parte dei casi, non hai bisogno di scegliere una dimensione specifica dell'intero da usare nel tuo codice. Swift fornisce un tipo intero aggiuntivo, `Int`, che ha la stessa dimensione della dimensione di parola nativa della piattaforma corrente:

* Su una piattaforma a 32 bit, `Int` ha la stessa dimensione di `Int32`.
* Su una piattaforma a 64 bit, `Int` ha la stessa dimensione di `Int64`.

A meno che tu non abbia bisogno di lavorare con una dimensione specifica dell'intero, usa sempre `Int` per i valori interi nel tuo codice. Questo favorisce la coerenza e l'interoperabilità del codice. Anche sulle piattaforme a 32 bit, `Int` può memorizzare qualsiasi valore tra `-2,147,483,648` e `2,147,483,647`, ed è abbastanza grande per molti intervalli di interi.

### UInt <a href="#uint" id="uint"></a>

Swift fornisce anche un tipo intero senza segno, `UInt`, che ha la stessa dimensione della dimensione di parola nativa della piattaforma corrente:

* Su una piattaforma a 32 bit, `UInt` ha la stessa dimensione di `UInt32`.
* Su una piattaforma a 64 bit, `UInt` ha la stessa dimensione di `UInt64`.

{% hint style="info" %}
**Nota:** Usa `UInt` solo quando hai specificamente bisogno di un tipo intero senza segno con la stessa dimensione della dimensione di parola nativa della piattaforma. Se non è questo il caso, è preferibile `Int`, anche quando si sa che i valori da memorizzare sono non negativi. Un uso coerente di `Int` per i valori interi favorisce l'interoperabilità del codice, evita la necessità di conversioni tra tipi numerici diversi, e corrisponde all'inferenza del tipo intero, come descritto in [Sicurezza dei tipi e inferenza di tipo](/guida-al-linguaggio/le-basi.md#sicurezza-dei-tipi-e-inferenza-di-tipo).
{% endhint %}

## Numeri in virgola mobile <a href="#numeri-in-virgola-mobile" id="numeri-in-virgola-mobile"></a>

I *numeri in virgola mobile* hanno una componente frazionaria, come `3.14159`, `0.1` e `-273.15`. Swift fornisce una varietà di tipi in virgola mobile che supportano diverse dimensioni di numeri, proprio come ha diverse dimensioni di interi. Se non hai bisogno di specificare una dimensione esatta, usa `Double`. Altrimenti, usa il tipo che include nel nome la dimensione necessaria, come `Float16` o `Float80`. Seguendo la terminologia comune della matematica in virgola mobile, `Float` usa 32 bit e `Double` usa 64 bit. Puoi anche scrivere questi tipi come `Float32` o `Float64`. Per esempio, il codice grafico usa spesso `Float` per corrispondere al tipo di dato più veloce della GPU. Alcuni tipi in virgola mobile sono supportati solo da certe piattaforme, ma `Float` e `Double` sono disponibili su tutte le piattaforme.

I numeri in virgola mobile ti permettono di lavorare con numeri molto piccoli e molto grandi, ma non possono rappresentare ogni possibile valore in quell'intervallo. A differenza dei calcoli con gli interi, che producono sempre un risultato esatto, la matematica in virgola mobile arrotonda i risultati al numero rappresentabile più vicino. Per esempio, quando si memorizza il numero 10.000 come `Float`, il numero immediatamente più grande che puoi rappresentare è 10.000,001 —- i valori compresi tra questi due numeri vengono arrotondati all'uno o all'altro. Anche lo spazio tra i numeri è variabile; ci sono spazi più ampi tra i numeri grandi che tra i numeri piccoli. Per esempio, il valore `Float` successivo a 0,001 è 0,0010000002, che è più piccolo della spaziatura dopo 10.000.

I numeri in virgola mobile hanno valori per lo zero negativo, l'infinito e l'infinito negativo, che rappresentano l'overflow e l'underflow nei calcoli. Hanno anche valori not-a-number (NaN, “non è un numero”) per rappresentare un risultato non valido o indefinito, come la divisione di zero per zero. Questo comportamento è diverso da quello degli interi, che interrompono il programma se non possono rappresentare il risultato.

Se hai bisogno della stessa spaziatura tra tutti i valori possibili, o se i calcoli che stai facendo richiedono risultati esatti e non prevedono i valori speciali elencati sopra, un numero in virgola mobile potrebbe non essere il tipo di dato giusto. Considera invece l'uso di numeri a virgola fissa, come descritto in [Interi](/guida-al-linguaggio/le-basi.md#interi).

## Sicurezza dei tipi e inferenza di tipo <a href="#sicurezza-dei-tipi-e-inferenza-di-tipo" id="sicurezza-dei-tipi-e-inferenza-di-tipo"></a>

Ogni valore in un programma Swift ha un tipo. Ogni punto in cui memorizzi un valore — comprese costanti, variabili e proprietà — ha anch'esso un tipo. Potresti scrivere il tipo esplicitamente usando un'annotazione di tipo, oppure Swift potrebbe inferire il tipo da un valore iniziale. In ogni punto del tuo codice in cui fornisci un valore, il tipo di quel valore deve corrispondere al punto in cui lo usi. Per esempio, se una parte del tuo codice richiede una `String`, non puoi passarle per errore un `Int`. Questo tipo di controllo rende Swift un linguaggio *sicuro rispetto ai tipi* (type-safe).

Un linguaggio sicuro rispetto ai tipi ti incoraggia a essere chiaro riguardo ai tipi dei valori con cui lavora il tuo codice. I valori di un tipo non vengono mai convertiti implicitamente in un altro tipo. Tuttavia, alcuni tipi possono essere convertiti esplicitamente. Durante la compilazione del codice, Swift verifica la sicurezza dei tipi del codice e segnala come errori tutti i tipi non corrispondenti.

Il controllo dei tipi ti aiuta a evitare errori quando lavori con diversi tipi di valori. Tuttavia, questo non significa che tu debba specificare il tipo di ogni costante e variabile che dichiari. Se non specifichi il tipo di valore di cui hai bisogno, Swift usa l'*inferenza di tipo* per determinare il tipo appropriato. L'inferenza di tipo permette a un compilatore di dedurre automaticamente il tipo di una particolare espressione quando compila il tuo codice, semplicemente esaminando i valori che fornisci.

Grazie all'inferenza di tipo, Swift richiede molte meno dichiarazioni di tipo rispetto a linguaggi come C o Objective-C. Costanti e variabili hanno comunque un tipo esplicito, ma gran parte del lavoro di specificarne il tipo viene fatto per te.

L'inferenza di tipo è particolarmente utile quando dichiari una costante o una variabile con un valore iniziale. Questo si fa spesso assegnando un *valore letterale* (o *letterale*) alla costante o alla variabile nel punto in cui la dichiari. (Un valore letterale è un valore che compare direttamente nel tuo codice sorgente, come `42` e `3.14159` negli esempi seguenti.)

Per esempio, se assegni un valore letterale `42` a una nuova costante senza dire di che tipo sia, Swift inferisce che vuoi che la costante sia un `Int`, perché l'hai inizializzata con un numero che sembra un intero:

```swift
let meaningOfLife = 42
// il tipo di meaningOfLife viene inferito come Int
```

Allo stesso modo, se non specifichi un tipo per un letterale in virgola mobile, Swift inferisce che vuoi creare un `Double`:

```swift
let pi = 3.14159
// il tipo di pi viene inferito come Double
```

Swift sceglie sempre `Double` (anziché `Float`) quando inferisce il tipo dei numeri in virgola mobile.

Se combini letterali interi e in virgola mobile in un'espressione, dal contesto verrà inferito un tipo `Double`:

```swift
let anotherPi = 3 + 0.14159
// anche il tipo di anotherPi viene inferito come Double
```

Il valore letterale `3` non ha di per sé un tipo esplicito, e quindi viene inferito un tipo di output appropriato `Double` dalla presenza di un letterale in virgola mobile come parte dell'addizione.

## Letterali numerici <a href="#letterali-numerici" id="letterali-numerici"></a>

I letterali interi possono essere scritti come:

* Un numero *decimale*, senza prefisso
* Un numero *binario*, con un prefisso `0b`
* Un numero *ottale*, con un prefisso `0o`
* Un numero *esadecimale*, con un prefisso `0x`

Tutti questi letterali interi hanno un valore decimale di `17`:

```swift
let decimalInteger = 17
let binaryInteger = 0b10001       // 17 in notazione binaria
let octalInteger = 0o21           // 17 in notazione ottale
let hexadecimalInteger = 0x11     // 17 in notazione esadecimale
```

I letterali in virgola mobile possono essere decimali (senza prefisso), o esadecimali (con un prefisso `0x`). Devono sempre avere un numero (o un numero esadecimale) su entrambi i lati del punto decimale. I numeri decimali in virgola mobile possono anche avere un *esponente* opzionale, indicato da una `e` maiuscola o minuscola; i numeri esadecimali in virgola mobile devono avere un esponente, indicato da una `p` maiuscola o minuscola.

Per i numeri decimali con un esponente pari a `x`, il numero base viene moltiplicato per 10ˣ:

* `1.25e2` significa 1,25 x 10², ovvero `125.0`.
* `1.25e-2` significa 1,25 x 10⁻², ovvero `0.0125`.

Per i numeri esadecimali con un esponente pari a `x`, il numero base viene moltiplicato per 2ˣ:

* `0xFp2` significa 15 x 2², ovvero `60.0`.
* `0xFp-2` significa 15 x 2⁻², ovvero `3.75`.

Tutti questi letterali in virgola mobile hanno un valore decimale di `12.1875`:

```swift
let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0
```

I letterali numerici possono contenere una formattazione aggiuntiva per renderli più facili da leggere. Sia gli interi sia i numeri in virgola mobile possono essere completati con zeri aggiuntivi e possono contenere trattini bassi per favorire la leggibilità. Nessuno dei due tipi di formattazione influisce sul valore sottostante del letterale:

```swift
let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1
```

## Conversione tra tipi numerici <a href="#conversione-tra-tipi-numerici" id="conversione-tra-tipi-numerici"></a>

Usa il tipo `Int` per tutte le costanti e le variabili intere di uso generale nel tuo codice, anche se si sa che sono non negative. Usare il tipo intero predefinito nelle situazioni quotidiane significa che le costanti e le variabili intere sono immediatamente interoperabili nel tuo codice e corrisponderanno al tipo inferito per i valori letterali interi.

Usa altri tipi interi solo quando sono specificamente necessari per il compito da svolgere, a causa di dati di dimensione esplicita provenienti da una fonte esterna, o per prestazioni, uso della memoria o altre ottimizzazioni necessarie. Usare tipi di dimensione esplicita in queste situazioni aiuta a intercettare eventuali overflow accidentali dei valori e documenta implicitamente la natura dei dati usati.

### Conversione tra interi <a href="#conversione-tra-interi" id="conversione-tra-interi"></a>

L'intervallo di numeri che può essere memorizzato in una costante o variabile intera è diverso per ciascun tipo numerico. Una costante o variabile `Int8` può memorizzare numeri compresi tra `-128` e `127`, mentre una costante o variabile `UInt8` può memorizzare numeri compresi tra `0` e `255`. Un numero che non entra in una costante o variabile di un tipo intero di dimensione fissa viene segnalato come errore quando il tuo codice viene compilato:

```swift
let cannotBeNegative: UInt8 = -1
// UInt8 non può memorizzare numeri negativi, quindi questo segnalerà un errore
let tooBig: Int8 = Int8.max + 1
// Int8 non può memorizzare un numero più grande del suo valore massimo,
// quindi anche questo segnalerà un errore
```

Poiché ciascun tipo numerico può memorizzare un intervallo di valori diverso, devi abilitare la conversione tra tipi numerici caso per caso. Questo approccio esplicito previene errori di conversione nascosti e aiuta a rendere esplicite nel tuo codice le intenzioni di conversione di tipo.

Per convertire un tipo numerico specifico in un altro, inizializzi un nuovo numero del tipo desiderato con il valore esistente. Nell'esempio seguente, la costante `twoThousand` è di tipo `UInt16`, mentre la costante `one` è di tipo `UInt8`. Non possono essere sommate direttamente, perché non sono dello stesso tipo. Invece, questo esempio chiama `UInt16(one)` per creare un nuovo `UInt16` inizializzato con il valore di `one`, e usa questo valore al posto di quello originale:

```swift
let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)
```

Poiché entrambi i lati dell'addizione sono ora di tipo `UInt16`, l'addizione è consentita. Il tipo della costante di output (`twoThousandAndOne`) viene inferito come `UInt16`, perché è la somma di due valori `UInt16`.

`SomeType(ofInitialValue)` è il modo predefinito per chiamare l'inizializzatore di un tipo Swift e passargli un valore iniziale. Dietro le quinte, `UInt16` ha un inizializzatore che accetta un valore `UInt8`, e quindi questo inizializzatore viene usato per creare un nuovo `UInt16` a partire da un `UInt8` esistente. Tuttavia, qui non puoi passare *qualsiasi* tipo — deve essere un tipo per cui `UInt16` fornisce un inizializzatore. L'estensione di tipi esistenti per fornire inizializzatori che accettano nuovi tipi (comprese le tue definizioni di tipo) è trattata in [Estensioni](/guida-al-linguaggio/estensioni.md).

### Conversione tra interi e numeri in virgola mobile <a href="#conversione-tra-interi-e-numeri-in-virgola-mobile" id="conversione-tra-interi-e-numeri-in-virgola-mobile"></a>

Le conversioni tra tipi numerici interi e in virgola mobile devono essere rese esplicite:

```swift
let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine
// pi è uguale a 3.14159, e il suo tipo viene inferito come Double
```

Qui, il valore della costante `three` viene usato per creare un nuovo valore di tipo `Double`, in modo che entrambi i lati dell'addizione siano dello stesso tipo. Senza questa conversione, l'addizione non sarebbe consentita.

Anche la conversione da virgola mobile a intero deve essere resa esplicita. Un tipo intero può essere inizializzato con un valore `Double` o `Float`:

```swift
let integerPi = Int(pi)
// integerPi è uguale a 3, e il suo tipo viene inferito come Int
```

I valori in virgola mobile vengono sempre troncati quando sono usati in questo modo per inizializzare un nuovo valore intero. Ciò significa che `4.75` diventa `4`, e `-3.9` diventa `-3`.

{% hint style="info" %}
**Nota:** Le regole per combinare costanti e variabili numeriche sono diverse dalle regole per i letterali numerici. Il valore letterale `3` può essere sommato direttamente al valore letterale `0.14159`, perché i letterali numerici non hanno di per sé un tipo esplicito. Il loro tipo viene inferito solo nel momento in cui vengono valutati dal compilatore.
{% endhint %}

## Alias di tipo <a href="#alias-di-tipo" id="alias-di-tipo"></a>

Gli *alias di tipo* definiscono un nome alternativo per un tipo esistente. Definisci gli alias di tipo con la parola chiave `typealias`.

Gli alias di tipo sono utili quando vuoi riferirti a un tipo esistente con un nome più appropriato al contesto, per esempio quando lavori con dati di una dimensione specifica provenienti da una fonte esterna:

```swift
typealias AudioSample = UInt16
```

Una volta definito un alias di tipo, puoi usare l'alias ovunque potresti usare il nome originale:

```swift
var maxAmplitudeFound = AudioSample.min
// maxAmplitudeFound ora vale 0
```

Qui, `AudioSample` è definito come alias di `UInt16`. Poiché è un alias, la chiamata a `AudioSample.min` chiama in realtà `UInt16.min`, che fornisce un valore iniziale di `0` per la variabile `maxAmplitudeFound`.

## Booleani <a href="#booleani" id="booleani"></a>

Swift ha un tipo *booleano* di base, chiamato `Bool`. I valori booleani sono detti *logici*, perché possono essere soltanto veri o falsi. Swift fornisce due valori costanti booleani, `true` e `false`:

```swift
let orangesAreOrange = true
let turnipsAreDelicious = false
```

I tipi di `orangesAreOrange` e `turnipsAreDelicious` sono stati inferiti come `Bool` dal fatto che sono stati inizializzati con valori letterali booleani. Come per `Int` e `Double` visti sopra, non hai bisogno di dichiarare costanti o variabili come `Bool` se le imposti a `true` o `false` non appena le crei.

I valori booleani sono particolarmente utili quando lavori con istruzioni condizionali come l'istruzione `if`:

```swift
if turnipsAreDelicious {
    print("Mmm, tasty turnips!")
} else {
    print("Eww, turnips are horrible.")
}
// Stampa "Eww, turnips are horrible."
```

Le istruzioni condizionali come l'istruzione `if` sono trattate in modo più dettagliato in [Flusso di controllo](/guida-al-linguaggio/flusso-di-controllo.md).

La sicurezza dei tipi di Swift impedisce che valori non booleani vengano sostituiti a `Bool`. L'esempio seguente segnala un errore in fase di compilazione:

```swift
let i = 1
if i {
    // questo esempio non verrà compilato, e segnalerà un errore
}
```

Tuttavia, l'esempio alternativo seguente è valido:

```swift
let i = 1
if i == 1 {
    // questo esempio verrà compilato con successo
}
```

Il risultato del confronto `i == 1` è di tipo `Bool`, e quindi questo secondo esempio supera il controllo dei tipi. Confronti come `i == 1` sono discussi in [Operatori di base](/guida-al-linguaggio/operatori-di-base.md).

Come per altri esempi di sicurezza dei tipi in Swift, questo approccio evita errori accidentali e garantisce che l'intenzione di una particolare sezione di codice sia sempre chiara.

## Tuple <a href="#tuple" id="tuple"></a>

Le *tuple* raggruppano più valori in un unico valore composto. I valori all'interno di una tupla possono essere di qualsiasi tipo e non devono essere dello stesso tipo tra loro.

In questo esempio, `(404, "Not Found")` è una tupla che descrive un *codice di stato HTTP*. Un codice di stato HTTP è un valore speciale restituito da un server web ogni volta che richiedi una pagina web. Un codice di stato `404 Not Found` viene restituito se richiedi una pagina web che non esiste.

```swift
let http404Error = (404, "Not Found")
// http404Error è di tipo (Int, String), ed è uguale a (404, "Not Found")
```

La tupla `(404, "Not Found")` raggruppa un `Int` e una `String` per dare al codice di stato HTTP due valori separati: un numero e una descrizione leggibile. Può essere descritta come “una tupla di tipo `(Int, String)`”.

Puoi creare tuple a partire da qualsiasi combinazione di tipi, e possono contenere tutti i tipi diversi che vuoi. Niente ti impedisce di avere una tupla di tipo `(Int, Int, Int)`, o `(String, Bool)`, o addirittura qualsiasi altra combinazione di cui hai bisogno.

Puoi *scomporre* il contenuto di una tupla in costanti o variabili separate, a cui poi accedi come di consueto:

```swift
let (statusCode, statusMessage) = http404Error
print("The status code is \(statusCode)")
// Stampa "The status code is 404".
print("The status message is \(statusMessage)")
// Stampa "The status message is Not Found".
```

Se ti servono solo alcuni dei valori della tupla, ignora parti della tupla con un trattino basso (`_`) quando scomponi la tupla:

```swift
let (justTheStatusCode, _) = http404Error
print("The status code is \(justTheStatusCode)")
// Stampa "The status code is 404".
```

In alternativa, accedi ai valori dei singoli elementi di una tupla usando numeri di indice a partire da zero:

```swift
print("The status code is \(http404Error.0)")
// Stampa "The status code is 404".
print("The status message is \(http404Error.1)")
// Stampa "The status message is Not Found".
```

Puoi dare un nome ai singoli elementi di una tupla quando la tupla viene definita:

```swift
let http200Status = (statusCode: 200, description: "OK")
```

Se dai un nome agli elementi di una tupla, puoi usare i nomi degli elementi per accedere ai valori di quegli elementi:

```swift
print("The status code is \(http200Status.statusCode)")
// Stampa "The status code is 200".
print("The status message is \(http200Status.description)")
// Stampa "The status message is OK".
```

Le tuple sono particolarmente utili come valori di ritorno delle funzioni. Una funzione che tenta di recuperare una pagina web potrebbe restituire il tipo tupla `(Int, String)` per descrivere il successo o il fallimento del recupero della pagina. Restituendo una tupla con due valori distinti, ciascuno di un tipo diverso, la funzione fornisce informazioni più utili sul suo esito rispetto a quanto farebbe se potesse restituire un solo valore di un solo tipo. Per maggiori informazioni, vedi [Funzioni con più valori di ritorno](/guida-al-linguaggio/funzioni.md#funzioni-con-piu-valori-di-ritorno).

{% hint style="info" %}
**Nota:** Le tuple sono utili per semplici gruppi di valori correlati. Non sono adatte alla creazione di strutture dati complesse. Se è probabile che la tua struttura dati sia più complessa, modellala come classe o struttura, anziché come tupla. Per maggiori informazioni, vedi [Strutture e classi](/guida-al-linguaggio/strutture-e-classi.md).
{% endhint %}

## Opzionali <a href="#opzionali" id="opzionali"></a>

Usi gli *opzionali* nelle situazioni in cui un valore può essere assente. Un opzionale rappresenta due possibilità: o *c'è* un valore di un tipo specificato, e puoi fare l'unwrapping dell'opzionale per accedere a quel valore, oppure *non c'è* alcun valore.

Come esempio di valore che potrebbe mancare, il tipo `Int` di Swift ha un inizializzatore che tenta di convertire un valore `String` in un valore `Int`. Tuttavia, solo alcune stringhe possono essere convertite in interi. La stringa `"123"` può essere convertita nel valore numerico `123`, ma la stringa `"hello, world"` non ha un valore numerico corrispondente. L'esempio seguente usa l'inizializzatore per tentare di convertire una `String` in un `Int`:

```swift
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// Il tipo di convertedNumber è "Int opzionale"
```

Poiché l'inizializzatore nel codice qui sopra potrebbe fallire, restituisce un `Int` *opzionale*, anziché un `Int`.

Per scrivere un tipo opzionale, scrivi un punto interrogativo (`?`) dopo il nome del tipo contenuto nell'opzionale — per esempio, il tipo di un `Int` opzionale è `Int?`. Un `Int` opzionale contiene sempre o un qualche valore `Int` oppure nessun valore. Non può contenere nient'altro, come un valore `Bool` o `String`.

### nil <a href="#nil" id="nil"></a>

Imposti una variabile opzionale a uno stato privo di valore assegnandole il valore speciale `nil`:

```swift
var serverResponseCode: Int? = 404
// serverResponseCode contiene un effettivo valore Int pari a 404
serverResponseCode = nil
// serverResponseCode ora non contiene alcun valore
```

Se definisci una variabile opzionale senza fornire un valore predefinito, la variabile viene impostata automaticamente a `nil`:

```swift
var surveyAnswer: String?
// surveyAnswer viene impostata automaticamente a nil
```

Puoi usare un'istruzione `if` per scoprire se un opzionale contiene un valore confrontando l'opzionale con `nil`. Esegui questo confronto con l'operatore “uguale a” (`==`) o con l'operatore “diverso da” (`!=`).

Se un opzionale ha un valore, è considerato “diverso da” `nil`:

```swift
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)

if convertedNumber != nil {
    print("convertedNumber contains some integer value.")
}
// Stampa "convertedNumber contains some integer value."
```

Non puoi usare `nil` con costanti o variabili non opzionali. Se una costante o una variabile nel tuo codice deve gestire l'assenza di un valore in determinate condizioni, dichiarala come valore opzionale del tipo appropriato. È garantito che una costante o una variabile dichiarata come valore non opzionale non contenga mai un valore `nil`. Se provi ad assegnare `nil` a un valore non opzionale, otterrai un errore in fase di compilazione.

Questa separazione tra valori opzionali e non opzionali ti permette di contrassegnare esplicitamente quali informazioni possono mancare, e rende più facile scrivere codice che gestisce i valori mancanti. Non puoi trattare per errore un opzionale come se fosse non opzionale perché questo errore produce un errore in fase di compilazione. Dopo che hai fatto l'unwrapping del valore, nessun'altra parte del codice che lavora con quel valore ha bisogno di verificare `nil`, quindi non c'è bisogno di verificare ripetutamente lo stesso valore in diverse parti del tuo codice.

Quando accedi a un valore opzionale, il tuo codice gestisce sempre sia il caso `nil` sia il caso non `nil`. Ci sono diverse cose che puoi fare quando un valore manca, come descritto nelle sezioni seguenti:

* Saltare il codice che opera sul valore quando è `nil`.
* Propagare il valore `nil`, restituendo `nil` o usando l'operatore `?.` descritto in [Optional chaining](/guida-al-linguaggio/optional-chaining.md).
* Fornire un valore di ripiego, usando l'operatore `??`.
* Interrompere l'esecuzione del programma, usando l'operatore `!`.

{% hint style="info" %}
**Nota:** In Objective-C, `nil` è un puntatore a un oggetto inesistente. In Swift, `nil` non è un puntatore — è l'assenza di un valore di un certo tipo. Gli opzionali di *qualsiasi* tipo possono essere impostati a `nil`, non solo i tipi oggetto.
{% endhint %}

### Optional binding <a href="#optional-binding" id="optional-binding"></a>

Usi l'optional binding per scoprire se un opzionale contiene un valore, e in tal caso, per rendere quel valore disponibile come costante o variabile temporanea. L'optional binding può essere usato con le istruzioni `if`, `guard` e `while` per verificare la presenza di un valore all'interno di un opzionale, e per estrarre quel valore in una costante o in una variabile, come parte di un'unica azione. Per maggiori informazioni sulle istruzioni `if`, `guard` e `while`, vedi [Flusso di controllo](/guida-al-linguaggio/flusso-di-controllo.md).

Scrivi un optional binding per un'istruzione `if` come segue:

```swift
if let <#constantName#> = <#someOptional#> {
   <#statements#>
}
```

Puoi riscrivere l'esempio `possibleNumber` della sezione [Opzionali](/guida-al-linguaggio/le-basi.md#opzionali) per usare l'optional binding anziché l'unwrapping forzato:

```swift
if let actualNumber = Int(possibleNumber) {
    print("The string \"\(possibleNumber)\" has an integer value of \(actualNumber)")
} else {
    print("The string \"\(possibleNumber)\" couldn't be converted to an integer")
}
// Stampa "The string "123" has an integer value of 123".
```

Questo codice può essere letto come:

“Se l'`Int` opzionale restituito da `Int(possibleNumber)` contiene un valore, imposta una nuova costante chiamata `actualNumber` al valore contenuto nell'opzionale.”

Se la conversione ha successo, la costante `actualNumber` diventa disponibile per l'uso all'interno del primo ramo dell'istruzione `if`. È già stata inizializzata con il valore contenuto nell'opzionale, e ha il tipo non opzionale corrispondente. In questo caso, il tipo di `Int(possibleNumber)` è `Int?`, quindi il tipo di `actualNumber` è `Int`.

Se non hai bisogno di fare riferimento alla costante o alla variabile opzionale originale dopo aver acceduto al valore che contiene, puoi usare lo stesso nome per la nuova costante o variabile:

```swift
let myNumber = Int(possibleNumber)
// Qui, myNumber è un intero opzionale
if let myNumber = myNumber {
    // Qui, myNumber è un intero non opzionale
    print("My number is \(myNumber)")
}
// Stampa "My number is 123".
```

Questo codice inizia verificando se `myNumber` contiene un valore, proprio come il codice dell'esempio precedente. Se `myNumber` ha un valore, il valore di una nuova costante chiamata `myNumber` viene impostato a quel valore. All'interno del corpo dell'istruzione `if`, scrivere `myNumber` si riferisce a quella nuova costante non opzionale. Scrivere `myNumber` prima o dopo l'istruzione `if` si riferisce alla costante intera opzionale originale.

Poiché questo tipo di codice è così comune, puoi usare una forma più breve per fare l'unwrapping di un valore opzionale: scrivi solo il nome della costante o della variabile di cui stai facendo l'unwrapping. La nuova costante o variabile estratta usa implicitamente lo stesso nome del valore opzionale.

```swift
if let myNumber {
    print("My number is \(myNumber)")
}
// Stampa "My number is 123".
```

Puoi usare sia costanti sia variabili con l'optional binding. Se volessi manipolare il valore di `myNumber` all'interno del primo ramo dell'istruzione `if`, potresti scrivere invece `if var myNumber`, e il valore contenuto nell'opzionale verrebbe reso disponibile come variabile anziché come costante. Le modifiche che apporti a `myNumber` all'interno del corpo dell'istruzione `if` si applicano solo a quella variabile locale, *non* alla costante o variabile opzionale originale di cui hai fatto l'unwrapping.

Puoi includere tutti gli optional binding e le condizioni booleane di cui hai bisogno in un'unica istruzione `if`, separati da virgole. Se uno qualsiasi dei valori negli optional binding è `nil` o una qualsiasi condizione booleana restituisce `false`, l'intera condizione dell'istruzione `if` è considerata `false`. Le istruzioni `if` seguenti sono equivalenti:

```swift
if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
    print("\(firstNumber) < \(secondNumber) < 100")
}
// Stampa "4 < 42 < 100".

if let firstNumber = Int("4") {
    if let secondNumber = Int("42") {
        if firstNumber < secondNumber && secondNumber < 100 {
            print("\(firstNumber) < \(secondNumber) < 100")
        }
    }
}
// Stampa "4 < 42 < 100".
```

Le costanti e le variabili create con l'optional binding in un'istruzione `if` sono disponibili solo all'interno del corpo dell'istruzione `if`. Al contrario, le costanti e le variabili create con un'istruzione `guard` sono disponibili nelle righe di codice che seguono l'istruzione `guard`, come descritto in [Uscita anticipata](/guida-al-linguaggio/flusso-di-controllo.md#uscita-anticipata).

### Fornire un valore di ripiego <a href="#fornire-un-valore-di-ripiego" id="fornire-un-valore-di-ripiego"></a>

Un altro modo per gestire un valore mancante è fornire un valore predefinito usando l'operatore di nil-coalescing (`??`). Se l'opzionale a sinistra di `??` non è `nil`, viene fatto l'unwrapping di quel valore, che viene usato. Altrimenti, viene usato il valore a destra di `??`. Per esempio, il codice seguente saluta qualcuno per nome se ne è specificato uno, e usa un saluto generico quando il nome è `nil`.

```swift
let name: String? = nil
let greeting = "Hello, " + (name ?? "friend") + "!"
print(greeting)
// Stampa "Hello, friend!"
```

Per maggiori informazioni sull'uso di `??` per fornire un valore di ripiego, vedi [Operatore di nil-coalescing](/guida-al-linguaggio/operatori-di-base.md#operatore-di-nil-coalescing).

### Unwrapping forzato <a href="#unwrapping-forzato" id="unwrapping-forzato"></a>

Quando `nil` rappresenta un fallimento irrecuperabile, come un errore del programmatore o uno stato corrotto, puoi accedere al valore sottostante dell'opzionale aggiungendo un punto esclamativo (`!`) alla fine del nome dell'opzionale. Questo è noto come *unwrapping forzato* (force unwrapping) del valore dell'opzionale. Quando forzi l'unwrapping di un valore diverso da `nil`, il risultato è il suo valore estratto. Forzare l'unwrapping di un valore `nil` attiva un errore in fase di esecuzione.

Il `!` è, di fatto, una forma abbreviata di [`fatalError(_:file:line:)`](https://developer.apple.com/documentation/swift/fatalerror\(_:file:line:\)). Per esempio, il codice seguente mostra due approcci equivalenti:

```swift
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)

let number = convertedNumber!

guard let number = convertedNumber else {
    fatalError("The number was invalid")
}
```

Entrambe le versioni del codice qui sopra dipendono dal fatto che `convertedNumber` contenga sempre un valore. Scrivere quel requisito come parte del codice, usando uno qualsiasi degli approcci qui sopra, permette al tuo codice di verificare che il requisito sia vero in fase di esecuzione.

Per maggiori informazioni su come imporre i requisiti sui dati e verificare le ipotesi in fase di esecuzione, vedi [Asserzioni e precondizioni](/guida-al-linguaggio/le-basi.md#asserzioni-e-precondizioni).

### Opzionali con unwrapping implicito <a href="#opzionali-con-unwrapping-implicito" id="opzionali-con-unwrapping-implicito"></a>

Come descritto sopra, gli opzionali indicano che a una costante o a una variabile è consentito avere “nessun valore”. Gli opzionali possono essere verificati con un'istruzione `if` per vedere se esiste un valore, e se ne può fare l'unwrapping in modo condizionale con l'optional binding per accedere al valore dell'opzionale, se esiste.

A volte è chiaro dalla struttura di un programma che un opzionale avrà *sempre* un valore, dopo che quel valore è stato impostato per la prima volta. In questi casi, è utile eliminare la necessità di verificare e fare l'unwrapping del valore dell'opzionale ogni volta che vi si accede, perché si può presumere con sicurezza che abbia sempre un valore.

Questo tipo di opzionali è definito *opzionali con unwrapping implicito* (implicitly unwrapped optionals). Scrivi un opzionale con unwrapping implicito collocando un punto esclamativo (`String!`) anziché un punto interrogativo (`String?`) dopo il tipo che vuoi rendere opzionale. Invece di collocare un punto esclamativo dopo il nome dell'opzionale quando lo usi, collochi un punto esclamativo dopo il tipo dell'opzionale quando lo dichiari.

Gli opzionali con unwrapping implicito sono utili quando si ha la conferma che il valore di un opzionale esiste subito dopo la prima definizione dell'opzionale e si può sicuramente presumere che esista in ogni momento successivo. L'uso principale degli opzionali con unwrapping implicito in Swift è durante l'inizializzazione delle classi, come descritto in [Riferimenti unowned e proprietà opzionali con unwrapping implicito](/guida-al-linguaggio/conteggio-automatico-dei-riferimenti.md#riferimenti-unowned-e-proprieta-opzionali-con-unwrapping-implicito).

Non usare un opzionale con unwrapping implicito quando c'è la possibilità che una variabile diventi `nil` in un momento successivo. Usa sempre un normale tipo opzionale se hai bisogno di verificare un valore `nil` durante il ciclo di vita di una variabile.

Un opzionale con unwrapping implicito è dietro le quinte un normale opzionale, ma può anche essere usato come un valore non opzionale, senza bisogno di fare l'unwrapping del valore opzionale ogni volta che vi si accede. L'esempio seguente mostra la differenza di comportamento tra una stringa opzionale e una stringa opzionale con unwrapping implicito quando si accede al loro valore racchiuso come `String` esplicita:

```swift
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // Richiede un unwrapping esplicito

let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // Unwrapping automatico
```

Puoi pensare a un opzionale con unwrapping implicito come a un permesso di forzare l'unwrapping dell'opzionale se necessario. Quando usi un valore opzionale con unwrapping implicito, Swift prova innanzitutto a usarlo come un normale valore opzionale; se non può essere usato come opzionale, Swift forza l'unwrapping del valore. Nel codice qui sopra, viene forzato l'unwrapping del valore opzionale `assumedString` prima di assegnare il suo valore a `implicitString` perché `implicitString` ha un tipo esplicito non opzionale `String`. Nel codice seguente, `optionalString` non ha un tipo esplicito quindi è un normale opzionale.

```swift
let optionalString = assumedString
// Il tipo di optionalString è "String?" e non viene forzato l'unwrapping di assumedString.
```

Se un opzionale con unwrapping implicito è `nil` e provi ad accedere al suo valore racchiuso, attiverai un errore in fase di esecuzione. Il risultato è esattamente lo stesso che si avrebbe scrivendo un punto esclamativo per forzare l'unwrapping di un normale opzionale che non contiene un valore.

Puoi verificare se un opzionale con unwrapping implicito è `nil` nello stesso modo in cui verifichi un normale opzionale:

```swift
if assumedString != nil {
    print(assumedString!)
}
// Stampa "An implicitly unwrapped optional string."
```

Puoi anche usare un opzionale con unwrapping implicito con l'optional binding, per verificarne il valore e farne l'unwrapping in un'unica istruzione:

```swift
if let definiteString = assumedString {
    print(definiteString)
}
// Stampa "An implicitly unwrapped optional string."
```

## Sicurezza della memoria <a href="#sicurezza-della-memoria" id="sicurezza-della-memoria"></a>

Oltre ai controlli che impediscono le discrepanze tra tipi, descritti sopra in [Sicurezza dei tipi e inferenza di tipo](/guida-al-linguaggio/le-basi.md#sicurezza-dei-tipi-e-inferenza-di-tipo), Swift protegge anche il codice dal lavorare con memoria non valida. Questa protezione è nota come *sicurezza della memoria* (memory safety) e comprende i requisiti seguenti:

* I valori vengono impostati prima di essere letti. La protezione contro l'interazione con regioni di memoria non inizializzate è nota anche come *inizializzazione definita* (definite initialization).
* Array e buffer vengono acceduti solo a indici validi. La protezione contro gli accessi fuori dai limiti è nota anche come *sicurezza dei limiti* (bounds safety).
* Alla memoria si accede solo durante il ciclo di vita del valore. La protezione contro gli errori di uso dopo la liberazione (use-after-free) è nota anche come *sicurezza del ciclo di vita* (lifetime safety).
* Gli accessi alla memoria si sovrappongono solo in modi dimostrabilmente sicuri. La protezione contro possibili data race nel codice concorrente è nota anche come *sicurezza dei thread* (thread safety).

Se hai lavorato con linguaggi che non forniscono queste garanzie, potresti conoscere alcuni degli errori e dei bug nominati nell'elenco qui sopra. Se non hai mai incontrato questi problemi, va bene lo stesso; il codice sicuro in Swift evita questi problemi. Per informazioni su come Swift garantisce che tu imposti i valori iniziali, vedi [Inizializzazione](/guida-al-linguaggio/inizializzazione.md), per informazioni su come Swift verifica la sicurezza della memoria nel codice concorrente, vedi [Concorrenza](/guida-al-linguaggio/concorrenza.md), e per informazioni su come Swift verifica gli accessi sovrapposti alla memoria, vedi [Sicurezza della memoria](/guida-al-linguaggio/sicurezza-della-memoria.md).

A volte hai bisogno di lavorare al di fuori dei limiti della sicurezza — per esempio, a causa di limitazioni del linguaggio o della libreria standard — quindi Swift fornisce anche versioni non sicure di alcune API. Quando usi tipi o metodi il cui nome include parole come "unsafe", "unchecked" o "unmanaged", ti assumi la responsabilità della sicurezza.

Il codice sicuro in Swift può comunque incontrare errori e fallimenti inattesi, che potrebbero interrompere l'esecuzione del programma. La sicurezza non garantisce che il tuo codice venga eseguito fino al completamento. Swift fornisce diversi modi per segnalare gli errori e riprendersi da essi, discussi più avanti in [Gestione degli errori](/guida-al-linguaggio/le-basi.md#gestione-degli-errori) e in [Asserzioni e precondizioni](/guida-al-linguaggio/le-basi.md#asserzioni-e-precondizioni). Tuttavia, in alcuni casi, l'*unico* modo sicuro di gestire un errore è interrompere l'esecuzione. Se hai bisogno di garantire che un servizio non si interrompa mai inaspettatamente, incorpora la tolleranza ai guasti nella sua architettura complessiva, in modo che possa riprendersi dall'interruzione inattesa di uno qualsiasi dei suoi componenti.

## Gestione degli errori <a href="#gestione-degli-errori" id="gestione-degli-errori"></a>

Usi la *gestione degli errori* per rispondere alle condizioni di errore che il tuo programma può incontrare durante l'esecuzione.

A differenza degli opzionali, che possono usare la presenza o l'assenza di un valore per comunicare il successo o il fallimento di una funzione, la gestione degli errori ti permette di determinare la causa sottostante del fallimento, e, se necessario, di propagare l'errore a un'altra parte del tuo programma.

Quando una funzione incontra una condizione di errore, *lancia* un errore. Chi chiama quella funzione può quindi *catturare* l'errore e rispondere in modo appropriato.

```swift
func canThrowAnError() throws {
    // questa funzione può lanciare un errore oppure no
}
```

Una funzione indica di poter lanciare un errore includendo la parola chiave `throws` nella sua dichiarazione. Quando chiami una funzione che può lanciare un errore, anteponi la parola chiave `try` all'espressione.

Swift propaga automaticamente gli errori al di fuori del loro ambito corrente finché non vengono gestiti da una clausola `catch`.

```swift
do {
    try canThrowAnError()
    // non è stato lanciato alcun errore
} catch {
    // è stato lanciato un errore
}
```

Un'istruzione `do` crea un nuovo ambito contenitore, che permette agli errori di essere propagati a una o più clausole `catch`.

Ecco un esempio di come la gestione degli errori può essere usata per rispondere a diverse condizioni di errore:

```swift
func makeASandwich() throws {
    // ...
}

do {
    try makeASandwich()
    eatASandwich()
} catch SandwichError.outOfCleanDishes {
    washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
    buyGroceries(ingredients)
}
```

In questo esempio, la funzione `makeASandwich()` lancerà un errore se non ci sono piatti puliti disponibili o se manca qualche ingrediente. Poiché `makeASandwich()` può lanciare un errore, la chiamata di funzione è racchiusa in un'espressione `try`. Racchiudendo la chiamata di funzione in un'istruzione `do`, tutti gli errori lanciati verranno propagati alle clausole `catch` fornite.

Se non viene lanciato alcun errore, viene chiamata la funzione `eatASandwich()`. Se viene lanciato un errore che corrisponde al caso `SandwichError.outOfCleanDishes`, allora verrà chiamata la funzione `washDishes()`. Se viene lanciato un errore che corrisponde al caso `SandwichError.missingIngredients`, allora viene chiamata la funzione `buyGroceries(_:)` con il valore associato `[String]` catturato dal pattern `catch`.

Il lancio, la cattura e la propagazione degli errori sono trattati in modo più dettagliato in [Gestione degli errori](/guida-al-linguaggio/gestione-degli-errori.md).

## Asserzioni e precondizioni <a href="#asserzioni-e-precondizioni" id="asserzioni-e-precondizioni"></a>

Le *asserzioni* e le *precondizioni* sono controlli che avvengono in fase di esecuzione. Le usi per assicurarti che una condizione essenziale sia soddisfatta prima di eseguire altro codice. Se la condizione booleana dell'asserzione o della precondizione restituisce `true`, l'esecuzione del codice prosegue come di consueto. Se la condizione restituisce `false`, lo stato corrente del programma non è valido; l'esecuzione del codice termina, e la tua app viene terminata.

Usi asserzioni e precondizioni per esprimere le ipotesi che fai e le aspettative che hai mentre scrivi il codice, in modo da poterle includere come parte del tuo codice. Le asserzioni ti aiutano a trovare errori e ipotesi scorrette durante lo sviluppo, e le precondizioni ti aiutano a individuare problemi in produzione.

Oltre a verificare le tue aspettative in fase di esecuzione, asserzioni e precondizioni diventano anche una forma utile di documentazione all'interno del codice. A differenza delle condizioni di errore discusse sopra in [Gestione degli errori](/guida-al-linguaggio/le-basi.md#gestione-degli-errori), asserzioni e precondizioni non vengono usate per errori recuperabili o previsti. Poiché un'asserzione o una precondizione fallita indica uno stato del programma non valido, non c'è modo di catturare un'asserzione fallita. Riprendersi da uno stato non valido è impossibile. Quando un'asserzione fallisce, almeno una porzione dei dati del programma non è valida — ma non sai perché non è valida né se anche un ulteriore stato non sia valido.

Usare asserzioni e precondizioni non sostituisce una progettazione del codice tale da rendere improbabile il verificarsi di condizioni non valide. Tuttavia, usarle per imporre dati e stati validi fa sì che la tua app termini in modo più prevedibile se si verifica uno stato non valido, e aiuta a rendere il problema più facile da correggere. Quando le ipotesi non vengono verificate, potresti non accorgerti di questo tipo di problema fino a molto più tardi, quando del codice altrove inizia a fallire in modo visibile, e dopo che i dati dell'utente sono stati corrotti silenziosamente. Interrompere l'esecuzione non appena viene rilevato uno stato non valido aiuta anche a limitare i danni causati da quello stato non valido.

La differenza tra asserzioni e precondizioni sta nel momento in cui vengono verificate: le asserzioni vengono verificate solo nelle build di debug, mentre le precondizioni vengono verificate sia nelle build di debug sia in quelle di produzione. Nelle build di produzione, la condizione all'interno di un'asserzione non viene valutata. Ciò significa che puoi usare tutte le asserzioni che vuoi durante il tuo processo di sviluppo, senza influire sulle prestazioni in produzione.

### Debug con le asserzioni <a href="#debug-con-le-asserzioni" id="debug-con-le-asserzioni"></a>

Scrivi un'asserzione chiamando la funzione [`assert(_:_:file:line:)`](https://developer.apple.com/documentation/swift/assert\(_:_:file:line:\)) della libreria standard di Swift. Passi a questa funzione un'espressione che restituisce `true` o `false` e un messaggio da mostrare se il risultato della condizione è `false`. Per esempio:

```swift
let age = -3
assert(age >= 0, "A person's age can't be less than zero.")
// Questa asserzione fallisce perché -3 non è >= 0.
```

In questo esempio, l'esecuzione del codice prosegue se `age >= 0` restituisce `true`, cioè, se il valore di `age` è non negativo. Se il valore di `age` è negativo, come nel codice qui sopra, allora `age >= 0` restituisce `false`, e l'asserzione fallisce, terminando l'applicazione.

Puoi omettere il messaggio dell'asserzione — per esempio, quando si limiterebbe a ripetere la condizione in prosa.

```swift
assert(age >= 0)
```

Se il codice verifica già la condizione, usi la funzione [`assertionFailure(_:file:line:)`](https://developer.apple.com/documentation/swift/assertionfailure\(_:file:line:\)) per indicare che un'asserzione è fallita. Per esempio:

```swift
if age > 10 {
    print("You can ride the roller-coaster or the ferris wheel.")
} else if age >= 0 {
    print("You can ride the ferris wheel.")
} else {
    assertionFailure("A person's age can't be less than zero.")
}
```

### Imporre le precondizioni <a href="#imporre-le-precondizioni" id="imporre-le-precondizioni"></a>

Usa una precondizione ogni volta che una condizione può potenzialmente essere falsa, ma deve *sicuramente* essere vera affinché il tuo codice possa proseguire l'esecuzione. Per esempio, usa una precondizione per verificare che un subscript non sia fuori dai limiti, o per verificare che a una funzione sia stato passato un valore valido.

Scrivi una precondizione chiamando la funzione [`precondition(_:_:file:line:)`](https://developer.apple.com/documentation/swift/precondition\(_:_:file:line:\)). Passi a questa funzione un'espressione che restituisce `true` o `false` e un messaggio da mostrare se il risultato della condizione è `false`. Per esempio:

```swift
// Nell'implementazione di un subscript...
precondition(index > 0, "Index must be greater than zero.")
```

Puoi anche chiamare la funzione [`preconditionFailure(_:file:line:)`](https://developer.apple.com/documentation/swift/preconditionfailure\(_:file:line:\)) per indicare che si è verificato un fallimento — per esempio, se è stato preso il caso default di uno switch, mentre tutti i dati di input validi avrebbero dovuto essere gestiti da uno degli altri casi dello switch.

{% hint style="info" %}
**Nota:** Se compili in modalità non controllata (`-Ounchecked`), le precondizioni non vengono verificate. Il compilatore presume che le precondizioni siano sempre vere, e ottimizza il tuo codice di conseguenza. Tuttavia, la funzione `fatalError(_:file:line:)` interrompe sempre l'esecuzione, indipendentemente dalle impostazioni di ottimizzazione.

Puoi usare la funzione `fatalError(_:file:line:)` durante la prototipazione e le prime fasi di sviluppo per creare segnaposto (stub) per funzionalità non ancora implementate, scrivendo `fatalError("Unimplemented")` come implementazione segnaposto. Poiché gli errori fatali non vengono mai eliminati dall'ottimizzazione, a differenza delle asserzioni o delle precondizioni, puoi essere sicuro che l'esecuzione si interrompa sempre se incontra un'implementazione segnaposto.
{% endhint %}
