Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

ポインタ

ポインタは変数のメモリアドレスを格納する型です。Goではポインタを使って関数から変数の値を変更したり、大きなデータのコピーを避けたりできます。

構文
// ポインタ型の宣言
var p *int           // intへのポインタ(ゼロ値はnil)

// アドレス演算子 & で変数のアドレスを取得
x := 42
p = &x              // p に x のアドレスを代入

// 間接参照演算子 * で値を取得・変更
fmt.Println(*p)      // 42(xの値)
*p = 100             // x の値を 100 に変更

// new() で新しい変数をヒープに確保
p2 := new(int)       // *int 型、値は 0
*p2 = 55
構文一覧
演算子/関数概要
&変数変数のメモリアドレスを取得します。戻り値はポインタ型(*T)です。
*ポインタポインタが指す値を取得(または変更)します。デリファレンスとも呼びます。
*型ポインタ型の宣言に使います。例: 『var p *int』
new(型)指定した型のゼロ値をヒープに確保し、そのポインタを返します。
nilポインタのゼロ値です。アドレスが設定されていない状態を表します。
サンプルコード
package main

import "fmt"

// ポインタを使って呼び出し元の値を変更する関数
func double(n *int) {
	*n = *n * 2
}

// 値渡し(コピーされるので元の値は変わらない)
func doubleCopy(n int) {
	n = n * 2
}

func main() {
	x := 10

	// 値渡し
	doubleCopy(x)
	fmt.Println(x) // 10(変わらない)

	// ポインタ渡し
	double(&x)
	fmt.Println(x) // 20(変わった!)

	// ポインタの基本操作
	p := &x
	fmt.Printf("アドレス: %p\n", p)  // メモリアドレスを表示
	fmt.Printf("値: %d\n", *p)       // 20

	// new() の使用
	p2 := new(int)
	*p2 = 99
	fmt.Println(*p2) // 99

	// nil チェック
	var p3 *int
	if p3 == nil {
		fmt.Println("p3 は nil です")
	}
}
概要

Goのポインタは安全に設計されており、CやC++とは異なりポインタ演算(アドレスの加減算)はできません。関数に大きな構造体を渡すときはポインタを使うことでコピーのコストを省けます。

nilポインタに対して間接参照(『*p』)を行うとpanicが発生します。ポインタを使う前に必ずnilチェックを行うか、初期化済みであることを確認してください。

構造体メソッドのレシーバでポインタを使うケースが多く、Goのコードではよく登場するパターンです。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。