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

# Attributi (Attributes)

Aggiungi informazioni alle dichiarazioni e ai tipi.

In Swift esistono due tipi di attributi — quelli che si applicano alle dichiarazioni e quelli che si applicano ai tipi. Un attributo fornisce informazioni aggiuntive sulla dichiarazione o sul tipo. Per esempio, l'attributo `discardableResult` sulla dichiarazione di una funzione indica che, sebbene la funzione restituisca un valore, il compilatore non dovrebbe generare un avviso se il valore restituito non viene usato.

Specifichi un attributo scrivendo il simbolo `@` seguito dal nome dell'attributo e da eventuali argomenti che l'attributo accetta:

```swift
@<#attribute name#>
@<#attribute name#>(<#attribute arguments#>)
```

Alcuni attributi di dichiarazione accettano argomenti che specificano ulteriori informazioni sull'attributo e su come si applica a una particolare dichiarazione. Questi *argomenti dell'attributo* sono racchiusi tra parentesi, e il loro formato è definito dall'attributo a cui appartengono.

Anche le macro attached e i property wrapper usano la sintassi degli attributi. Per informazioni su come si espandono le macro, vedi [Espressione di espansione di macro](/riferimento-del-linguaggio/espressioni.md#espressione-di-espansione-di-macro). Per informazioni sui property wrapper, vedi [propertyWrapper](/riferimento-del-linguaggio/attributi.md#propertywrapper).

## Attributi di dichiarazione <a href="#attributi-di-dichiarazione" id="attributi-di-dichiarazione"></a>

Puoi applicare un attributo di dichiarazione solo alle dichiarazioni.

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

Applica l'attributo `attached` alla dichiarazione di una macro. Gli argomenti di questo attributo indicano il ruolo della macro. Per una macro che ha più ruoli, applica la macro `attached` più volte, una per ciascun ruolo.

Il primo argomento di questo attributo indica il ruolo della macro:

* **Macro peer**: Scrivi `peer` come primo argomento di questo attributo. Il tipo che implementa la macro è conforme al protocollo `PeerMacro`. Queste macro producono nuove dichiarazioni nello stesso ambito della dichiarazione a cui la macro è associata. Per esempio, applicare una macro peer a un metodo di una struttura può definire metodi e proprietà aggiuntivi su quella struttura.
* **Macro member**: Scrivi `member` come primo argomento di questo attributo. Il tipo che implementa la macro è conforme al protocollo `MemberMacro`. Queste macro producono nuove dichiarazioni che sono membri del tipo o dell'estensione a cui la macro è associata. Per esempio, applicare una macro member alla dichiarazione di una struttura può definire metodi e proprietà aggiuntivi su quella struttura.
* **Member attribute**: Scrivi `memberAttribute` come primo argomento di questo attributo. Il tipo che implementa la macro è conforme al protocollo `MemberAttributeMacro`. Queste macro aggiungono attributi ai membri del tipo o dell'estensione a cui la macro è associata.
* **Macro accessor**: Scrivi `accessor` come primo argomento di questo attributo. Il tipo che implementa la macro è conforme al protocollo `AccessorMacro`. Queste macro aggiungono accessor alla proprietà memorizzata a cui sono associate, trasformandola in una proprietà calcolata.
* **Macro extension**: Scrivi `extension` come primo argomento di questo attributo. Il tipo che implementa la macro è conforme al protocollo `ExtensionMacro`. Queste macro possono aggiungere la conformità a protocolli, una clausola `where` e nuove dichiarazioni che sono membri del tipo a cui la macro è associata. Se la macro aggiunge conformità a protocolli, includi l'argomento `conformances:` e specifica quei protocolli. L'elenco delle conformità contiene nomi di protocolli, alias di tipo che fanno riferimento a elementi dell'elenco delle conformità, o composizioni di protocolli di elementi dell'elenco delle conformità. Una macro extension su un tipo annidato si espande in un'estensione al primo livello di quel file. Non puoi scrivere una macro extension su un'estensione, su un alias di tipo o su un tipo annidato all'interno di una funzione, né usare una macro extension per aggiungere un'estensione che ha una macro peer.
* **Macro body**: Scrivi `body` come primo argomento di questo attributo. Il tipo che implementa la macro è conforme al protocollo `BodyMacro`. Queste macro possono generare, modificare o sostituire il corpo della funzione o dell'accessor a cui sono associate. Puoi scrivere al massimo una macro body su una data funzione. Se viene fornito un corpo originale della funzione, deve essere sintatticamente corretto, ma non viene sottoposto al controllo dei tipi fino a dopo l'espansione della macro.

I ruoli di macro peer e member richiedono un argomento `names:`, che elenca i nomi dei simboli generati dalla macro. Il ruolo di macro accessor richiede un argomento `names:` se la macro genera un osservatore di proprietà `willSet` o `didSet`. Una macro accessor che genera osservatori di proprietà non può aggiungere altri accessor, perché gli osservatori si applicano solo alle proprietà memorizzate. Anche il ruolo di macro extension richiede un argomento `names:` se la macro aggiunge dichiarazioni all'interno dell'estensione. Quando la dichiarazione di una macro include l'argomento `names:`, l'implementazione della macro deve generare solo simboli con nomi che corrispondono a quell'elenco. Detto questo, una macro non deve necessariamente generare un simbolo per ogni nome elencato. Il valore di quell'argomento è un elenco di uno o più dei seguenti:

* `named(<#name#>)` dove *name* è quel nome di simbolo fisso, per un nome noto in anticipo.
* `overloaded` per un nome uguale a quello di un simbolo esistente.
* `prefixed(<#prefix#>)` dove *prefix* viene anteposto al nome del simbolo, per un nome che inizia con una stringa fissa.
* `suffixed(<#suffix#>)` dove *suffix* viene posposto al nome del simbolo, per un nome che termina con una stringa fissa.
* `arbitrary` per un nome che non può essere determinato fino all'espansione della macro.

Come caso speciale, puoi scrivere `prefixed($)` per una macro che si comporta in modo simile a un property wrapper.

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

Applica questo attributo per indicare il ciclo di vita di una dichiarazione rispetto a determinate versioni del linguaggio Swift o a determinate piattaforme e versioni del sistema operativo.

L'attributo `available` compare sempre con un elenco di due o più argomenti dell'attributo separati da virgole. Questi argomenti iniziano con uno dei seguenti nomi di piattaforma o di linguaggio:

* `iOS`
* `iOSApplicationExtension`
* `macOS`
* `macOSApplicationExtension`
* `macCatalyst`
* `macCatalystApplicationExtension`
* `watchOS`
* `watchOSApplicationExtension`
* `tvOS`
* `tvOSApplicationExtension`
* `visionOS`
* `visionOSApplicationExtension`
* `swift`

Puoi anche usare un asterisco (`*`) per indicare la disponibilità della dichiarazione su tutti i nomi di piattaforma elencati sopra. Un attributo `available` che specifica la disponibilità usando un numero di versione di Swift non può usare l'asterisco.

Gli argomenti rimanenti possono comparire in qualsiasi ordine e specificano informazioni aggiuntive sul ciclo di vita della dichiarazione, comprese le tappe importanti.

* L'argomento `unavailable` indica che la dichiarazione non è disponibile sulla piattaforma specificata. Questo argomento non può essere usato quando si specifica la disponibilità per versione di Swift.
* L'argomento `introduced` indica la prima versione della piattaforma o del linguaggio specificati in cui la dichiarazione è stata introdotta. Ha la forma seguente:

  ```swift
  introduced: <#version number#>
  ```

  Il *version number* (numero di versione) è costituito da uno a tre interi positivi, separati da punti.
* L'argomento `deprecated` indica la prima versione della piattaforma o del linguaggio specificati in cui la dichiarazione è stata deprecata. Ha la forma seguente:

  ```swift
  deprecated: <#version number#>
  ```

  Il *version number* facoltativo è costituito da uno a tre interi positivi, separati da punti. Omettere il numero di versione indica che la dichiarazione è attualmente deprecata, senza fornire alcuna informazione su quando è avvenuta la deprecazione. Se ometti il numero di versione, ometti anche i due punti (`:`).
* L'argomento `obsoleted` indica la prima versione della piattaforma o del linguaggio specificati in cui la dichiarazione è diventata obsoleta. Quando una dichiarazione diventa obsoleta, viene rimossa dalla piattaforma o dal linguaggio specificati e non può più essere usata. Ha la forma seguente:

  ```swift
  obsoleted: <#version number#>
  ```

  Il *version number* è costituito da uno a tre interi positivi, separati da punti.
* L'argomento `noasync` indica che il simbolo dichiarato non può essere usato direttamente in un contesto asincrono.

  Poiché la concorrenza di Swift può riprendere su un thread diverso dopo un potenziale punto di sospensione, usare elementi come la memoria locale al thread, i lock, i mutex o i semafori attraverso i punti di sospensione può portare a risultati errati.

  Per evitare questo problema, aggiungi un attributo `@available(*, noasync)` alla dichiarazione del simbolo:

  ```swift
  extension pthread_mutex_t {

    @available(*, noasync)
    mutating func lock() {
        pthread_mutex_lock(&self)
    }

    @available(*, noasync)
    mutating func unlock() {
        pthread_mutex_unlock(&self)
    }
  }
  ```

  Questo attributo genera un errore in fase di compilazione quando qualcuno usa il simbolo in un contesto asincrono. Puoi anche usare l'argomento `message` per fornire informazioni aggiuntive sul simbolo.

  ```swift
  @available(*, noasync, message: "Migrate locks to Swift concurrency.")
  mutating func lock() {
    pthread_mutex_lock(&self)
  }
  ```

  Se puoi garantire che il tuo codice usa un simbolo potenzialmente non sicuro in modo sicuro, puoi racchiuderlo in una funzione sincrona e chiamare quella funzione da un contesto asincrono.

  ```swift

  // Fornisce un wrapper sincrono attorno ai metodi con una dichiarazione noasync.
  extension pthread_mutex_t {
    mutating func withLock(_ operation: () -> ()) {
      self.lock()
      operation()
      self.unlock()
    }
  }

  func downloadAndStore(key: Int,
                      dataStore: MyKeyedStorage,
                      dataLock: inout pthread_mutex_t) async {
    // Chiama in sicurezza il wrapper in un contesto asincrono.
    dataLock.withLock {
      dataStore[key] = downloadContent()
    }
  }
  ```

  Puoi usare l'argomento `noasync` sulla maggior parte delle dichiarazioni; tuttavia, non puoi usarlo quando dichiari deinizializzatori. Swift deve poter chiamare i deinizializzatori di una classe da qualsiasi contesto, sia sincrono sia asincrono.
* L'argomento `message` fornisce un messaggio testuale che il compilatore mostra quando emette un avviso o un errore sull'uso di una dichiarazione contrassegnata come `deprecated`, `obsoleted` o `noasync`. Ha la forma seguente:

  ```swift
  message: <#message#>
  ```

  Il *message* (messaggio) è costituito da un letterale stringa.
* L'argomento `renamed` fornisce un messaggio testuale che indica il nuovo nome di una dichiarazione che è stata rinominata. Il compilatore mostra il nuovo nome quando emette un errore sull'uso di una dichiarazione rinominata. Ha la forma seguente:

  ```swift
  renamed: <#new name#>
  ```

  Il *new name* (nuovo nome) è costituito da un letterale stringa.

  Puoi applicare l'attributo `available` con gli argomenti `renamed` e `unavailable` alla dichiarazione di un alias di tipo, come mostrato di seguito, per indicare che il nome di una dichiarazione è cambiato tra una release e l'altra di un framework o di una libreria. Questa combinazione produce un errore in fase di compilazione che segnala che la dichiarazione è stata rinominata.

  ```swift
  // Prima release
  protocol MyProtocol {
      // definizione del protocollo
  }
  ```

  ```swift
  // La release successiva rinomina MyProtocol
  protocol MyRenamedProtocol {
      // definizione del protocollo
  }

  @available(*, unavailable, renamed: "MyRenamedProtocol")
  typealias MyProtocol = MyRenamedProtocol
  ```

Puoi applicare più attributi `available` a una singola dichiarazione per specificare la disponibilità della dichiarazione su piattaforme diverse e su versioni diverse di Swift. La dichiarazione a cui si applica l'attributo `available` viene ignorata se l'attributo specifica una piattaforma o una versione del linguaggio che non corrisponde al target corrente. Se usi più attributi `available`, la disponibilità effettiva è la combinazione delle disponibilità per piattaforma e per Swift.

Se un attributo `available` specifica solo un argomento `introduced` oltre a un argomento con il nome di una piattaforma o di un linguaggio, puoi usare invece la seguente sintassi abbreviata:

```swift
@available(<#platform name#> <#version number#>, *)
@available(swift <#version number#>)
```

La sintassi abbreviata per gli attributi `available` esprime in modo conciso la disponibilità per più piattaforme. Sebbene le due forme siano funzionalmente equivalenti, la forma abbreviata è preferibile ogni volta che è possibile.

```swift
@available(iOS 10.0, macOS 10.12, *)
class MyClass {
    // definizione della classe
}
```

Un attributo `available` che specifica la disponibilità usando un numero di versione di Swift non può specificare anche la disponibilità della dichiarazione per piattaforma. Usa invece attributi `available` separati per specificare la disponibilità per versione di Swift e una o più disponibilità per piattaforma.

```swift
@available(swift 3.0.2)
@available(macOS 10.12, *)
struct MyStruct {
    // definizione della struttura
}
```

### backDeployed <a href="#backdeployed" id="backdeployed"></a>

Applica questo attributo a una funzione, a un metodo, a un subscript o a una proprietà calcolata per includere una copia dell'implementazione del simbolo nei programmi che chiamano il simbolo o vi accedono. Usi questo attributo per annotare simboli distribuiti come parte di una piattaforma, come le API incluse in un sistema operativo. Questo attributo contrassegna i simboli che possono essere resi disponibili retroattivamente includendo una copia della loro implementazione nei programmi che vi accedono. Copiare l'implementazione è noto anche come *emissione nel client*.

Questo attributo accetta un argomento `before:`, che specifica la prima versione delle piattaforme che forniscono questo simbolo. Queste versioni di piattaforma hanno lo stesso significato della versione di piattaforma che specifichi per l'attributo `available`. A differenza dell'attributo `available`, l'elenco non può contenere un asterisco (`*`) per fare riferimento a tutte le versioni. Per esempio, considera il codice seguente:

```swift
@available(iOS 16, *)
@backDeployed(before: iOS 17)
func someFunction() { /* ... */ }
```

Nell'esempio qui sopra, l'SDK di iOS fornisce `someFunction()` a partire da iOS 17. Inoltre, l'SDK rende disponibile `someFunction()` su iOS 16 usando il back deployment.

Quando si compila codice che chiama questa funzione, Swift inserisce un livello di indirezione che trova l'implementazione della funzione. Se il codice viene eseguito usando una versione dell'SDK che include questa funzione, viene usata l'implementazione dell'SDK. Altrimenti, viene usata la copia inclusa nel chiamante. Nell'esempio qui sopra, chiamare `someFunction()` usa l'implementazione dell'SDK quando il codice viene eseguito su iOS 17 o versioni successive, e quando viene eseguito su iOS 16 usa la copia di `someFunction()` inclusa nel chiamante.

{% hint style="info" %}
**Nota:** Quando il target di distribuzione minimo del chiamante è uguale o superiore alla prima versione dell'SDK che include il simbolo, il compilatore può eliminare con l'ottimizzazione il controllo in fase di esecuzione e chiamare direttamente l'implementazione dell'SDK. In questo caso, se accedi direttamente al simbolo sottoposto a back deployment, il compilatore può anche omettere dal client la copia dell'implementazione del simbolo.
{% endhint %}

Le funzioni, i metodi, i subscript e le proprietà calcolate che soddisfano i criteri seguenti possono essere sottoposti a back deployment:

* La dichiarazione è `public` o `@usableFromInline`.
* Per i metodi di istanza di classe e i metodi di tipo di classe, il metodo è contrassegnato come `final` e non è contrassegnato come `@objc`.
* L'implementazione soddisfa i requisiti per una funzione inlinable, descritti in [inlinable](/riferimento-del-linguaggio/attributi.md#inlinable).

### discardableResult <a href="#discardableresult" id="discardableresult"></a>

Applica questo attributo alla dichiarazione di una funzione o di un metodo per sopprimere l'avviso del compilatore quando la funzione o il metodo che restituisce un valore viene chiamato senza usarne il risultato.

### dynamicCallable <a href="#dynamiccallable" id="dynamiccallable"></a>

Applica questo attributo a una classe, a una struttura, a un'enumerazione o a un protocollo per trattare le istanze del tipo come funzioni chiamabili. Il tipo deve implementare un metodo `dynamicallyCall(withArguments:)`, un metodo `dynamicallyCall(withKeywordArguments:)`, o entrambi.

Puoi chiamare un'istanza di un tipo dinamicamente chiamabile come se fosse una funzione che accetta un numero qualsiasi di argomenti.

```swift
@dynamicCallable
struct TelephoneExchange {
    func dynamicallyCall(withArguments phoneNumber: [Int]) {
        if phoneNumber == [4, 1, 1] {
            print("Get Swift help on forums.swift.org")
        } else {
            print("Unrecognized number")
        }
    }
}

let dial = TelephoneExchange()

// Usa una chiamata di metodo dinamica.
dial(4, 1, 1)
// Stampa "Get Swift help on forums.swift.org".

dial(8, 6, 7, 5, 3, 0, 9)
// Stampa "Unrecognized number".

// Chiama direttamente il metodo sottostante.
dial.dynamicallyCall(withArguments: [4, 1, 1])
```

La dichiarazione del metodo `dynamicallyCall(withArguments:)` deve avere un singolo parametro conforme al protocollo [`ExpressibleByArrayLiteral`](https://developer.apple.com/documentation/swift/expressiblebyarrayliteral) — come `[Int]` nell'esempio qui sopra. Il tipo di ritorno può essere qualsiasi tipo.

Puoi includere etichette in una chiamata di metodo dinamica se implementi il metodo `dynamicallyCall(withKeywordArguments:)`.

```swift
@dynamicCallable
struct Repeater {
    func dynamicallyCall(withKeywordArguments pairs: KeyValuePairs<String, Int>) -> String {
        return pairs
            .map { label, count in
                repeatElement(label, count: count).joined(separator: " ")
            }
            .joined(separator: "\n")
    }
}

let repeatLabels = Repeater()
print(repeatLabels(a: 1, b: 2, c: 3, b: 2, a: 1))
// a
// b b
// c c c
// b b
// a
```

La dichiarazione del metodo `dynamicallyCall(withKeywordArguments:)` deve avere un singolo parametro conforme al protocollo [`ExpressibleByDictionaryLiteral`](https://developer.apple.com/documentation/swift/expressiblebydictionaryliteral), e il tipo di ritorno può essere qualsiasi tipo. La [`Key`](https://developer.apple.com/documentation/swift/expressiblebydictionaryliteral/key) del parametro deve essere [`ExpressibleByStringLiteral`](https://developer.apple.com/documentation/swift/expressiblebystringliteral). L'esempio precedente usa [`KeyValuePairs`](https://developer.apple.com/documentation/swift/keyvaluepairs) come tipo del parametro così che i chiamanti possano includere etichette di parametro duplicate — `a` e `b` compaiono più volte nella chiamata a `repeat`.

Se implementi entrambi i metodi `dynamicallyCall`, viene chiamato `dynamicallyCall(withKeywordArguments:)` quando la chiamata di metodo include argomenti con parola chiave. In tutti gli altri casi, viene chiamato `dynamicallyCall(withArguments:)`.

Puoi chiamare un'istanza dinamicamente chiamabile solo con argomenti e un valore di ritorno che corrispondono ai tipi che specifichi in una delle tue implementazioni del metodo `dynamicallyCall`. La chiamata nell'esempio seguente non viene compilata perché non esiste un'implementazione di `dynamicallyCall(withArguments:)` che accetta `KeyValuePairs<String, String>`.

```swift
repeatLabels(a: "four") // Errore
```

### dynamicMemberLookup <a href="#dynamicmemberlookup" id="dynamicmemberlookup"></a>

Applica questo attributo a una classe, a una struttura, a un'enumerazione o a un protocollo per consentire la ricerca dei membri per nome in fase di esecuzione. Il tipo deve implementare un subscript `subscript(dynamicMember:)`.

In un'espressione membro esplicita, se non esiste una dichiarazione corrispondente per il membro indicato, l'espressione viene interpretata come una chiamata al subscript `subscript(dynamicMember:)` del tipo, passando come argomento informazioni sul membro. Il subscript può accettare un parametro che è un key path o il nome di un membro; se implementi entrambi i subscript, viene usato il subscript che accetta un argomento key path.

Un'implementazione di `subscript(dynamicMember:)` può accettare key path usando un argomento di tipo [`KeyPath`](https://developer.apple.com/documentation/swift/keypath), [`WritableKeyPath`](https://developer.apple.com/documentation/swift/writablekeypath) o [`ReferenceWritableKeyPath`](https://developer.apple.com/documentation/swift/referencewritablekeypath). Può accettare nomi di membri usando un argomento di un tipo conforme al protocollo [`ExpressibleByStringLiteral`](https://developer.apple.com/documentation/swift/expressiblebystringliteral) — nella maggior parte dei casi, `String`. Il tipo di ritorno del subscript può essere qualsiasi tipo.

La ricerca dinamica dei membri per nome del membro può essere usata per creare un tipo wrapper attorno a dati che non possono essere sottoposti al controllo dei tipi in fase di compilazione, come quando si esegue il bridging in Swift di dati provenienti da altri linguaggi. Per esempio:

```swift
@dynamicMemberLookup
struct DynamicStruct {
    let dictionary = ["someDynamicMember": 325,
                      "someOtherMember": 787]
    subscript(dynamicMember member: String) -> Int {
        return dictionary[member] ?? 1054
    }
}
let s = DynamicStruct()

// Usa la ricerca dinamica dei membri.
let dynamic = s.someDynamicMember
print(dynamic)
// Stampa "325".

// Chiama direttamente il subscript sottostante.
let equivalent = s[dynamicMember: "someDynamicMember"]
print(dynamic == equivalent)
// Stampa "true".
```

La ricerca dinamica dei membri per key path può essere usata per implementare un tipo wrapper in un modo che supporta il controllo dei tipi in fase di compilazione. Per esempio:

```swift
struct Point { var x, y: Int }

@dynamicMemberLookup
struct PassthroughWrapper<Value> {
    var value: Value
    subscript<T>(dynamicMember member: KeyPath<Value, T>) -> T {
        get { return value[keyPath: member] }
    }
}

let point = Point(x: 381, y: 431)
let wrapper = PassthroughWrapper(value: point)
print(wrapper.x)
```

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

Applica questo attributo alla dichiarazione di una funzione o di un metodo per controllare come la sua definizione viene esportata ai moduli client. Includi uno degli argomenti seguenti, che indica quale aspetto della dichiarazione esportare:

* L'argomento `interface` specifica che ai client viene esportata solo l'interfaccia, sotto forma di simbolo chiamabile. La definizione (il corpo della funzione) non è disponibile ai client per l'inlining, l'ottimizzazione o qualsiasi altro scopo. Usa questo argomento per nascondere l'implementazione ai client.
* L'argomento `implementation` specifica che ai client viene esportata solo la definizione (il corpo della funzione). Nel binario non viene emesso alcun simbolo per questa funzione, e i client sono responsabili di emettere una copia della definizione ovunque sia necessaria. Usa questo argomento per introdurre una nuova funzione o un nuovo metodo senza influire sull'Application Binary Interface (ABI).

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

Applica l'attributo `freestanding` alla dichiarazione di una macro freestanding.

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

Applica questo attributo alla dichiarazione di una struttura o di un'enumerazione per limitare i tipi di modifiche che puoi apportare al tipo. Questo attributo è consentito solo quando si compila in modalità library evolution. Le versioni future della libreria non possono modificare la dichiarazione aggiungendo, rimuovendo o riordinando i casi di un'enumerazione o le proprietà di istanza memorizzate di una struttura. Queste modifiche sono consentite sui tipi non frozen, ma rompono la compatibilità ABI per i tipi frozen.

In modalità library evolution, il codice che interagisce con i membri di strutture ed enumerazioni non frozen viene compilato in modo da continuare a funzionare senza ricompilazione anche se una versione futura della libreria aggiunge, rimuove o riordina alcuni dei membri di quel tipo. Il compilatore lo rende possibile usando tecniche come la ricerca di informazioni in fase di esecuzione e l'aggiunta di un livello di indirezione. Contrassegnare una struttura o un'enumerazione come frozen rinuncia a questa flessibilità per guadagnare in prestazioni: le versioni future della libreria possono apportare solo modifiche limitate al tipo, ma il compilatore può applicare ottimizzazioni aggiuntive nel codice che interagisce con i membri del tipo.

I tipi frozen, i tipi delle proprietà memorizzate delle strutture frozen e i valori associati dei casi delle enumerazioni frozen devono essere pubblici o contrassegnati con l'attributo `usableFromInline`. Le proprietà di una struttura frozen non possono avere osservatori di proprietà, e le espressioni che forniscono il valore iniziale delle proprietà di istanza memorizzate devono seguire le stesse restrizioni delle funzioni inlinable, come discusso in [inlinable](/riferimento-del-linguaggio/attributi.md#inlinable).

Per abilitare la modalità library evolution dalla riga di comando, passa l'opzione `-enable-library-evolution` al compilatore Swift. Per abilitarla in Xcode, imposta l'impostazione di build "Build Libraries for Distribution" (`BUILD_LIBRARY_FOR_DISTRIBUTION`) su Yes, come descritto nell'[Aiuto di Xcode](https://help.apple.com/xcode/mac/current/#/dev04b3a04ba).

Un'istruzione switch su un'enumerazione frozen non richiede un caso `default`, come discusso in [Switch sui casi futuri di un'enumerazione](/riferimento-del-linguaggio/istruzioni.md#switch-sui-casi-futuri-di-unenumerazione). Includere un caso `default` o `@unknown default` quando si esegue uno switch su un'enumerazione frozen produce un avviso perché quel codice non viene mai eseguito.

### GKInspectable <a href="#gkinspectable" id="gkinspectable"></a>

Applica questo attributo per esporre una proprietà personalizzata di un componente GameplayKit all'interfaccia utente dell'editor di SpriteKit. Applicare questo attributo implica anche l'attributo `objc`.

### globalActor <a href="#globalactor" id="globalactor"></a>

Applica questo attributo a un actor, a una struttura, a un'enumerazione o a una classe final. Il tipo deve definire una proprietà statica chiamata `shared`, che fornisce un'istanza condivisa di un actor.

Un global actor generalizza il concetto di isolamento degli actor a uno stato distribuito in diversi punti del codice — come più tipi, file e moduli — e rende possibile accedere in sicurezza alle variabili globali dal codice concorrente. L'actor che il global actor fornisce come valore della sua proprietà `shared` serializza l'accesso a tutto questo stato. Puoi anche usare un global actor per modellare vincoli nel codice concorrente, come codice che deve essere eseguito interamente sullo stesso thread.

I global actor sono implicitamente conformi al protocollo [`GlobalActor`](https://developer.apple.com/documentation/swift/globalactor). Il main actor è un global actor fornito dalla libreria standard, come discusso in [Il main actor](/guida-al-linguaggio/concorrenza.md#il-main-actor). La maggior parte del codice può usare il main actor invece di definire un nuovo global actor.

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

Applica questo attributo alla dichiarazione di una funzione, di un metodo, di una proprietà calcolata, di un subscript, di un inizializzatore di convenienza o di un deinizializzatore per esporre l'implementazione di quella dichiarazione come parte dell'interfaccia pubblica del modulo. Il compilatore può sostituire le chiamate a un simbolo inlinable con una copia dell'implementazione del simbolo nel punto di chiamata.

Il codice inlinable può interagire con i simboli `open` e `public` dichiarati in qualsiasi modulo, e può interagire con i simboli `internal` dichiarati nello stesso modulo che sono contrassegnati con l'attributo `usableFromInline`. Il codice inlinable non può interagire con i simboli `private` o `fileprivate`.

Questo attributo non può essere applicato a dichiarazioni annidate all'interno di funzioni né a dichiarazioni `fileprivate` o `private`. Le funzioni e le closure definite all'interno di una funzione inlinable sono implicitamente inlinable, anche se non possono essere contrassegnate con questo attributo.

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

Applica questo attributo alla dichiarazione di una struttura, di una classe o di un'enumerazione per indicare che contiene il punto di ingresso di primo livello per il flusso del programma. Il tipo deve fornire una funzione di tipo `main` che non accetta argomenti e restituisce `Void`. Per esempio:

```swift
@main
struct MyTopLevel {
    static func main() {
        // Qui va il codice di primo livello
    }
}
```

Un altro modo per descrivere i requisiti dell'attributo `main` è che il tipo su cui scrivi questo attributo deve soddisfare gli stessi requisiti dei tipi conformi al seguente protocollo ipotetico:

```swift
protocol ProvidesMain {
    static func main() throws
}
```

Il codice Swift che compili per creare un eseguibile può contenere al massimo un punto di ingresso di primo livello, come discusso in [Codice di primo livello](/riferimento-del-linguaggio/dichiarazioni.md#codice-di-primo-livello).

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

Applica questo attributo alla dichiarazione di un metodo, di una proprietà, di un subscript o di un inizializzatore per sopprimere un attributo `objc` implicito. L'attributo `nonobjc` indica al compilatore di rendere la dichiarazione non disponibile nel codice Objective-C, anche se è possibile rappresentarla in Objective-C.

Applicare questo attributo a un'estensione ha lo stesso effetto di applicarlo a ogni membro di quell'estensione che non è contrassegnato esplicitamente con l'attributo `objc`.

Usi l'attributo `nonobjc` per risolvere la circolarità dei metodi di bridging in una classe contrassegnata con l'attributo `objc`, e per consentire l'overload di metodi e inizializzatori in una classe contrassegnata con l'attributo `objc`.

Un metodo contrassegnato con l'attributo `nonobjc` non può eseguire l'override di un metodo contrassegnato con l'attributo `objc`. Tuttavia, un metodo contrassegnato con l'attributo `objc` può eseguire l'override di un metodo contrassegnato con l'attributo `nonobjc`. Analogamente, un metodo contrassegnato con l'attributo `nonobjc` non può soddisfare il requisito di un protocollo per un metodo contrassegnato con l'attributo `objc`.

### NSApplicationMain <a href="#nsapplicationmain" id="nsapplicationmain"></a>

{% hint style="danger" %}
**Deprecato:** Questo attributo è deprecato; usa invece l'attributo [main](/riferimento-del-linguaggio/attributi.md#main). In Swift 6, l'uso di questo attributo produce un errore in fase di compilazione.
{% endhint %}

Applica questo attributo a una classe per indicare che è il delegato dell'app. Usare questo attributo equivale a chiamare la funzione `NSApplicationMain(_:_:)`.

Se non usi questo attributo, fornisci un file `main.swift` con codice al primo livello che chiama la funzione `NSApplicationMain(_:_:)` come segue:

```swift
import AppKit
NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
```

Il codice Swift che compili per creare un eseguibile può contenere al massimo un punto di ingresso di primo livello, come discusso in [Codice di primo livello](/riferimento-del-linguaggio/dichiarazioni.md#codice-di-primo-livello).

### NSCopying <a href="#nscopying" id="nscopying"></a>

Applica questo attributo a una proprietà variabile memorizzata di una classe. Questo attributo fa sì che il setter della proprietà venga sintetizzato con una *copia* del valore della proprietà — restituita dal metodo `copyWithZone(_:)` — anziché con il valore della proprietà stessa. Il tipo della proprietà deve essere conforme al protocollo `NSCopying`.

L'attributo `NSCopying` si comporta in modo simile all'attributo di proprietà `copy` di Objective-C.

### NSManaged <a href="#nsmanaged" id="nsmanaged"></a>

Applica questo attributo a un metodo di istanza o a una proprietà variabile memorizzata di una classe che eredita da `NSManagedObject` per indicare che Core Data ne fornisce dinamicamente l'implementazione in fase di esecuzione, in base alla descrizione dell'entità associata. Per una proprietà contrassegnata con l'attributo `NSManaged`, Core Data fornisce anche la memoria in fase di esecuzione. Applicare questo attributo implica anche l'attributo `objc`.

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

Applica questo attributo a qualsiasi dichiarazione che possa essere rappresentata in Objective-C — per esempio, classi non annidate, protocolli, enumerazioni non generiche (limitate a tipi a valore grezzo interi), proprietà e metodi (inclusi getter e setter) di classi, protocolli e membri facoltativi di un protocollo, inizializzatori e subscript. L'attributo `objc` indica al compilatore che una dichiarazione è disponibile per l'uso nel codice Objective-C.

Applicare questo attributo a un'estensione ha lo stesso effetto di applicarlo a ogni membro di quell'estensione che non è contrassegnato esplicitamente con l'attributo `nonobjc`.

Il compilatore aggiunge implicitamente l'attributo `objc` alle sottoclassi di qualsiasi classe definita in Objective-C. Tuttavia, la sottoclasse non deve essere generica, e non deve ereditare da alcuna classe generica. Puoi aggiungere esplicitamente l'attributo `objc` a una sottoclasse che soddisfa questi criteri, per specificarne il nome in Objective-C come discusso più avanti. I protocolli contrassegnati con l'attributo `objc` non possono ereditare da protocolli che non sono contrassegnati con questo attributo.

L'attributo `objc` viene aggiunto implicitamente anche nei casi seguenti:

* La dichiarazione è un override in una sottoclasse, e la dichiarazione della superclasse ha l'attributo `objc`.
* La dichiarazione soddisfa un requisito di un protocollo che ha l'attributo `objc`.
* La dichiarazione ha l'attributo `IBAction`, `IBSegueAction`, `IBOutlet`, `IBDesignable`, `IBInspectable`, `NSManaged` o `GKInspectable`.

Se applichi l'attributo `objc` a un'enumerazione, ogni caso dell'enumerazione viene esposto al codice Objective-C come concatenazione del nome dell'enumerazione e del nome del caso. La prima lettera del nome del caso è maiuscola. Per esempio, un caso chiamato `venus` in un'enumerazione Swift `Planet` viene esposto al codice Objective-C come un caso chiamato `PlanetVenus`.

L'attributo `objc` accetta facoltativamente un singolo argomento dell'attributo, costituito da un identificatore. L'identificatore specifica il nome da esporre a Objective-C per l'entità a cui si applica l'attributo `objc`. Puoi usare questo argomento per dare un nome a classi, enumerazioni, casi di enumerazioni, protocolli, metodi, getter, setter e inizializzatori. Se specifichi il nome Objective-C di una classe, di un protocollo o di un'enumerazione, includi un prefisso di tre lettere nel nome, come descritto in [Conventions](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Conventions/Conventions.html#//apple_ref/doc/uid/TP40011210-CH10-SW1) in [Programming with Objective-C](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011210). L'esempio seguente espone il getter della proprietà `enabled` di `ExampleClass` al codice Objective-C come `isEnabled` anziché semplicemente con il nome della proprietà stessa.

```swift
class ExampleClass: NSObject {
    @objc var enabled: Bool {
        @objc(isEnabled) get {
            // Restituisce il valore appropriato
        }
    }
}
```

Per maggiori informazioni, vedi [Importing Swift into Objective-C](https://developer.apple.com/documentation/swift/imported_c_and_objective-c_apis/importing_swift_into_objective-c).

{% hint style="info" %}
**Nota:** L'argomento dell'attributo `objc` può anche cambiare il nome in fase di esecuzione di quella dichiarazione. Usi il nome in fase di esecuzione quando chiami funzioni che interagiscono con il runtime di Objective-C, come [`NSClassFromString(_:)`](https://developer.apple.com/documentation/foundation/nsclassfromstring\(_:\)), e quando specifichi i nomi delle classi nel file Info.plist di un'app. Se specifichi un nome passando un argomento, quel nome viene usato come nome nel codice Objective-C e come nome in fase di esecuzione. Se ometti l'argomento, il nome usato nel codice Objective-C corrisponde al nome nel codice Swift, e il nome in fase di esecuzione segue la normale convenzione del compilatore Swift per il name mangling.
{% endhint %}

### objcMembers <a href="#objcmembers" id="objcmembers"></a>

Applica questo attributo alla dichiarazione di una classe per applicare implicitamente l'attributo `objc` a tutti i membri compatibili con Objective-C della classe, delle sue estensioni, delle sue sottoclassi e di tutte le estensioni delle sue sottoclassi.

La maggior parte del codice dovrebbe invece usare l'attributo `objc`, per esporre solo le dichiarazioni necessarie. Se devi esporre molte dichiarazioni, puoi raggrupparle in un'estensione che ha l'attributo `objc`. L'attributo `objcMembers` è una comodità per le librerie che fanno un uso intenso delle funzionalità di introspezione del runtime di Objective-C. Applicare l'attributo `objc` quando non è necessario può aumentare le dimensioni del binario e influire negativamente sulle prestazioni.

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

Applica questo attributo a una dichiarazione per sopprimere il controllo rigoroso della concorrenza. Puoi applicare questo attributo ai seguenti tipi di dichiarazioni:

* Importazioni
* Strutture, classi e actor
* Enumerazioni e casi di enumerazioni
* Protocolli
* Variabili e costanti
* Subscript
* Inizializzatori
* Funzioni

Su una dichiarazione di importazione, questo attributo riduce il rigore del controllo della concorrenza per il codice che usa tipi del modulo importato. Nello specifico, i tipi del modulo importato che non sono contrassegnati esplicitamente come non sendable possono essere usati in un contesto che richiede tipi sendable.

Sulle altre dichiarazioni, questo attributo riduce il rigore del controllo della concorrenza per il codice che usa il simbolo dichiarato. Quando usi questo simbolo in un ambito che ha un controllo minimo della concorrenza, i vincoli relativi alla concorrenza specificati da quel simbolo, come i requisiti `Sendable` o i global actor, non vengono verificati.

Puoi usare questo attributo come segue, per facilitare la migrazione del codice al controllo rigoroso della concorrenza:

1. Abilita il controllo rigoroso.
2. Annota con l'attributo `preconcurrency` le importazioni dei moduli che non hanno abilitato il controllo rigoroso.
3. Dopo aver migrato un modulo al controllo rigoroso, rimuovi l'attributo `preconcurrency`. Il compilatore ti avvisa di tutti i punti in cui l'attributo `preconcurrency` su un'importazione non ha più effetto e dovrebbe essere rimosso.

Per le altre dichiarazioni, aggiungi l'attributo `preconcurrency` quando aggiungi vincoli relativi alla concorrenza alla dichiarazione, se hai ancora client che non sono migrati al controllo rigoroso. Rimuovi l'attributo `preconcurrency` dopo che tutti i tuoi client sono migrati.

Le dichiarazioni provenienti da Objective-C vengono sempre importate come se fossero contrassegnate con l'attributo `preconcurrency`.

### propertyWrapper <a href="#propertywrapper" id="propertywrapper"></a>

Applica questo attributo alla dichiarazione di una classe, di una struttura o di un'enumerazione per usare quel tipo come property wrapper. Quando applichi questo attributo a un tipo, crei un attributo personalizzato con lo stesso nome del tipo. Applica quel nuovo attributo a una proprietà di una classe, di una struttura o di un'enumerazione per incapsulare l'accesso alla proprietà attraverso un'istanza del tipo wrapper; applica l'attributo alla dichiarazione di una variabile memorizzata locale per incapsulare allo stesso modo l'accesso alla variabile. Le variabili calcolate, le variabili globali e le costanti non possono usare i property wrapper.

Il wrapper deve definire una proprietà di istanza `wrappedValue`. Il *valore incapsulato* della proprietà è il valore che il getter e il setter di questa proprietà espongono. Nella maggior parte dei casi, `wrappedValue` è un valore calcolato, ma può invece essere un valore memorizzato. Il wrapper definisce e gestisce qualsiasi memoria sottostante necessaria al suo valore incapsulato. Il compilatore sintetizza la memoria per l'istanza del tipo wrapper anteponendo al nome della proprietà incapsulata un trattino basso (`_`) — per esempio, il wrapper di `someProperty` è memorizzato come `_someProperty`. La memoria sintetizzata per il wrapper ha un livello di controllo degli accessi `private`.

Una proprietà che ha un property wrapper può includere blocchi `willSet` e `didSet`, ma non può eseguire l'override dei blocchi `get` o `set` sintetizzati dal compilatore.

Swift fornisce due forme di zucchero sintattico per l'inizializzazione di un property wrapper. Puoi usare la sintassi di assegnazione nella definizione di un valore incapsulato per passare l'espressione sul lato destro dell'assegnazione come argomento del parametro `wrappedValue` dell'inizializzatore del property wrapper. Puoi anche fornire argomenti all'attributo quando lo applichi a una proprietà, e quegli argomenti vengono passati all'inizializzatore del property wrapper. Per esempio, nel codice seguente, `SomeStruct` chiama ciascuno degli inizializzatori definiti da `SomeWrapper`.

```swift
@propertyWrapper
struct SomeWrapper {
    var wrappedValue: Int
    var someValue: Double
    init() {
        self.wrappedValue = 100
        self.someValue = 12.3
    }
    init(wrappedValue: Int) {
        self.wrappedValue = wrappedValue
        self.someValue = 45.6
    }
    init(wrappedValue value: Int, custom: Double) {
        self.wrappedValue = value
        self.someValue = custom
    }
}

struct SomeStruct {
    // Usa init()
    @SomeWrapper var a: Int

    // Usa init(wrappedValue:)
    @SomeWrapper var b = 10

    // Entrambe usano init(wrappedValue:custom:)
    @SomeWrapper(custom: 98.7) var c = 30
    @SomeWrapper(wrappedValue: 30, custom: 98.7) var d
}
```

Il *valore proiettato* di una proprietà incapsulata è un secondo valore che un property wrapper può usare per esporre funzionalità aggiuntive. L'autore di un tipo property wrapper è responsabile di determinare il significato del suo valore proiettato e di definire l'interfaccia che il valore proiettato espone. Per proiettare un valore da un property wrapper, definisci una proprietà di istanza `projectedValue` sul tipo wrapper. Il compilatore sintetizza un identificatore per il valore proiettato anteponendo al nome della proprietà incapsulata il simbolo del dollaro (`$`) — per esempio, il valore proiettato di `someProperty` è `$someProperty`. Il valore proiettato ha lo stesso livello di controllo degli accessi della proprietà incapsulata originale.

```swift
@propertyWrapper
struct WrapperWithProjection {
    var wrappedValue: Int
    var projectedValue: SomeProjection {
        return SomeProjection(wrapper: self)
    }
}
struct SomeProjection {
    var wrapper: WrapperWithProjection
}

struct SomeStruct {
    @WrapperWithProjection var x = 123
}
let s = SomeStruct()
s.x           // Valore Int
s.$x          // Valore SomeProjection
s.$x.wrapper  // Valore WrapperWithProjection
```

Se il valore proiettato incapsula una variabile il cui nome usa un identificatore grezzo, usi un identificatore grezzo anche per fare riferimento alla memoria sintetizzata del valore e al suo valore proiettato. Scrivi il trattino basso o il simbolo del dollaro all'interno degli apici inversi; per esempio, `` someValue.`_some raw identifier` `` fa riferimento alla memoria sintetizzata di una proprietà che include spazi nel nome, e `` someValue.`$some raw identifier` `` fa riferimento al suo valore proiettato.

### resultBuilder <a href="#resultbuilder" id="resultbuilder"></a>

Applica questo attributo a una classe, a una struttura o a un'enumerazione per usare quel tipo come result builder. Un *result builder* è un tipo che costruisce passo dopo passo una struttura di dati annidata. Usi i result builder per implementare un linguaggio specifico di dominio (DSL) per creare strutture di dati annidate in modo naturale e dichiarativo. Per un esempio di come usare l'attributo `resultBuilder`, vedi [Result builder](/guida-al-linguaggio/operatori-avanzati.md#result-builder).

#### Metodi di costruzione del risultato <a href="#metodi-di-costruzione-del-risultato" id="metodi-di-costruzione-del-risultato"></a>

Un result builder implementa i metodi statici descritti di seguito. Poiché tutte le funzionalità del result builder sono esposte tramite metodi statici, non inizializzi mai un'istanza di quel tipo. Un result builder deve implementare il metodo `buildBlock(_:)` oppure entrambi i metodi `buildPartialBlock(first:)` e `buildPartialBlock(accumulated:next:)`. Gli altri metodi — che abilitano funzionalità aggiuntive nel DSL — sono facoltativi. La dichiarazione di un tipo result builder non deve in realtà includere alcuna conformità a protocolli.

La descrizione dei metodi statici usa tre tipi come segnaposto. Il tipo `Expression` è un segnaposto per il tipo dell'input del result builder, `Component` è un segnaposto per il tipo di un risultato parziale, e `FinalResult` è un segnaposto per il tipo del risultato prodotto dal result builder. Sostituisci questi tipi con i tipi effettivi usati dal tuo result builder. Se i tuoi metodi di costruzione del risultato non specificano un tipo per `Expression` o `FinalResult`, per impostazione predefinita questi coincidono con `Component`.

I metodi di costruzione dei blocchi sono i seguenti:

* **`static func buildBlock(_ components: Component...) -> Component`**: Combina un array di risultati parziali in un unico risultato parziale.
* **`static func buildPartialBlock(first: Component) -> Component`**: Costruisce un componente di risultato parziale a partire dal primo componente. Implementa sia questo metodo sia `buildPartialBlock(accumulated:next:)` per supportare la costruzione dei blocchi un componente alla volta. Rispetto a `buildBlock(_:)`, questo approccio riduce la necessità di overload generici che gestiscono numeri diversi di argomenti.
* **`static func buildPartialBlock(accumulated: Component, next: Component) -> Component`**: Costruisce un componente di risultato parziale combinando un componente accumulato con un nuovo componente. Implementa sia questo metodo sia `buildPartialBlock(first:)` per supportare la costruzione dei blocchi un componente alla volta. Rispetto a `buildBlock(_:)`, questo approccio riduce la necessità di overload generici che gestiscono numeri diversi di argomenti.

Un result builder può implementare tutti e tre i metodi di costruzione dei blocchi elencati sopra; in tal caso, la disponibilità determina quale metodo viene chiamato. Per impostazione predefinita, Swift chiama i metodi `buildPartialBlock(first:)` e `buildPartialBlock(accumulated:next:)`. Per fare in modo che Swift chiami invece `buildBlock(_:)`, contrassegna la dichiarazione che li racchiude come disponibile prima della disponibilità che scrivi su `buildPartialBlock(first:)` e `buildPartialBlock(accumulated:next:)`.

I metodi aggiuntivi di costruzione del risultato sono i seguenti:

* **`static func buildOptional(_ component: Component?) -> Component`**: Costruisce un risultato parziale a partire da un risultato parziale che può essere `nil`. Implementa questo metodo per supportare le istruzioni `if` che non includono una clausola `else`.
* **`static func buildEither(first: Component) -> Component`**: Costruisce un risultato parziale il cui valore varia a seconda di una condizione. Implementa sia questo metodo sia `buildEither(second:)` per supportare le istruzioni `switch` e le istruzioni `if` che includono una clausola `else`.
* **`static func buildEither(second: Component) -> Component`**: Costruisce un risultato parziale il cui valore varia a seconda di una condizione. Implementa sia questo metodo sia `buildEither(first:)` per supportare le istruzioni `switch` e le istruzioni `if` che includono una clausola `else`.
* **`static func buildArray(_ components: [Component]) -> Component`**: Costruisce un risultato parziale a partire da un array di risultati parziali. Implementa questo metodo per supportare i cicli `for`.
* **`static func buildExpression(_ expression: Expression) -> Component`**: Costruisce un risultato parziale a partire da un'espressione. Puoi implementare questo metodo per eseguire una pre-elaborazione — per esempio, convertire le espressioni in un tipo interno — o per fornire informazioni aggiuntive per l'inferenza di tipo nei punti d'uso.
* **`static func buildFinalResult(_ component: Component) -> FinalResult`**: Costruisce un risultato finale a partire da un risultato parziale. Puoi implementare questo metodo come parte di un result builder che usa un tipo diverso per i risultati parziali e finali, o per eseguire un'altra post-elaborazione su un risultato prima di restituirlo.
* **`static func buildLimitedAvailability(_ component: Component) -> Component`**: Costruisce un risultato parziale che cancella le informazioni sul tipo. Puoi implementare questo metodo per impedire che le informazioni sul tipo si propaghino al di fuori di un'istruzione di controllo del compilatore che esegue un controllo di disponibilità.

Per esempio, il codice seguente definisce un semplice result builder che costruisce un array di interi. Questo codice definisce `Component` ed `Expression` come alias di tipo, per rendere più facile far corrispondere gli esempi seguenti all'elenco dei metodi qui sopra.

```swift
@resultBuilder
struct ArrayBuilder {
    typealias Component = [Int]
    typealias Expression = Int
    static func buildExpression(_ element: Expression) -> Component {
        return [element]
    }
    static func buildOptional(_ component: Component?) -> Component {
        guard let component = component else { return [] }
        return component
    }
    static func buildEither(first component: Component) -> Component {
        return component
    }
    static func buildEither(second component: Component) -> Component {
        return component
    }
    static func buildArray(_ components: [Component]) -> Component {
        return Array(components.joined())
    }
    static func buildBlock(_ components: Component...) -> Component {
        return Array(components.joined())
    }
}
```

#### Trasformazioni del risultato <a href="#trasformazioni-del-risultato" id="trasformazioni-del-risultato"></a>

Le seguenti trasformazioni sintattiche vengono applicate ricorsivamente per trasformare il codice che usa la sintassi dei result builder in codice che chiama i metodi statici del tipo result builder:

* Se il result builder ha un metodo `buildExpression(_:)`, ogni espressione diventa una chiamata a quel metodo. Questa trasformazione è sempre la prima. Per esempio, le dichiarazioni seguenti sono equivalenti:

  ```swift
  @ArrayBuilder var builderNumber: [Int] { 10 }
  var manualNumber = ArrayBuilder.buildExpression(10)
  ```

  * Un'istruzione di assegnazione viene trasformata come un'espressione, ma viene considerata come una che restituisce `()`. Puoi definire un overload di `buildExpression(_:)` che accetta un argomento di tipo `()` per gestire in modo specifico le assegnazioni.
* Un'istruzione di diramazione che verifica una condizione di disponibilità diventa una chiamata al metodo `buildLimitedAvailability(_:)`, se quel metodo è implementato. Se non implementi `buildLimitedAvailability(_:)`, le istruzioni di diramazione che verificano la disponibilità usano le stesse trasformazioni delle altre istruzioni di diramazione. Questa trasformazione avviene prima della trasformazione in una chiamata a `buildEither(first:)`, `buildEither(second:)` o `buildOptional(_:)`.

  Usi il metodo `buildLimitedAvailability(_:)` per cancellare le informazioni sul tipo che cambiano a seconda del ramo intrapreso. Per esempio, i metodi `buildEither(first:)` e `buildEither(second:)` seguenti usano un tipo generico che cattura le informazioni sul tipo di entrambi i rami.

  ```swift
  protocol Drawable {
      func draw() -> String
  }
  struct Text: Drawable {
      var content: String
      init(_ content: String) { self.content = content }
      func draw() -> String { return content }
  }
  struct Line<D: Drawable>: Drawable {
      var elements: [D]
      func draw() -> String {
          return elements.map { $0.draw() }.joined(separator: "")
      }
  }
  struct DrawEither<First: Drawable, Second: Drawable>: Drawable {
      var content: Drawable
      func draw() -> String { return content.draw() }
  }

  @resultBuilder
  struct DrawingBuilder {
      static func buildBlock<D: Drawable>(_ components: D...) -> Line<D> {
          return Line(elements: components)
      }
      static func buildEither<First, Second>(first: First)
              -> DrawEither<First, Second> {
          return DrawEither(content: first)
      }
      static func buildEither<First, Second>(second: Second)
              -> DrawEither<First, Second> {
          return DrawEither(content: second)
      }
  }
  ```

  Tuttavia, questo approccio causa un problema nel codice che contiene controlli di disponibilità:

  ```swift
  @available(macOS 99, *)
  struct FutureText: Drawable {
      var content: String
      init(_ content: String) { self.content = content }
      func draw() -> String { return content }
  }
  @DrawingBuilder var brokenDrawing: Drawable {
      if #available(macOS 99, *) {
          FutureText("Inside.future")  // Problema
      } else {
          Text("Inside.present")
      }
  }
  // Il tipo di brokenDrawing è Line<DrawEither<Line<FutureText>, Line<Text>>>
  ```

  Nel codice qui sopra, `FutureText` compare come parte del tipo di `brokenDrawing` perché è uno dei tipi nel tipo generico `DrawEither`. Ciò potrebbe causare l'arresto anomalo del programma se `FutureText` non è disponibile in fase di esecuzione, anche nel caso in cui quel tipo non venga esplicitamente usato.

  Per risolvere questo problema, implementa un metodo `buildLimitedAvailability(_:)` per cancellare le informazioni sul tipo restituendo un tipo sempre disponibile. Per esempio, il codice seguente costruisce un valore `AnyDrawable` a partire dal suo controllo di disponibilità.

  ```swift
  struct AnyDrawable: Drawable {
      var content: Drawable
      func draw() -> String { return content.draw() }
  }
  extension DrawingBuilder {
      static func buildLimitedAvailability(_ content: some Drawable) -> AnyDrawable {
          return AnyDrawable(content: content)
      }
  }

  @DrawingBuilder var typeErasedDrawing: Drawable {
      if #available(macOS 99, *) {
          FutureText("Inside.future")
      } else {
          Text("Inside.present")
      }
  }
  // Il tipo di typeErasedDrawing è Line<DrawEither<AnyDrawable, Line<Text>>>
  ```
* Un'istruzione di diramazione diventa una serie di chiamate annidate ai metodi `buildEither(first:)` e `buildEither(second:)`. Le condizioni e i casi delle istruzioni vengono mappati sui nodi foglia di un albero binario, e l'istruzione diventa una chiamata annidata ai metodi `buildEither` che segue il percorso verso quel nodo foglia a partire dal nodo radice.

  Per esempio, se scrivi un'istruzione switch che ha tre casi, il compilatore usa un albero binario con tre nodi foglia. Analogamente, poiché il percorso dal nodo radice al secondo caso è "secondo figlio" e poi "primo figlio", quel caso diventa una chiamata annidata come `buildEither(first: buildEither(second: ... ))`. Le dichiarazioni seguenti sono equivalenti:

  ```swift
  let someNumber = 19
  @ArrayBuilder var builderConditional: [Int] {
      if someNumber < 12 {
          31
      } else if someNumber == 19 {
          32
      } else {
          33
      }
  }

  var manualConditional: [Int]
  if someNumber < 12 {
      let partialResult = ArrayBuilder.buildExpression(31)
      let outerPartialResult = ArrayBuilder.buildEither(first: partialResult)
      manualConditional = ArrayBuilder.buildEither(first: outerPartialResult)
  } else if someNumber == 19 {
      let partialResult = ArrayBuilder.buildExpression(32)
      let outerPartialResult = ArrayBuilder.buildEither(second: partialResult)
      manualConditional = ArrayBuilder.buildEither(first: outerPartialResult)
  } else {
      let partialResult = ArrayBuilder.buildExpression(33)
      manualConditional = ArrayBuilder.buildEither(second: partialResult)
  }
  ```

  * Un'istruzione di diramazione che potrebbe non produrre un valore, come un'istruzione `if` senza una clausola `else`, diventa una chiamata a `buildOptional(_:)`. Se la condizione dell'istruzione `if` è soddisfatta, il suo blocco di codice viene trasformato e passato come argomento; altrimenti, `buildOptional(_:)` viene chiamato con `nil` come argomento. Per esempio, le dichiarazioni seguenti sono equivalenti:

  ```swift
  @ArrayBuilder var builderOptional: [Int] {
      if (someNumber % 2) == 1 { 20 }
  }

  var partialResult: [Int]? = nil
  if (someNumber % 2) == 1 {
      partialResult = ArrayBuilder.buildExpression(20)
  }
  var manualOptional = ArrayBuilder.buildOptional(partialResult)
  ```

  * Se il result builder implementa i metodi `buildPartialBlock(first:)` e `buildPartialBlock(accumulated:next:)`, un blocco di codice o un'istruzione `do` diventa una chiamata a quei metodi. La prima istruzione all'interno del blocco viene trasformata per diventare un argomento del metodo `buildPartialBlock(first:)`, e le istruzioni rimanenti diventano chiamate annidate al metodo `buildPartialBlock(accumulated:next:)`. Per esempio, le dichiarazioni seguenti sono equivalenti:

  ```swift
  struct DrawBoth<First: Drawable, Second: Drawable>: Drawable {
      var first: First
      var second: Second
      func draw() -> String { return first.draw() + second.draw() }
  }

  @resultBuilder
  struct DrawingPartialBlockBuilder {
      static func buildPartialBlock<D: Drawable>(first: D) -> D {
          return first
      }
      static func buildPartialBlock<Accumulated: Drawable, Next: Drawable>(
          accumulated: Accumulated, next: Next
      ) -> DrawBoth<Accumulated, Next> {
          return DrawBoth(first: accumulated, second: next)
      }
  }

  @DrawingPartialBlockBuilder var builderBlock: some Drawable {
      Text("First")
      Line(elements: [Text("Second"), Text("Third")])
      Text("Last")
  }

  let partialResult1 = DrawingPartialBlockBuilder.buildPartialBlock(first: Text("first"))
  let partialResult2 = DrawingPartialBlockBuilder.buildPartialBlock(
      accumulated: partialResult1,
      next: Line(elements: [Text("Second"), Text("Third")])
  )
  let manualResult = DrawingPartialBlockBuilder.buildPartialBlock(
      accumulated: partialResult2,
      next: Text("Last")
  )
  ```

  * Altrimenti, un blocco di codice o un'istruzione `do` diventa una chiamata al metodo `buildBlock(_:)`. Ciascuna delle istruzioni all'interno del blocco viene trasformata, una alla volta, e diventano gli argomenti del metodo `buildBlock(_:)`. Per esempio, le dichiarazioni seguenti sono equivalenti:

  ```swift
  @ArrayBuilder var builderBlock: [Int] {
      100
      200
      300
  }

  var manualBlock = ArrayBuilder.buildBlock(
      ArrayBuilder.buildExpression(100),
      ArrayBuilder.buildExpression(200),
      ArrayBuilder.buildExpression(300)
  )
  ```

  * Un ciclo `for` diventa una variabile temporanea, un ciclo `for` e una chiamata al metodo `buildArray(_:)`. Il nuovo ciclo `for` itera sulla sequenza e aggiunge ciascun risultato parziale a quell'array. L'array temporaneo viene passato come argomento nella chiamata a `buildArray(_:)`. Per esempio, le dichiarazioni seguenti sono equivalenti:

  ```swift
  @ArrayBuilder var builderArray: [Int] {
      for i in 5...7 {
          100 + i
      }
  }

  var temporary: [[Int]] = []
  for i in 5...7 {
      let partialResult = ArrayBuilder.buildExpression(100 + i)
      temporary.append(partialResult)
  }
  let manualArray = ArrayBuilder.buildArray(temporary)
  ```

  * Se il result builder ha un metodo `buildFinalResult(_:)`, il risultato finale diventa una chiamata a quel metodo. Questa trasformazione è sempre l'ultima.

Sebbene il comportamento della trasformazione sia descritto in termini di variabili temporanee, usare un result builder in realtà non crea alcuna nuova dichiarazione visibile dal resto del tuo codice.

Non puoi usare istruzioni `break`, `continue`, `defer`, `guard` o `return`, istruzioni `while` o istruzioni `do`-`catch` nel codice che un result builder trasforma.

Il processo di trasformazione non modifica le dichiarazioni nel codice, il che ti permette di usare costanti e variabili temporanee per costruire le espressioni pezzo per pezzo. Inoltre non modifica le istruzioni `throw`, le istruzioni di diagnostica in fase di compilazione o le closure che contengono un'istruzione `return`.

Ogni volta che è possibile, le trasformazioni vengono accorpate. Per esempio, l'espressione `4 + 5 * 6` diventa `buildExpression(4 + 5 * 6)` anziché più chiamate a quella funzione. Analogamente, le istruzioni di diramazione annidate diventano un unico albero binario di chiamate ai metodi `buildEither`.

#### Attributi personalizzati dei result builder <a href="#attributi-personalizzati-dei-result-builder" id="attributi-personalizzati-dei-result-builder"></a>

Creare un tipo result builder crea un attributo personalizzato con lo stesso nome. Puoi applicare quell'attributo nei punti seguenti:

* Sulla dichiarazione di una funzione, il result builder costruisce il corpo della funzione.
* Sulla dichiarazione di una variabile o di un subscript che include un getter, il result builder costruisce il corpo del getter.
* Su un parametro nella dichiarazione di una funzione, il result builder costruisce il corpo di una closure passata come argomento corrispondente.

Applicare un attributo result builder non influisce sulla compatibilità ABI. Applicare un attributo result builder a un parametro rende quell'attributo parte dell'interfaccia della funzione, il che può influire sulla compatibilità del codice sorgente.

### requires\_stored\_property\_inits <a href="#requires-stored-property-inits" id="requires-stored-property-inits"></a>

Applica questo attributo alla dichiarazione di una classe per richiedere che tutte le proprietà memorizzate all'interno della classe forniscano valori predefiniti come parte delle loro definizioni. Questo attributo viene inferito per qualsiasi classe che eredita da `NSManagedObject`.

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

Applica questo attributo a una dichiarazione `import` per importare quel modulo con modifiche al suo controllo degli accessi che semplificano il test del codice del modulo. Le entità del modulo importato contrassegnate con il modificatore di livello di accesso `internal` vengono importate come se fossero dichiarate con il modificatore di livello di accesso `public`. Le classi e i membri delle classi contrassegnati con il modificatore di livello di accesso `internal` o `public` vengono importati come se fossero dichiarati con il modificatore di livello di accesso `open`. Il modulo importato deve essere compilato con i test abilitati.

### UIApplicationMain <a href="#uiapplicationmain" id="uiapplicationmain"></a>

{% hint style="danger" %}
**Deprecato:** Questo attributo è deprecato; usa invece l'attributo [main](/riferimento-del-linguaggio/attributi.md#main). In Swift 6, l'uso di questo attributo produce un errore in fase di compilazione.
{% endhint %}

Applica questo attributo a una classe per indicare che è il delegato dell'app. Usare questo attributo equivale a chiamare la funzione `UIApplicationMain` e passare il nome di questa classe come nome della classe delegata.

Se non usi questo attributo, fornisci un file `main.swift` con codice al primo livello che chiama la funzione [`UIApplicationMain(_:_:_:_:)`](https://developer.apple.com/documentation/uikit/uiapplicationmain\(_:_:_:_:\)-1yub7). Per esempio, se la tua app usa una sottoclasse personalizzata di `UIApplication` come classe principale, chiama la funzione `UIApplicationMain(_:_:_:_:)` invece di usare questo attributo.

Il codice Swift che compili per creare un eseguibile può contenere al massimo un punto di ingresso di primo livello, come discusso in [Codice di primo livello](/riferimento-del-linguaggio/dichiarazioni.md#codice-di-primo-livello).

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

Applica questo attributo a un tipo protocollo come parte dell'elenco dei protocolli adottati nella dichiarazione di un tipo per disattivare l'applicazione dei requisiti di quel protocollo.

L'unico protocollo supportato è [`Sendable`](https://developer.apple.com/documentation/swift/sendable).

### usableFromInline <a href="#usablefrominline" id="usablefrominline"></a>

Applica questo attributo alla dichiarazione di una funzione, di un metodo, di una proprietà calcolata, di un subscript, di un inizializzatore o di un deinizializzatore per consentire che quel simbolo venga usato nel codice inlinable definito nello stesso modulo della dichiarazione. La dichiarazione deve avere il modificatore di livello di accesso `internal`. Una struttura o una classe contrassegnata come `usableFromInline` può usare per le sue proprietà solo tipi pubblici o `usableFromInline`. Un'enumerazione contrassegnata come `usableFromInline` può usare solo tipi pubblici o `usableFromInline` per i valori grezzi e i valori associati dei suoi casi.

Come il modificatore di livello di accesso `public`, questo attributo espone la dichiarazione come parte dell'interfaccia pubblica del modulo. A differenza di `public`, il compilatore non consente che le dichiarazioni contrassegnate con `usableFromInline` vengano referenziate per nome nel codice al di fuori del modulo, anche se il simbolo della dichiarazione viene esportato. Tuttavia, il codice al di fuori del modulo potrebbe comunque essere in grado di interagire con il simbolo della dichiarazione usando comportamenti in fase di esecuzione.

Le dichiarazioni contrassegnate con l'attributo `inlinable` sono implicitamente utilizzabili dal codice inlinable. Sebbene sia `inlinable` sia `usableFromInline` possano essere applicati a dichiarazioni `internal`, applicare entrambi gli attributi è un errore.

### warn\_unqualified\_access <a href="#warn-unqualified-access" id="warn-unqualified-access"></a>

Applica questo attributo a una funzione di primo livello, a un metodo di istanza o a un metodo di classe o statico per generare avvisi quando quella funzione o quel metodo viene usato senza un qualificatore che lo preceda, come il nome di un modulo, il nome di un tipo o una variabile o costante di istanza. Usa questo attributo per contribuire a scoraggiare l'ambiguità tra funzioni con lo stesso nome accessibili dallo stesso ambito.

Per esempio, la libreria standard di Swift include sia una funzione di primo livello [`min(_:_:)`](https://developer.apple.com/documentation/swift/min\(_:_:\)) sia un metodo [`min()`](https://developer.apple.com/documentation/swift/sequence/min\(\)) per le sequenze con elementi confrontabili. Il metodo delle sequenze è dichiarato con l'attributo `warn_unqualified_access` per contribuire a ridurre la confusione quando si tenta di usare l'uno o l'altro dall'interno di un'estensione di `Sequence`.

### Attributi di dichiarazione usati da Interface Builder <a href="#attributi-di-dichiarazione-usati-da-interface-builder" id="attributi-di-dichiarazione-usati-da-interface-builder"></a>

Gli attributi di Interface Builder sono attributi di dichiarazione usati da Interface Builder per sincronizzarsi con Xcode. Swift fornisce i seguenti attributi di Interface Builder: `IBAction`, `IBSegueAction`, `IBOutlet`, `IBDesignable` e `IBInspectable`. Questi attributi sono concettualmente uguali ai loro corrispettivi in Objective-C.

Applichi gli attributi `IBOutlet` e `IBInspectable` alle dichiarazioni di proprietà di una classe. Applichi gli attributi `IBAction` e `IBSegueAction` alle dichiarazioni di metodi di una classe e l'attributo `IBDesignable` alle dichiarazioni di classi.

Applicare l'attributo `IBAction`, `IBSegueAction`, `IBOutlet`, `IBDesignable` o `IBInspectable` implica anche l'attributo `objc`.

## Attributi di tipo <a href="#attributi-di-tipo" id="attributi-di-tipo"></a>

Puoi applicare gli attributi di tipo solo ai tipi.

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

Applica questo attributo per ritardare la valutazione di un'espressione racchiudendo automaticamente quell'espressione in una closure senza argomenti. Lo applichi al tipo di un parametro nella dichiarazione di una funzione o di un metodo, per un parametro il cui tipo è un tipo funzione che non accetta argomenti e che restituisce un valore del tipo dell'espressione. Per un esempio di come usare l'attributo `autoclosure`, vedi [Autoclosure](/guida-al-linguaggio/closure.md#autoclosure) e [Tipo funzione](/riferimento-del-linguaggio/tipi.md#tipo-funzione).

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

Applica questo attributo al tipo di una funzione per indicarne le convenzioni di chiamata.

L'attributo `convention` compare sempre con uno degli argomenti seguenti:

* L'argomento `swift` indica un riferimento a una funzione Swift. Questa è la convenzione di chiamata standard per i valori funzione in Swift.
* L'argomento `block` indica un riferimento a un blocco compatibile con Objective-C. Il valore funzione è rappresentato come un riferimento all'oggetto blocco, che è un oggetto Objective-C compatibile con `id` che incorpora la sua funzione di invocazione all'interno dell'oggetto. La funzione di invocazione usa la convenzione di chiamata del C.
* L'argomento `c` indica un riferimento a una funzione C. Il valore funzione non porta con sé alcun contesto e usa la convenzione di chiamata del C.

Con poche eccezioni, una funzione con qualsiasi convenzione di chiamata può essere usata quando è necessaria una funzione con qualsiasi altra convenzione di chiamata. Una funzione globale non generica, una funzione locale che non cattura alcuna variabile locale, o una closure che non cattura alcuna variabile locale può essere convertita alla convenzione di chiamata del C. Le altre funzioni Swift non possono essere convertite alla convenzione di chiamata del C. Una funzione con la convenzione di chiamata dei blocchi Objective-C non può essere convertita alla convenzione di chiamata del C.

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

Applica questo attributo al tipo di un parametro nella dichiarazione di una funzione o di un metodo per indicare che il valore del parametro può essere memorizzato per un'esecuzione successiva. Ciò significa che il valore può sopravvivere alla durata della chiamata. I parametri di tipo funzione con l'attributo di tipo `escaping` richiedono l'uso esplicito di `self.` per proprietà o metodi. Per un esempio di come usare l'attributo `escaping`, vedi [Closure escaping](/guida-al-linguaggio/closure.md#closure-escaping).

### Sendable <a href="#sendable" id="sendable"></a>

Applica questo attributo al tipo di una funzione per indicare che la funzione o la closure è sendable. Applicare questo attributo a un tipo funzione ha lo stesso significato di rendere un tipo non funzione conforme al protocollo [`Sendable`](https://developer.apple.com/documentation/swift/sendable).

Questo attributo viene inferito su funzioni e closure se la funzione o la closure viene usata in un contesto che si aspetta un valore sendable, e la funzione o la closure soddisfa i requisiti per essere sendable.

Un tipo funzione sendable è un sottotipo del corrispondente tipo funzione non sendable.

## Attributi dei casi di switch <a href="#attributi-dei-casi-di-switch" id="attributi-dei-casi-di-switch"></a>

Puoi applicare gli attributi dei casi di switch solo ai casi di switch.

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

Applica questo attributo a un caso di switch per indicare che non ci si aspetta che corrisponda ad alcun caso dell'enumerazione noto nel momento in cui il codice viene compilato. Per un esempio di come usare l'attributo `unknown`, vedi [Switch sui casi futuri di un'enumerazione](/riferimento-del-linguaggio/istruzioni.md#switch-sui-casi-futuri-di-unenumerazione).

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

*attribute* → **`@`** *attribute-name* *attribute-argument-clause?*\
*attribute-name* → *identifier*\
*attribute-argument-clause* → **`(`** *balanced-tokens?* **`)`**\
*attributes* → *attribute* *attributes?*

*balanced-tokens* → *balanced-token* *balanced-tokens?*\
*balanced-token* → **`(`** *balanced-tokens?* **`)`**\
*balanced-token* → **`[`** *balanced-tokens?* **`]`**\
*balanced-token* → **`{`** *balanced-tokens?* **`}`**\
*balanced-token* → Any identifier, keyword, literal, or operator\
*balanced-token* → Any punctuation except **`(`**, **`)`**, **`[`**, **`]`**, **`{`**, or **`}`**
{% endhint %}
