Swift と mutating struct 質問する

Swift と mutating struct 質問する

Swift で値型を変更する場合、完全に理解できないことがあります。

「The Swift Programming Language」iBook には次のように書かれています:デフォルトでは、値型のプロパティはインスタンス メソッド内から変更できません。

これを可能にするには、mutating構造体と列挙型内でキーワードを使用してメソッドを宣言します。

私にとって完全に明確ではないのは、構造体の外部から var を変更できるが、構造体自体のメソッドからは変更できないということです。これは直感に反しているように思えます。オブジェクト指向言語では、通常、変数をカプセル化して内部からのみ変更できるようにします。構造体の場合は、逆のようです。詳しく説明すると、次のコード スニペットになります。

struct Point {
    var x = 0, y = 0
    mutating func moveToX(x: Int, andY y:Int) { //Needs to be a mutating method in order to work
        self.x = x
        self.y = y
    }
}

var p = Point(x: 1, y: 2)
p.x = 3 //Works from outside the struct!
p.moveToX(5, andY: 5) 

構造体は他の場所では簡単に内容を変更できるのに、構造体自身のコンテキスト内から内容を変更できない理由を知っている人はいますか?

ベストアンサー1

可変属性は、型ではなくストレージ (定数または変数) にマークされます。構造体には 2 つのモードがあると考えることができます。可変そして不変構造体の値を不変ストレージ(letまたは絶え間ないSwift では、値は不変モードになり、値の状態を変更することはできません。(変更メソッドの呼び出しを含む)

値が可変ストレージ(varまたは変数Swift では、状態を自由に変更でき、変更メソッドの呼び出しが許可されます。

さらに、クラスにはこの不変/可変モードがありません。私の意見では、これはクラスが通常、参照可能なエンティティ。また、参照可能なエンティティは通常は可変です。適切なパフォーマンスを維持しながら、エンティティの参照グラフを不変な方法で作成および管理するのは非常に難しいためです。この機能は後で追加される可能性がありますが、少なくとも現時点では追加されません。

Objective-C プログラマーにとって、可変/不変の概念は非常に馴染み深いものです。Objective-C では、各概念に対して 2 つの別々のクラスがありましたが、Swift では 1 つの構造体でこれを行うことができます。作業の半分です。

C/C++ プログラマーにとって、これも非常に馴染みのある概念です。これはまさにconstC/C++ のキーワードが行うことです。

また、不変値は非常にうまく最適化できます。理論的には、Swift コンパイラ (または LLVM) は、C++ と同様に、渡される値のコピー省略を実行できますlet。不変構造体を賢く使用すると、参照カウント クラスよりも優れたパフォーマンスを発揮します。

アップデート

@Josephが主張したように、これはなぜ、もう少し追加します。

構造体には 2 種類のメソッドがあります。無地そして変異する方法。無地方法は意味する不変(または非変化)この分離はサポートのためだけに存在します不変セマンティクス。不変モードのオブジェクトは状態をまったく変更しません。

そして、不変メソッドはこれを保証する必要がある意味的不変性つまり、内部の値は変更すべきではありません。そのため、コンパイラは不変メソッド内で自身の状態変更を許可しません。対照的に、変更メソッドは状態を自由に変更できます。

そして、あなたは疑問に思うかもしれませんなぜ不変がデフォルトなのでしょうか?なぜなら、変化する値の将来の状態を予測するのは非常に難しく、それが頭痛の種やバグの主な原因となるからです。多くの人が、解決策は可変のものを避けることだと同意しました。デフォルトでは変更不可C/C++ ファミリー言語とその派生言語では、何十年もの間、希望リストのトップにありました。

見る純粋に機能的なスタイル詳細については、こちらをご覧ください。いずれにせよ、不変のものにはいくつかの弱点があり、それについて議論するのは話題から外れているように思われるため、可変のものはまだ必要です。

おすすめ記事