質問: p1 //p1 and p2 point to the same data internally p1.scale(2) //copy on mutate, p1 and p2 now have distinct copies 今私は、構造体のさまざまなコピーが、突然変異がコピーを強制するまで、実際にはスタック上の同じデータを指すと信じています。つまり、突然変異がコピーを形成する必要があるかどうかを知るために、スタック上の特定のメモリアドレスを参照するオブジェクトの数を追跡する必要があるか、単純にすべての突然変異にコピーを形成する必要があります。前者は非効率的で、後者はarcと同じようです。何が欠けていますか?編集:私は値のセマンティクスと参照のセマンティクスの違いを理解しています。しかし、最適化としてswiftは、変更が行われるまで、実際にはデータの新しいコピーを作成しません。これにより、不要なコピーが回避されます。参照 https://www.hackingwithswift.com/ example-code/language/what-is-copy-on-write ですが、これが原因で、何らかの形式のarcを回避できるかどうかはわかりません。この記事では、書き込み時のコピーは配列と辞書それが真実かどうかはわかりませんが、もしそうだとしても、私の質問はまだ配列についてです。
回答: swift構造体は、そのデータが一意に参照されているかどうかを知るだけでよく、本格的なarcを必要としません。たとえば、次の行でvar p2 = p1 コンパイラーは理論的には、p1の一意に参照されるフラグをオフからオンに切り替えるだけです。次に、書き込みが行われると、コンパイラはコピーすることを認識します。これが発生する前にp2の割り当てが解除されたとします。現在、コピーは冗長ですが、コンパイラーは知らないので、それでもコピーを作成します。これが、一意に参照されるアプローチが完全な近似ではない理由です。実際には、完全なarcと常にコピーすることの間にあります。注:swiftコンパイラは実際にはこのように機能しません。@ alexanderのコメントと this answer に基づいて、コピーオンライト動作はswiftコードで実装されます。コンパイラの最適化。ユーザー定義の構造体では、毎回コピーするだけです。効率についてのあなたの要点については、はい、技術的に毎回コピーすることは効率が良くありません。コピーと変更の動作がたくさんある場合、ある時点で、クラスに切り替えるだけでより効率的になります。そのため、swiftには両方のオプションがあります。