String
, Array
e Dictionary
sono tutte le strutture (che vengono memorizzate nello stack), ma il loro "contenuto" di dimensioni dinamiche è memorizzato in un buffer allocato nello stack. Questo buffer fa parte di un oggetto, a cui fa riferimento la struct.
Prendi Array
ad esempio, il cui codice sorgente è disponibile su GitHub (come nel resto del linguaggio di programmazione Swift).
Puoi vedere che la struttura Array
contiene un singolo membro: internal var _buffer: _Buffer
. Per Array
, questo tipo di _Buffer
è un typealias
per entrambi _ArrayBuffer<Element>
(se viene utilizzato il runtime Objective C, per un bridging più veloce verso / da NSArray
) o _ContiguousArrayBuffer<Element>
.
Avere l'oggetto _Buffer
racchiuso in una struct ( Array
) come questo è ciò che consente a Array
di avere un comportamento copy-on-write. Le copie di Array
possono essere rese molto economiche semplicemente copiando il riferimento _buffer
dall'array sorgente all'array di destinazione. Quando viene eseguita un'operazione mutabile, Array
controlla se il suo _buffer
è referenziato in modo univoco (ovvero nessun altro Array
condivide lo stesso _buffer ').
- Se si fa riferimento in modo univoco, l'operazione mutabile può essere eseguita direttamente su
_buffer
, senza la possibilità di modificare involontariamente un altro Array
(poiché non vi è altro Array
che condivide questo _buffer
.)
- Se non viene fatto riferimento in modo univoco, viene eseguita una copia e l'operazione mutevole viene eseguita sulla copia.