スキップしてメイン コンテンツに移動

Goポインタ入門:値渡しとnil

Goポインタ入門:値渡しとnil

ポインタの基本

Go初心者が最初に直面する概念の一つがポインタです。ポインタは変数のアドレスを保持する型で、*で宣言します。例えば var p *int は整数型のポインタを作ります。

ポインタを使うと、関数に渡す際に値渡しではなく参照渡しが可能になります。これにより、関数内で変更した値が呼び出し元にも反映されます。

アドレスとデリファレンス

ポインタ変数に格納されるのはアドレスです。アドレスを取得するには & を使います。例: x := 10; p := &xpx のアドレスを指します。

逆に、ポインタが指す値を取り出す操作をデリファレンスと言い、*p で行います。以下は典型的なコード例です。

package main
import "fmt"

func main() {
    x := 42
    p := &x
    fmt.Println(*p) // 42
    *p = 100
    fmt.Println(x) // 100
}

nilとメモリ管理

ポインタが何も指していない状態は nil です。var p *int = nil のように宣言できます。nilポインタにデリファレンスするとランタイムエラーが発生します。

Goはガベージコレクションを備えているため、メモリ管理は自動です。ただし、nilチェックを怠るとパニックになるので注意が必要です。

値渡しと参照の違い

Goでは関数に引数を渡すとき、デフォルトは値渡しです。構造体やスライスはコピーされますが、スライスは内部でポインタを持つため、実質的に参照渡しに近い挙動をします。

ポインタを引数に渡すと、関数内でポインタが指すメモリ領域を直接操作できます。これにより、関数呼び出し後も変更が残ります。以下は比較例です。

func inc(v int) { v++ }
func incPtr(v *int) { *v++ }

func main() {
    a := 5
    inc(a)
    fmt.Println(a) // 5

    incPtr(&a)
    fmt.Println(a) // 6
}

この記事はAIによって作成されました。

コメント