ポインタ(&と*)・newとmake【夏休みにGo vol.18】

こんにちは、しーたです。
今日はポインタとnewについて学んでいます。

ポインタ(&と*)

"&"はその変数の値が入っているアドレスを指します。
"*"はそのアドレスに入っている値を指します。

以下のように確認できます。

func main() {
	var n int = 100
	fmt.Println(n)

	fmt.Println(&n) //アドレス

	var p *int = &n //アドレスを値として代入
	fmt.Println(p)
	fmt.Println(*p) //pの値として入っているアドレスにある、変数に入っている値を返す
}

画像1


また、関数内で変数の値を更新する際は、「ポインタを用いてアドレスを渡す」必要があります

func one(x int) {
	x = 1 //渡された値を持つ「別の変数」を作り、その値を更新する。
}

func one2(x *int) {
	*x = 1 //渡されたアドレスの中にある値を更新する。
}

func main() {
	var n int = 100
	one(n) //値だけを渡しているので、nは100のまま。
	fmt.Println(n)

	one2(&n) //アドレスを渡しているので、nは1に上書きされる。
	fmt.Println(n)
}

画像2


newとmake

newはmake同様、メモリを確保する際に用います。
普通の宣言に比べ、値を入れなくてもメモリが確保されています

func main() {
	var p *int = new(int) //メモリが事前に確保される。
	fmt.Println(p)

	var p2 *int //値が入るまでメモリが確保されない。
	fmt.Println(p2)
}

画像3


配列の時に出てきたmakeとの基本的な違いは、
make -> ポインタを使わない型に使う。(つまりslice, map, channelのみ)
new -> ポインタを含む型に使う。
です。

【vol.8 配列・スライス・make, cap, len】
https://note.com/theta04/n/nbc226b192bd3

func main() {
	s := make([]int, 0) //ポインタではない型にはmakeを使う
	fmt.Printf("%T\n", s)

	m := make(map[string]int) //ポインタではない型にはmakeを使う
	fmt.Printf("%T\n", m)

	var p *int = new(int)
	fmt.Printf("%T\n", p) //ポインタの型にはnewを使う
}

画像4

初期化の有無など、より細かな違いは下記URLで解説されています。
"https://cipepser.hatenablog.com/entry/go-new-make"
※現時点の私には少し難しかったので大まかな説明のみにしています。
また分かれば詳しく書くかもしれません。


以上です。それでは!

この記事が気に入ったらサポートをしてみませんか?