Go でのプログラミングの世界を詳しく調べると、特に次のような場合にポインター逆参照に関連する興味深い動作に遭遇することがあります。構造体を使った作業。次の例を考えてみましょう:
package main import "fmt" type Vertex struct { X, Y int } var ( p = Vertex{1, 2} // has type Vertex q = &Vertex{1, 2} // has type *Vertex r = Vertex{X: 1} // Y:0 is implicit s = Vertex{} // X:0 and Y:0 ) func main() { t := *q q.X = 4 u := *q fmt.Println(p, q, r, s, t, u, t == u) }
このコードを実行すると、驚くべき結果が生成されます:
{1 2} &{4 2} {1 0} {0 0} {1 2} {4 2} false
q.X を変更した後、t が {4, 2} に変更されると予想されるかもしれませんが、これは変更されません。起こる。この動作の理由は何ですか?
これを理解するための鍵は、ポインターの逆参照です。 Go では、ポインター (*q など) を逆参照すると、それが指す値のコピーが作成されます。したがって、 t := *q は、q によって参照される Vertex struct の別のコピーを作成します。
例 28 の変更を明確にしました:
変更した例では、次のように設定すると、 q.X = 4 の場合、q が指す構造体のみを変更します。 t はコピーであるため、元の値が保持されます。
C/C の観点から見ると奇妙に見える動作について言及しました。ただし、C/C も同様に動作します。次の例を考えてみましょう:
#include <iostream> struct Vertex { int x; int y; }; int main() { Vertex v = Vertex{1, 2}; Vertex* q = &v; Vertex t = *q; q->x = 4; std::cout << "*q: " << *q << "\n"; std::cout << " t: " << t << "\n"; }
この C コードは同じ動作を生成します:
*q: { 4, 2 } t: { 1, 2 }
要約すると、Go でポインタを逆参照すると、次のようになります。基になる値のコピーを作成しています。ポインターを介して加えられた変更を監視するには、次の変更例のようにポインター自体を使用する必要があります。
func main() { t := q q.X = 4 u := *q fmt.Println(p, q, r, s, t, u, *t == u) }
これにより、期待される出力 {1 2} &{4 2} {1 0} が生成されます。 {0 0} {4 2} {4 2} true。
以上がGo でポインターを逆参照しても元の値が変更されないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。