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.