構造体フィールドへの新しい値の代入
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 サイトの他の関連記事を参照してください。