1. ホーム

[解決済み】Swiftの配列の代入が矛盾している(参照でも深層コピーでもない)理由はあるのか?)

2022-04-18 10:58:29

質問

ドキュメントを読んでいて、この言語の設計上の決定事項のいくつかに、いつも首をかしげています。 しかし、私が本当に困惑したのは、配列がどのように扱われるかです。

慌てて遊び場に行って、これらを試してみました。 あなたも試してみてください。 では、最初の例です。

var a = [1, 2, 3]
var b = a
a[1] = 42
a
b

ここで ab はいずれも [1, 42, 3] を受け入れることができます。 配列が参照される - OK!

では、この例をご覧ください。

var c = [1, 2, 3]
var d = c
c.append(42)
c
d

c[1, 2, 3, 42] BUT d[1, 2, 3] . ということです。 d は、前回の例ではその変更を確認しましたが、今回の例では確認できません。 ドキュメントによると、それは長さが変わったからだそうです。

さて、こちらはどうでしょう。

var e = [1, 2, 3]
var f = e
e[0..2] = [4, 5]
e
f

e[4, 5, 3] は、かっこいいですね。 複数インデックスの置き換えができるのはいいことですが f 長さが変わっていないにもかかわらず、STILLは変化を見ません。

つまり、まとめると、配列の共通参照は、1つの要素を変更すれば変化を見るが、複数の要素を変更したり、項目を追加したりすると、コピーが作成されるのです。

これはとてもお粗末な設計のように思えます。 私がそう考えるのは正しいのでしょうか? 配列がこのように動作しなければならない理由が私にはわからないのですが、何か理由があるのでしょうか?

EDIT : 配列が変更され、値のセマンティクスを持つようになりました。 よりまともになりました。

解決するには?

注意点 配列のセマンティクスとシンタックスは、Xcodeベータ3バージョンで変更されました。 ( ブログ記事 )であるため、この質問はもはや適用されません。以下の回答は、ベータ2に適用されました。


それは、パフォーマンスのためです。基本的に、彼らはできる限り配列のコピーを避けようとしています(そして、"Cのようなパフォーマンス"を主張しています)。その言語を引用すると 書籍 :

配列の場合は、配列の長さを変更する可能性のある操作を行ったときのみコピーが行われます。これには、項目の追加、挿入、削除、または範囲指定添え字を使用して配列の項目範囲を置き換えることが含まれます。

少し分かりにくいというのは同意しますが、少なくとも、どのように機能するかについて、明確でシンプルな説明があります。

そのセクションには、アレイを一意に参照する方法、アレイを強制コピーする方法、2つのアレイがストレージを共有しているかどうかを確認する方法などの情報も含まれています。