> 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/pattern.md).

# Pattern (Patterns)

Confronta e destruttura i valori.

Un *pattern* rappresenta la struttura di un singolo valore o di un valore composto. Per esempio, la struttura di una tupla `(1, 2)` è un elenco di due elementi separati da virgole. Poiché i pattern rappresentano la struttura di un valore piuttosto che un particolare valore, puoi confrontarli con valori diversi. Per esempio, il pattern `(x, y)` corrisponde alla tupla `(1, 2)` e a qualsiasi altra tupla di due elementi. Oltre a confrontare un pattern con un valore, puoi estrarre una parte o la totalità di un valore composto e associare ciascuna parte al nome di una costante o di una variabile.

In Swift esistono due tipi fondamentali di pattern: quelli che corrispondono con successo a qualsiasi tipo di valore, e quelli che possono non riuscire a corrispondere a un valore specificato in fase di esecuzione.

Il primo tipo di pattern è usato per destrutturare i valori nei binding semplici di variabili, di costanti e negli optional binding. Questi comprendono i pattern wildcard, i pattern identificatore, e qualsiasi pattern di value binding o pattern tupla che li contenga. Puoi specificare un'annotazione di tipo per questi pattern per vincolarli a corrispondere solo a valori di un certo tipo.

Il secondo tipo di pattern è usato per il pattern matching completo, in cui i valori con cui stai cercando di effettuare il confronto potrebbero non esserci in fase di esecuzione. Questi comprendono i pattern dei casi di enumerazione, i pattern opzionali, i pattern espressione e i pattern di type casting. Usi questi pattern nell'etichetta case di un'istruzione `switch`, in una clausola `catch` di un'istruzione `do`, oppure nella condizione case di un'istruzione `if`, `while`, `guard` o `for`-`in`.

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

*pattern* → *wildcard-pattern* *type-annotation?*\
*pattern* → *identifier-pattern* *type-annotation?*\
*pattern* → *value-binding-pattern*\
*pattern* → *tuple-pattern* *type-annotation?*\
*pattern* → *enum-case-pattern*\
*pattern* → *optional-pattern*\
*pattern* → *type-casting-pattern*\
*pattern* → *expression-pattern*
{% endhint %}

## Pattern wildcard <a href="#pattern-wildcard" id="pattern-wildcard"></a>

Un *pattern wildcard* corrisponde a qualsiasi valore e lo ignora, ed è costituito da un trattino basso (`_`). Usa un pattern wildcard quando non ti interessano i valori con cui si sta effettuando il confronto. Per esempio, il codice seguente itera attraverso l'intervallo chiuso `1...3`, ignorando il valore corrente dell'intervallo a ogni iterazione del ciclo:

```swift
for _ in 1...3 {
    // Fai qualcosa tre volte.
}
```

{% hint style="info" %}
**Grammatica di un pattern wildcard:**

*wildcard-pattern* → **`_`**
{% endhint %}

## Pattern identificatore <a href="#pattern-identificatore" id="pattern-identificatore"></a>

Un *pattern identificatore* corrisponde a qualsiasi valore e associa il valore corrispondente al nome di una variabile o di una costante. Per esempio, nella seguente dichiarazione di costante, `someValue` è un pattern identificatore che corrisponde al valore `42` di tipo `Int`:

```swift
let someValue = 42
```

Quando la corrispondenza ha successo, il valore `42` viene associato (assegnato) al nome di costante `someValue`.

Quando il pattern sul lato sinistro di una dichiarazione di variabile o di costante è un pattern identificatore, il pattern identificatore è implicitamente un sotto-pattern di un pattern di value binding.

{% hint style="info" %}
**Grammatica di un pattern identificatore:**

*identifier-pattern* → *identifier*
{% endhint %}

## Pattern di value binding <a href="#pattern-di-value-binding" id="pattern-di-value-binding"></a>

Un *pattern di value binding* associa i valori corrispondenti a nomi di variabili o di costanti. I pattern di value binding che associano un valore corrispondente al nome di una costante iniziano con la parola chiave `let`; quelli che lo associano al nome di una variabile iniziano con la parola chiave `var`.

I pattern identificatore all'interno di un pattern di value binding associano nuove variabili o costanti con nome ai valori corrispondenti. Per esempio, puoi scomporre gli elementi di una tupla e associare il valore di ciascun elemento a un pattern identificatore corrispondente.

```swift
let point = (3, 2)
switch point {
// Associa x e y agli elementi di point.
case let (x, y):
    print("The point is at (\(x), \(y)).")
}
// Stampa "The point is at (3, 2)."
```

Nell'esempio qui sopra, `let` si distribuisce su ciascun pattern identificatore del pattern tupla `(x, y)`. A causa di questo comportamento, i casi dello `switch` `case let (x, y):` e `case (let x, let y):` corrispondono agli stessi valori.

{% hint style="info" %}
**Grammatica di un pattern di value binding:**

*value-binding-pattern* → **`var`** *pattern* | **`let`** *pattern*
{% endhint %}

## Pattern tupla <a href="#pattern-tupla" id="pattern-tupla"></a>

Un *pattern tupla* è un elenco separato da virgole di zero o più pattern, racchiuso tra parentesi tonde. I pattern tupla corrispondono a valori dei tipi tupla corrispondenti.

Puoi vincolare un pattern tupla a corrispondere a certi tipi di tupla usando le annotazioni di tipo. Per esempio, il pattern tupla `(x, y): (Int, Int)` nella dichiarazione di costante `let (x, y): (Int, Int) = (1, 2)` corrisponde solo ai tipi tupla in cui entrambi gli elementi sono di tipo `Int`.

Quando un pattern tupla è usato come pattern in un'istruzione `for`-`in` o in una dichiarazione di variabile o di costante, può contenere solo pattern wildcard, pattern identificatore, pattern opzionali o altri pattern tupla che contengano questi. Per esempio, il codice seguente non è valido perché l'elemento `0` nel pattern tupla `(x, 0)` è un pattern espressione:

```swift
let points = [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)]
// Questo codice non è valido.
for (x, 0) in points {
    /* ... */
}
```

Le parentesi attorno a un pattern tupla che contiene un singolo elemento non hanno alcun effetto. Il pattern corrisponde ai valori del tipo di quel singolo elemento. Per esempio, le forme seguenti sono equivalenti:

```swift
let a = 2        // a: Int = 2
let (a) = 2      // a: Int = 2
let (a): Int = 2 // a: Int = 2
```

{% hint style="info" %}
**Grammatica di un pattern tupla:**

*tuple-pattern* → **`(`** *tuple-pattern-element-list?* **`)`**\
*tuple-pattern-element-list* → *tuple-pattern-element* | *tuple-pattern-element* **`,`** *tuple-pattern-element-list*\
*tuple-pattern-element* → *pattern* | *identifier* **`:`** *pattern*
{% endhint %}

## Pattern dei casi di enumerazione <a href="#pattern-dei-casi-di-enumerazione" id="pattern-dei-casi-di-enumerazione"></a>

Un *pattern dei casi di enumerazione* corrisponde a un caso di un tipo enumerazione esistente. I pattern dei casi di enumerazione compaiono nelle etichette case delle istruzioni `switch` e nelle condizioni case delle istruzioni `if`, `while`, `guard` e `for`-`in`.

Se il caso di enumerazione che stai cercando di confrontare ha dei valori associati, il pattern del caso di enumerazione corrispondente deve specificare un pattern tupla che contenga un elemento per ciascun valore associato. Per un esempio che usa un'istruzione `switch` per confrontare casi di enumerazione contenenti valori associati, vedi [Valori associati](/guida-al-linguaggio/enumerazioni.md#valori-associati).

Un pattern dei casi di enumerazione corrisponde anche ai valori di quel caso racchiusi in un opzionale. Questa sintassi semplificata ti permette di omettere un pattern opzionale. Nota che, poiché `Optional` è implementato come un'enumerazione, `.none` e `.some` possono comparire nello stesso switch insieme ai casi del tipo enumerazione.

```swift
enum SomeEnum { case left, right }
let x: SomeEnum? = .left
switch x {
case .left:
    print("Turn left")
case .right:
    print("Turn right")
case nil:
    print("Keep going straight")
}
// Stampa "Turn left".
```

{% hint style="info" %}
**Grammatica di un pattern dei casi di enumerazione:**

*enum-case-pattern* → *type-identifier?* **`.`** *enum-case-name* *tuple-pattern?*
{% endhint %}

## Pattern opzionale <a href="#pattern-opzionale" id="pattern-opzionale"></a>

Un *pattern opzionale* corrisponde ai valori racchiusi in un caso `some(Wrapped)` di un'enumerazione `Optional<Wrapped>`. I pattern opzionali sono costituiti da un pattern identificatore seguito immediatamente da un punto interrogativo e compaiono negli stessi punti dei pattern dei casi di enumerazione.

Poiché i pattern opzionali sono zucchero sintattico per i pattern dei casi dell'enumerazione `Optional`, le forme seguenti sono equivalenti:

```swift
let someOptional: Int? = 42
// Confronto tramite un pattern dei casi di enumerazione.
if case .some(let x) = someOptional {
    print(x)
}

// Confronto tramite un pattern opzionale.
if case let x? = someOptional {
    print(x)
}
```

Il pattern opzionale fornisce un modo comodo per iterare su un array di valori opzionali in un'istruzione `for`-`in`, eseguendo il corpo del ciclo solo per gli elementi diversi da `nil`.

```swift
let arrayOfOptionalInts: [Int?] = [nil, 2, 3, nil, 5]
// Corrisponde solo ai valori diversi da nil.
for case let number? in arrayOfOptionalInts {
    print("Found a \(number)")
}
// Found a 2
// Found a 3
// Found a 5
```

{% hint style="info" %}
**Grammatica di un pattern opzionale:**

*optional-pattern* → *identifier-pattern* **`?`**
{% endhint %}

## Pattern di type casting <a href="#pattern-di-type-casting" id="pattern-di-type-casting"></a>

Esistono due pattern di type casting, il pattern `is` e il pattern `as`. Il pattern `is` compare solo nelle etichette case delle istruzioni `switch`. I pattern `is` e `as` hanno la forma seguente:

```swift
is <#type#>
<#pattern#> as <#type#>
```

Il pattern `is` corrisponde a un valore se il tipo di quel valore in fase di esecuzione è lo stesso del tipo specificato sul lato destro del pattern `is` — o una sottoclasse di quel tipo. Il pattern `is` si comporta come l'operatore `is`, nel senso che entrambi eseguono un type cast ma scartano il tipo restituito.

Il pattern `as` corrisponde a un valore se il tipo di quel valore in fase di esecuzione è lo stesso del tipo specificato sul lato destro del pattern `as` — o una sottoclasse di quel tipo. Se la corrispondenza ha successo, il tipo del valore corrispondente viene convertito nel *pattern* specificato sul lato destro del pattern `as`.

Per un esempio che usa un'istruzione `switch` per confrontare valori con i pattern `is` e `as`, vedi [Type casting per Any e AnyObject](/guida-al-linguaggio/type-casting.md#type-casting-per-any-e-anyobject).

{% hint style="info" %}
**Grammatica di un pattern di type casting:**

*type-casting-pattern* → *is-pattern* | *as-pattern*\
*is-pattern* → **`is`** *type*\
*as-pattern* → *pattern* **`as`** *type*
{% endhint %}

## Pattern espressione <a href="#pattern-espressione" id="pattern-espressione"></a>

Un *pattern espressione* rappresenta il valore di un'espressione. I pattern espressione compaiono solo nelle etichette case delle istruzioni `switch`.

L'espressione rappresentata dal pattern espressione viene confrontata con il valore di un'espressione di input usando l'operatore di pattern matching (`~=`) della libreria standard di Swift. La corrispondenza ha successo se l'operatore `~=` restituisce `true`. Per impostazione predefinita, l'operatore `~=` confronta due valori dello stesso tipo usando l'operatore `==`. Può anche confrontare un valore con un intervallo di valori, verificando se il valore è contenuto nell'intervallo, come mostra l'esempio seguente.

```swift
let point = (1, 2)
switch point {
case (0, 0):
    print("(0, 0) is at the origin.")
case (-2...2, -2...2):
    print("(\(point.0), \(point.1)) is near the origin.")
default:
    print("The point is at (\(point.0), \(point.1)).")
}
// Stampa "(1, 2) is near the origin."
```

Puoi eseguire l'overload dell'operatore `~=` per fornire un comportamento personalizzato di corrispondenza delle espressioni. Per esempio, puoi riscrivere l'esempio qui sopra per confrontare l'espressione `point` con delle rappresentazioni in forma di stringa dei punti.

```swift
// Overload dell'operatore ~= per confrontare una stringa con un intero.
func ~= (pattern: String, value: Int) -> Bool {
    return pattern == "\(value)"
}
switch point {
case ("0", "0"):
    print("(0, 0) is at the origin.")
default:
    print("The point is at (\(point.0), \(point.1)).")
}
// Stampa "The point is at (1, 2)."
```

{% hint style="info" %}
**Grammatica di un pattern espressione:**

*expression-pattern* → *expression*
{% endhint %}
