概要
Go 言語の仕様まとめ。
前回:
Go 言語仕様7(goroutine と channel)
内容
- ポインタ
ポインタ
ポインタとは、変数のアドレスのこと。
アドレスとは、変数が格納されるメモリ上の区分のこと。
ポインタを使い、変数のアドレスを参照することで、元の変数の値を更新できる。
ポインタを使う上で出てくるのが、値型と参照型。
値型はアドレスを参照しないため、呼び出し先の関数で値の更新をしても、呼び出し元の変数は更新されない。
値型
func Plus(i int) {
i = i + 10
fmt.Println(i) // 20
}
func main() {
var num int = 10
fmt.Println(num) // 10
Plus(num)
// Plus関数の変数iとはアドレスが異なるため、Plus関数内の計算結果は変数numに反映されない
fmt.Println(num) // 10
}
ポインタ型の変数(アドレスを格納できる変数)を参照渡ししてみる。
参照渡し
func Plus(i int) {
i = i + 10
fmt.Println(i) // 20
fmt.Println(&i)
}
func main() {
var num int = 10
fmt.Println(num) // 10
// numのアドレス
fmt.Println(&num)
Plus(num)
// Plus関数の変数iとはアドレスが異なるため、Plus関数内の計算結果は変数numに反映されない
fmt.Println(num) // 10
// ポインタ型の宣言
var p *int
// ポインタ型の変数には、アドレスが代入できる
p = &num
fmt.Println(p)
// アドレスを経由して元の変数の値を参照する
fmt.Println(*p)
// 変数pを更新すれば、アドレスを経由して元の変数numも更新される
*p = 999
fmt.Println(*p) // 999
fmt.Println(num) // 999
}
変数pでは変数numのアドレスを持っているため、変数pと変数numのアドレスは同じ。
つまり、同じ変数の値を見ている。
変数 | アドレス | 値 |
---|---|---|
num | アドレスA | 100 |
p | アドレスA | アドレスA |
map, slice, channelなどは参照型に分類され、ポインタ型を使わないでも、デフォルトで参照渡しになる。
参照型
func Plus(s []int) {
for i, v := range s {
s[i] = v * 2
}
}
func main() {
sl := []int{10, 20, 30}
Plus(sl)
fmt.Println(sl) // [20 40 60]
}