🐙

[Go] ポインタの使い方を忘れるのでまとめる

2022/09/24に公開

What`s This

ポインタ、構造体、new(),make()がわからなすぎるのでまとめた。

dereferenceとは

ポインタ型が保持するメモリ上のアドレスを経由して、データ本体を参照するための仕組み。

new()を使う宣言と、使わない宣言の違い

# 値を何も入れない状態で、メモリーにポインタが入る領域を確保したい場合
# →new()を使う
var p *int = new(int)
fmt.Println(p)

new()を使わない宣言

// nilが帰ってくる。
// pを宣言してはいるが、まだメモリに格納していないから。
var p *int
fmt.Println(p)

<nil>
// この状態で、pに値を入れようとすると、エラーになる。
// pをデリファレンスして、増分する。
var p *int
fmt.Println(p)
*p++
fmt.Println(p)

<nil>
panic: runtime error: invalid memory address or nil pointer dereference

new()を使う宣言

// new()によって、メモリの領域を確保しているから、アドレスが返ってくる。
// 値はまだ入っていない。
var p *int = new(int)
fmt.Println(p)

0xc000016078
// デフォルトの値を確認すると、0が返ってくる。
var p *int = new(int)
fmt.Println(*p)

0

// データ本体を参照(dereference)して、増分
var p *int = new(int)
fmt.Println(*p)
*p++
fmt.Println(*p)

0
1

new(),make()の使い所について

ポインタが帰ってくる返り値のものについては、new()を使用して、そうでない場合にはmake()を使用する。
Typeで確認する。

a := make([]int, 0)
fmt.Printf("%T\n", a)

b := make(map[string]int)
fmt.Printf("%T\n", b)

var c *int = new(int)
fmt.Printf("%T\n", c)

[]int
map[string]int
*int

Discussion