go tourでわからなかったことのメモです
package main import "fmt" type Vertex struct { X, Y int } var ( v1 = Vertex{1, 2} // has type Vertex v2 = Vertex{X: 1} // Y:0 is implicit v3 = Vertex{} // X:0 and Y:0 p = &Vertex{1, 2} // has type *Vertex ) func main() { fmt.Println(v1, p, v2, v3) }
なんとなくは理解できたのですがわからないので調べた。
&Vertex{1, 2}
の部分について
この部分はGo言語におけるポインタの使用に関するものです。具体的には、&Vertex{1, 2}
は Vertex
構造体のインスタンスを作成し、そのポインタを返します。
以下に詳細を説明します:
Vertex構造体
まず、Vertex
構造体は以下のように定義されています:
type Vertex struct { X, Y int }
構造体の初期化
Vertex
構造体のインスタンスを作成するには以下のようにします:
v := Vertex{1, 2}
これは、X
フィールドに 1
、Y
フィールドに 2
を持つ Vertex
構造体のインスタンスを作成します。
ポインタの取得
ここで、&
演算子を使うことで、Vertex
構造体のインスタンスのポインタを取得できます:
p := &Vertex{1, 2}
このコードは、Vertex
構造体のインスタンスを作成し、そのメモリ上のアドレス(ポインタ)を変数 p
に格納します。p
の型は *Vertex
となります。
ポインタの利用
ポインタを使うことで、構造体のフィールドに対して間接的にアクセスすることができます。例えば:
p := &Vertex{1, 2} fmt.Println(p.X, p.Y) // 1 2 と表示される
ここで、p.X
や p.Y
にアクセスすることで、ポインタを経由して Vertex
構造体のフィールドにアクセスしています。
プログラムの動作
質問にあるプログラムの main
関数では、以下のようにしています:
func main() {
fmt.Println(v1, v2, v3)
fmt.Println(p)
}
v1
,v2
,v3
はそれぞれ異なる方法で初期化されたVertex
構造体のインスタンスです。p
はVertex
構造体のポインタです。
このプログラムを実行すると、構造体インスタンスの内容とポインタが表示されます:
{1 2} {1 0} {0 0} &{1 2}
最初の Println
では v1
, v2
, v3
の値が表示され、次の Println
ではポインタ p
が指す Vertex
構造体の内容が表示されます(ポインタであることを示す &
が付いています)。
間接的に操作する例
以下の例では、Vertex
構造体のフィールドをポインタを通じて変更する方法を示しています。
package main import "fmt" type Vertex struct { X, Y int } // 関数 updateVertex でポインタを受け取り、フィールドを更新します func updateVertex(v *Vertex, newX int, newY int) { v.X = newX v.Y = newY } func main() { // Vertex構造体のポインタを作成 p := &Vertex{1, 2} // 初期値を表示 fmt.Println("Before update:", *p) // ポインタを使って構造体のフィールドを更新 updateVertex(p, 10, 20) // 更新後の値を表示 fmt.Println("After update:", *p) }
このプログラムの出力は以下のようになります:
Before update: {1 2} After update: {10 20}
説明
構造体のポインタを作成:
go p := &Vertex{1, 2}
これは、X
が1
、Y
が2
であるVertex
構造体のポインタを作成します。初期値を表示:
go fmt.Println("Before update:", *p)
*p
を使うことでポインタp
が指す構造体の値を取得し、初期値{1 2}
が表示されます。関数
updateVertex
でフィールドを更新:go updateVertex(p, 10, 20)
この関数は、ポインタp
を受け取り、X
フィールドを10
に、Y
フィールドを20
に更新します。更新後の値を表示:
go fmt.Println("After update:", *p)
再び*p
を使って更新後の構造体の値を表示します。この時点で、X
が10
、Y
が20
になっています。
このように、ポインタを使うことで構造体のフィールドを間接的に操作できます。 ポインタを関数に渡すことで、関数内で構造体の内容を変更できる点が重要です。