目次
ポインタとは
値型であるデータ構造のメモリ上にあるアドレスと型の情報のことです。
もう少し噛み砕くと、ある変数が保存されているアドレス情報とその変数の型情報をポインタと言います。
Golangでのポインタの使い方
変数のアドレスを取得する
変数の先頭に「&」を付ける
//書式
&変数
//例
&number
ポインタ型の変数宣言
型の前に「*」を付けて、ポインタ変数にはアドレスを代入します。
//書式
var 変数名 *型 = &値
//例
var numberP *int = &number
ポインタ変数の値を取得する
*変数
//例
*numberP
具体的なコード例
package main
import (
"fmt"
)
func main() {
var number int = 10
fmt.Println(&number) //0xc0001e6230
var numberP *int = &number
fmt.Println(numberP) //0xc0001e6230
fmt.Println(*numberP) //10
}
つまり上記の例だと、以下のようになることがわかります。
&number => 0xc0001e6230(アドレス)
numberP => 0xc0001e6230(アドレス)
number => 10
*numberP => 10
ポインタを使わないと参照渡しができない
ポインタを使用しない場合
package main
import (
"fmt"
)
func DoubleNumber(number int) {
number = number * 2
}
func main() {
var number int = 10
DoubleNumber(number) //変数numberを2倍にする処理
fmt.Println(number) //10のまま変わらず..あれ?
}
ポインタを使わないと関数に渡した引数は、渡した引数そのものではなくコピーされた値が関数内で使用されます。
main関数内で定義した変数numberとDoubleNumber関数の中で使われる変数numberはまったく別の存在となるため、main関数内のnumberの値は変化しないままとなります。
ポインタを使用する場合
package main
import (
"fmt"
)
func DoubleNumber(number *int) {
*number = *number * 2
}
func main() {
var number int = 10
DoubleNumber(&number) //変数numberを2倍にする処理
fmt.Println(number) //20になる
}
ポインタを使うと変数numberのアドレスを参照しているため、main関数内で定義した変数numberにDoubleNumberの処理が適応されます。
Sliceは参照型であることに注意
Golangのスライスは元々参照型となっているため、そのままの変数を関数に渡すことができます。
package main
import (
"fmt"
)
func DoubleNumbers(numbers []int) {
for i, v := range numbers {
numbers[i] = v * 2
}
}
func main() {
var numbers []int = []int{10, 20, 30}
DoubleNumbers(numbers) //numbers内の値を全て2倍にする処理
fmt.Println(numbers) //20 40 60
}