📬

GO言語 関数でのポインタ利用

2023/05/12に公開

はじめに

はじめまして。新卒エンジニアです。
Go言語を学習する際に、関数でポインタを使用するのが複雑に感じたため、複数の例を活用してまとめてみます。

実行結果

package main

import "fmt"

func Add(x *int, y int) {
	*x += 10
	y += 10
	
	// 関数内でのx,y
	fmt.Printf("x : %d, y : %d\n", *x, y)
	//実行結果 x : 11, y : 11
	
	//関数内での適当な数x,yのアドレス
	fmt.Printf("xのアドレス : %p, yのアドレス : %p\n", x, &y)
	//実行結果 xのポインタ : 0xc0000180b8, yのポインタ : 0xc0000180e0
}

func main() {
	// 適当な数x,yを指定
	x := 1
	y := 1
	
	//適当な数x,yのアドレス
	fmt.Printf("xのアドレス : %p, yのアドレス : %p\n", &x, &y)
	//実行結果 xのポインタ : 0xc0000180b8, yのポインタ : 0xc0000180c0

	// 変更前
	fmt.Printf("x : %d, y : %d\n", x, y)
	//実行結果 x : 1, y : 1

	Add(&x, y)
	// 変更後
	fmt.Printf("x : %d, y : %d\n", x, y)
	//実行結果 x : 11, y : 1
}

解説

GO言語ではポインタというものが存在します。

ポインタとは

Go ではアドレスを格納するための変数が用意されています。これを ポインターといいます。
ポインターはデータ型毎に、 int32 型のポインターの型は *int32、 byte 型のポインター型は *byte という具合に、 型名に * を付ける形で宣言できます。

https://golang.keicode.com/basics/go-pointer.php#:~:text=といいます。-,Go のポインター,形で宣言できます。

ポインタを使用することによって、関数内での書き換えが可能になります。
実際の書き換える方法は上記のコードの通りで、ひとつづつ解説していきます。

まず今回の例では、main関数内で定義したx,yを別の関数である、Add関数内で足し算し、その結果をmain関数内にも反映させようとしました。
そして、ポインタの使用の有無での差を確認するために、xではポインタを用いて、yではポインタを用いず実行してみました。

その結果、Add関数内ではx,yともに+10されているものの、Add関数実行後のmain関数内では、xの値のみ+10されていました。

その理由として、xはAdd関数の引数としてポインタを与えているため、main関数内のxと同じアドレスになるのに対して、yは引数としてintを与えているため、main関数内のyと、Add関数内のyは全くの別物になっています。
その証明として、main関数内のyのアドレスと、Add関数内のyのアドレスが異なっています。

終わりに

今回は簡潔にポインタの関数利用について、記述させていただきましたが、今後さらに複雑なポインタの利用や、他のプログラミング言語でポインタを活用することがあると思うので、その都度調べまとめていきたいと思います。

参考

https://go.dev/tour/moretypes/1

株式会社アクティブコア

Discussion