ホームページ >バックエンド開発 >Golang >値レシーバー メソッドの Go 構造体フィールドを変更しても元の値が変更されないのはなぜですか?

値レシーバー メソッドの Go 構造体フィールドを変更しても元の値が変更されないのはなぜですか?

DDD
DDDオリジナル
2024-12-15 17:16:18118ブラウズ

Why Doesn't Modifying a Go Struct Field in a Value Receiver Method Change the Original Value?

構造体フィールドへの新しい値の代入

Go で構造体を扱うときは、値の受信側と値の受信側の概念を理解することが重要です。ポインタ受信機。値レシーバーは元の値のコピーを操作しますが、ポインター レシーバーは元の値を直接操作します。

次のコード スニペットを考えてみましょう。ここでは、予期せず変更されなかった構造体フィールド値について疑問が生じています。

type Point struct {
  x, dx int
}

func (s Point) Move() {
  s.x += s.dx
  log.Printf("New X=%d", s.x)
}

func (s Point) Print() {
  log.Printf("Final X=%d", s.x)
}

func main() {
  st := Point{ 3, 2 };
  st.Move()
  st.Print()
}

Move() メソッドが Point 構造体の x フィールドを変更することが期待されており、これは Print() メソッドに反映される必要があります。ただし、出力には、x フィールドが変更されていないことが示されています。

解決策: ポインター レシーバーの使用

問題は、Move( での値レシーバーの使用にあります) ) メソッドと Print() メソッド。 Go では、すべてが値によって渡されます。つまり、構造体を関数に渡すときに、元の値のコピーが作成されます。したがって、関数内でコピーに加えられた変更は、元の値には影響しません。

これを解決するには、ポインター レシーバーを使用する必要があります。ポインタ レシーバを使用すると、関数が元の値に対して直接操作できるようになります。修正されたコードは次のとおりです。

type Point struct {
  x, dx int
}

func (s *Point) Move() {
  s.x += s.dx
  log.Printf("New X=%d", s.x)
}

func (s *Point) Print() {
  log.Printf("Final X=%d", s.x)
}

func main() {
  st := Point{ 3, 2 };
  st.Move()
  st.Print()
}

Move() メソッドと Print() メソッドのポインター レシーバーを使用することで、元の Point 構造体を直接操作できるようになり、x フィールドへの変更が正しく反映されます。 .

以上が値レシーバー メソッドの Go 構造体フィールドを変更しても元の値が変更されないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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