【Golang】ポインタの使い方と参照渡しを詳しく解説します

ポインタとは

値型であるデータ構造のメモリ上にあるアドレスと型の情報のことです。

もう少し噛み砕くと、ある変数が保存されているアドレス情報とその変数の型情報をポインタと言います。

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関数内で定義した変数numberDoubleNumber関数の中で使われる変数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
}

タイトルとURLをコピーしました