ホームページ >バックエンド開発 >Golang >値レシーバーとポインター レシーバーを使用する場合、Go の構造体セッター メソッドの動作が異なるのはなぜですか?

値レシーバーとポインター レシーバーを使用する場合、Go の構造体セッター メソッドの動作が異なるのはなぜですか?

Linda Hamilton
Linda Hamiltonオリジナル
2024-12-24 20:08:17139ブラウズ

Why Do Go's Struct Setter Methods Behave Differently When Using Value vs. Pointer Receivers?

構造体型のセッター メソッドを理解する

Go の構造体型は、関連データをグループ化する便利な方法を提供し、セッター メソッドを使用すると、彼らの特性。ただし、特定のシナリオでは予期しない動作が発生する可能性があります。

問題の説明:

フィールド Val と 2 つのセッター関数 SetVal と SetVal2 を持つ構造体 T を考えてみましょう。 SetVal を使用すると元の構造体は変更されませんが、SetVal2 は変更します。この矛盾を理解することが重要です。

基礎となるメカニズム:

構造体を関数に渡す場合、2 つのアプローチが可能です:

  • 値による受け渡し: 構造体のコピーを作成します。関数内で行われた変更はコピーにのみ影響します。
  • 参照による受け渡し (ポインター): 元の構造体へのポインターを提供し、変更を永続化できます。

推論:

SetVal は構造体を値パラメータ。したがって、構造体のコピーが関数内に作成され、t (コピー) への変更は元の v には影響しません。

問題の解決:

SetVal2 でポインタ レシーバ アプローチを使用して、変更が元のファイルに確実に反映されるようにします。 struct:

func (t *T) SetVal(s string) {
    t.Val = s
}

検証:

違いを示すために print ステートメントを追加:

type T struct { Val string }

func (t T) SetVal(s string) {
    fmt.Printf("Address of copy is %p\n", &t)
}

func (t *T) SetVal2(s string) {
    fmt.Printf("Pointer argument is %p\n", t)
}

func main() {
    v := T{"abc"}
    fmt.Printf("Address of v is %p\n", &v)
    v.SetVal("pdq")
    v.SetVal2("xyz")
}

このプログラムの出力:

Address of v is 0xf8400cfc00
Address of copy is 0xf8400cfcd0
Pointer argument is 0xf8400cfc00

v のアドレスと SetVal2 のポインターは等しいため、次の使用法が確認されます。 SetVal はコピーに対して機能します。

以上が値レシーバーとポインター レシーバーを使用する場合、Go の構造体セッター メソッドの動作が異なるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。