🦔

ポインタとは

2023/04/28に公開

ポインタとは

参考記事:https://qiita.com/Sekky0905/items/447efa04a95e3fec217f

→ポインタとは、メモリ上のアドレスを値として入れられる変数のこと

Go言語におけるポインタは、変数のアドレスを格納する特別な型です。

変数は、コンピュータメモリ上の特定の場所に割り当てられたスペースを表します。ポインタを使用すると、その変数のメモリアドレスを参照できます。これは、その変数の値を変更したり、関数にその変数への参照を渡したりするために非常に便利です。

Go言語では、ポインタは * を使って宣言されます。たとえば、以下は int 型のポインタを宣言する方法です。

var p *int

ポインタを使用すると、以下のように値を直接変更できます。

func main() {
    var x int = 10
    var p *int = &x
    *p = 20
    fmt.Println(x) // Output: 20
}

このコードでは、 x 変数のアドレスを & 演算子で取得し、 p に格納します。その後、ポインタを使用して x の値を直接変更しています。 fmt.Println 関数によって x の新しい値が出力されます。

また、ポインタを関数に渡すこともできます。関数内でポインタを使用すると、関数から出た後も変数の値が変更されます。

デリファレンス

& を使うことで、ポインタ型を生成することができる。

Person型の変数pを &p とすると、Personへのポインタである *Person型 の値を生み出すことができる。

&p は、pのアドレスという。

package main

import "fmt"

// Person は人間を表す構造体。
type Person struct {
    Name string
    Age  int
}

func main() {

    // 値として、pに代入
    p := Person{
        Name: "太郎",
        Age:  20,
    }

    fmt.Printf("最初のp :%+v\n", p)

    p2 := p
    p2.Name = "二郎"
    p2.Age = 21
    // pではなく
    fmt.Printf("p2で二郎に書き換えを行なったはずのp :%+v\n", p)

    // &pで*Person(Personのポインタ型)を生成する
    // p3はpのアドレスが格納されている状態になる
    p3 := &p
    p3.Name = "二郎"
    p3.Age = 21

    fmt.Printf("p3で二郎に書き換えを行なったp :%+v\n", p)
}

↓出力結果

最初のp :{Name:太郎 Age:20}
p2で二郎に書き換えを行なったはずのp :{Name:太郎 Age:20}
p3で二郎に書き換えを行なったp :{Name:二郎 Age:21}

pはポインタではなく、Person型の値である。

p2 := p は、Person型の値コピーしてp2に格納しているので、p2で書き換えを行っても、それがpに反映されることはない。これを値渡しという。

逆に、p3 := &p は、*Person型(Personへのポインタである *Person型)をp3に格納しているので、p3はpのアドレス(Personへのポインタである *Person型)を持っていることになる。

従って、p3で書き換えを行うと、その変更はpに反映される。これを参照渡しという。

Goでは、構造体内のメソッド内で、構造体のフィールドの情報を変更するときには、この参照渡しをよく利用する。

ポインタとは、大元のことと理解しました。

Discussion