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

# Tipi annidati (Nested Types)

Definisci tipi all'interno dell'ambito di un altro tipo.

Le enumerazioni vengono spesso create per supportare la funzionalità di una specifica classe o struttura. Analogamente, può essere comodo definire strutture di utilità esclusivamente per l'uso nel contesto di un tipo più complesso, e protocolli che vengono normalmente usati insieme a un tipo specifico. Per ottenere questo, Swift ti permette di definire *tipi annidati*, con cui annidi i tipi di supporto, come enumerazioni, strutture e protocolli, all'interno della definizione del tipo che supportano.

Per annidare un tipo all'interno di un altro tipo, scrivi la sua definizione all'interno delle parentesi graffe esterne del tipo che supporta. I tipi possono essere annidati su tutti i livelli necessari.

## Tipi annidati in azione <a href="#tipi-annidati-in-azione" id="tipi-annidati-in-azione"></a>

L'esempio seguente definisce una struttura chiamata `BlackjackCard`, che modella una carta da gioco come quelle usate nel gioco del Blackjack. La struttura `BlackjackCard` contiene due tipi enumerazione annidati chiamati `Suit` e `Rank`.

Nel Blackjack, gli assi valgono uno oppure undici. Questa caratteristica è rappresentata da una struttura chiamata `Values`, che è annidata all'interno dell'enumerazione `Rank`:

```swift
struct BlackjackCard {
    // enumerazione Suit annidata
    enum Suit: Character {
        case spades = "♠", hearts = "♡", diamonds = "♢", clubs = "♣"
    }

    // enumerazione Rank annidata
    enum Rank: Int {
        case two = 2, three, four, five, six, seven, eight, nine, ten
        case jack, queen, king, ace
        struct Values {
            let first: Int, second: Int?
        }
        var values: Values {
            switch self {
            case .ace:
                return Values(first: 1, second: 11)
            case .jack, .queen, .king:
                return Values(first: 10, second: nil)
            default:
                return Values(first: self.rawValue, second: nil)
            }
        }
    }

    // proprietà e metodi di BlackjackCard
    let rank: Rank, suit: Suit
    var description: String {
        var output = "suit is \(suit.rawValue),"
        output += " value is \(rank.values.first)"
        if let second = rank.values.second {
            output += " or \(second)"
        }
        return output
    }
}
```

L'enumerazione `Suit` descrive i quattro semi comuni delle carte da gioco, insieme a un valore grezzo `Character` che rappresenta il loro simbolo.

L'enumerazione `Rank` descrive i tredici possibili valori delle carte da gioco, insieme a un valore grezzo `Int` che rappresenta il loro valore nominale. (Questo valore grezzo `Int` non viene usato per il Fante, la Regina, il Re e l'Asso.)

Come accennato sopra, l'enumerazione `Rank` definisce a sua volta un'ulteriore struttura annidata, chiamata `Values`. Questa struttura incapsula il fatto che la maggior parte delle carte ha un solo valore, mentre l'Asso ne ha due. La struttura `Values` definisce due proprietà per rappresentarlo:

* `first`, di tipo `Int`
* `second`, di tipo `Int?`, ovvero “`Int` opzionale”

`Rank` definisce anche una proprietà calcolata, `values`, che restituisce un'istanza della struttura `Values`. Questa proprietà calcolata considera il valore della carta e inizializza una nuova istanza di `Values` con i valori appropriati in base al suo valore. Usa valori speciali per `jack`, `queen`, `king` e `ace`. Per le carte numeriche, usa il valore grezzo `Int` del valore della carta.

La struttura `BlackjackCard` stessa ha due proprietà — `rank` e `suit`. Definisce inoltre una proprietà calcolata chiamata `description`, che usa i valori memorizzati in `rank` e `suit` per costruire una descrizione del nome e del valore della carta. La proprietà `description` usa l'optional binding per verificare se c'è un secondo valore da mostrare e, in tal caso, inserisce un ulteriore dettaglio descrittivo per quel secondo valore.

Poiché `BlackjackCard` è una struttura priva di inizializzatori personalizzati, ha un inizializzatore memberwise implicito, come descritto in [Inizializzatori memberwise per i tipi struttura](/guida-al-linguaggio/inizializzazione.md#inizializzatori-memberwise-per-i-tipi-struttura). Puoi usare questo inizializzatore per inizializzare una nuova costante chiamata `theAceOfSpades`:

```swift
let theAceOfSpades = BlackjackCard(rank: .ace, suit: .spades)
print("theAceOfSpades: \(theAceOfSpades.description)")
// Stampa "theAceOfSpades: suit is ♠, value is 1 or 11".
```

Anche se `Rank` e `Suit` sono annidati all'interno di `BlackjackCard`, il loro tipo può essere inferito dal contesto, e quindi l'inizializzazione di questa istanza può riferirsi ai casi dell'enumerazione soltanto tramite i loro nomi (`.ace` e `.spades`). Nell'esempio qui sopra, la proprietà `description` riporta correttamente che l'Asso di Picche ha un valore di `1` o `11`.

## Riferirsi ai tipi annidati <a href="#riferirsi-ai-tipi-annidati" id="riferirsi-ai-tipi-annidati"></a>

Per usare un tipo annidato al di fuori del suo contesto di definizione, anteponi al suo nome il nome del tipo all'interno del quale è annidato:

```swift
let heartsSymbol = BlackjackCard.Suit.hearts.rawValue
// heartsSymbol è "♡"
```

Per l'esempio qui sopra, questo permette di mantenere deliberatamente brevi i nomi di `Suit`, `Rank` e `Values`, perché i loro nomi sono qualificati in modo naturale dal contesto in cui sono definiti.
