Copy-on-write preserva a semântica de valor e adia a cópia do armazenamento. Separe o armazenamento compartilhado antes de alterá-lo; quando a posse for única, altere diretamente. Nem todo struct implementa essa estratégia automaticamente.
Mecanismo e decisão de projeto
A semântica de uma coleção padrão e a responsabilidade de implementar armazenamento próprio são diferentes. Aqui uma classe privada guarda um array de inteiros e métodos mutáveis consultam isKnownUniquelyReferenced. Todas as formas de alteração precisam manter essa disciplina. Fonte primária
Código reproduzível
Após atribuir IntBuffer, verificamos por identidade que ambos compartilham Storage. Adicionar 3 à cópia deve separar o armazenamento e preservar o array original. Adicionar 4 depois não deve separá-lo novamente, pois a cópia já possui Storage de forma única.
Este exemplo independente foi executado em 2026-10-23 com Apple Swift 6.4 para arm64 macOS, no modo de linguagem Swift 6. Não requer rede nem pacotes adicionais.
Baixar o arquivo Swift completo
Execute o comando na pasta do download. As precondições interrompem a execução se uma verificação falhar. Não use -Ounchecked: essa opção remove as verificações.
swift -swift-version 6 swift-copy-on-write-prototype-pattern.swift
struct IntBuffer {
private final class Storage {
var values: [Int]
init(_ values: [Int]) { self.values = values }
}
private var storage: Storage
private(set) var detachments = 0
init(_ values: [Int]) { storage = Storage(values) }
var values: [Int] { storage.values }
func sharesStorage(with other: IntBuffer) -> Bool {
storage === other.storage
}
mutating func append(_ value: Int) {
if !isKnownUniquelyReferenced(&storage) {
storage = Storage(storage.values)
detachments += 1
}
storage.values.append(value)
}
}
let original = IntBuffer([1, 2])
var copy = original
precondition(copy.sharesStorage(with: original))
copy.append(3)
precondition(!copy.sharesStorage(with: original))
precondition(original.values == [1, 2] && copy.values == [1, 2, 3])
copy.append(4)
precondition(copy.detachments == 1 && copy.values == [1, 2, 3, 4])
print("shared-before=true shared-after=false detachments=1 original=[1,2] copy=[1,2,3,4]")
Saída registrada e interpretação
shared-before=true shared-after=false detachments=1 original=[1,2] copy=[1,2,3,4]
detachments=1 conta uma separação do nosso wrapper Storage. O original fica em [1,2] e a cópia em [1,2,3,4]. Isso não mede alocações do buffer interno de Array, que pode usar sua própria implementação CoW.
Escopo e limitações
Este é um exemplo didático de fluxo único, não uma coleção segura entre threads. Verificar unicidade não sincroniza acessos. Um array de instâncias de classe também não clona profundamente seus elementos: tipos de valor não eliminam todos os usos do padrão Prototype.
O que verificar em seguida
Distinga dados que exigem cópias independentes daqueles que podem ser compartilhados. Meça o desempenho com cargas reais e prefira coleções padrão, salvo necessidade concreta. O experimento class versus struct mostra o compartilhamento de referências internas.
Fontes e verificação
- Swift Standard Library: isKnownUniquelyReferencedSwift.org · Documentação oficial · Consultado 23 de outubro de 2026Evidência: Fonte do contrato de implementação e da explicação. A saída foi verificada separadamente com o experimento incluído aqui.

