Copy-on-Writeは値の意味を保ちながら保存領域のコピーを遅らせる実装戦略です。共有中なら変更前に分離し、単独所有なら直接変更します。すべてのstructに自動で備わる機能ではありません。
仕組みと設計の判断基準
標準コレクションの値の意味と、自作保存領域の実装責任は別です。ここではprivateなクラスに整数配列を持たせ、変更メソッドでisKnownUniquelyReferencedにより強参照の一意性を調べます。すべての変更経路でこの規律を守る必要があります。 一次資料
再現コード
IntBufferの代入直後、同じStorageを参照することをidentityで確認します。コピー側へ3を追加すると保存領域が分離し、原本の配列は保たれるはずです。次に4を追加する時点ではStorageを単独所有しているので、追加の分離は不要です。
この独立したサンプルは2026-10-23に、arm64 macOS向けのApple Swift 6.4をSwift 6言語モードで実行しました。ネットワーク接続や追加パッケージは不要です。
ダウンロード先のフォルダーで実行してください。検証条件を満たさない場合はpreconditionで停止します。検証が削除されるため、-Ouncheckedは使用しないでください。
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]")
実行結果と読み取り方
shared-before=true shared-after=false detachments=1 original=[1,2] copy=[1,2,3,4]
detachments=1は、自作Storageラッパーの分離が一度だったことを示します。原本は[1,2]、コピーは[1,2,3,4]です。内部Arrayバッファの実際の割り当て回数ではありません。そのArrayは独自のCoW実装を利用できます。
適用範囲と注意点
単一実行フロー用の学習例であり、スレッド安全なコレクションではありません。一意性検査は同期機構ではありません。クラスを要素とする配列も要素を深く複製しないため、値型がすべてのプロトタイプパターンを不要にするとは言えません。
次に確認すること
独立コピーが必要なデータと共有可能なデータを分けてください。性能は実際の負荷で測定し、自作型が必要でなければ標準コレクションを優先します。内部参照の共有はclassとstructの実験で確認できます。
出典と確認基準
- Swift Standard Library: isKnownUniquelyReferencedSwift.org · 公式ドキュメント · 確認日 2026年10月23日根拠: 実装の契約と説明の根拠です。出力は、この記事に掲載した実験で別途確認しました。

