Go言語におけるポインタとは
ポインタはメモリ上のアドレスを表し、そのアドレスに格納された値に対して直接アクセスすることができる。
ポインタの基本をサンプルコードを交えて
func main() {
var num int = 10
var pointer *int
pointer = &num
fmt.Println("ポインタの値:", pointer)
fmt.Println("ポインタ経由の値:", *pointer)
*pointer = 20
fmt.Println("変更後の値:", num)
}
- 整数型のnumを定義
- 整数型ポインタ変数pointerを定義
- pointerにはnumのアドレス情報が格納されている
-
*pointer = 20
でpointer経由でnumの値を更新できる
※注意1
func main() {
var num int = 10
fmt.Println("ポインタの値:", *num)
}
これはビルド時にコンパイルエラーを吐く
=> invalid indirect of num (type int)
原因としては、numはポインタ変数として定義されていないため
※注意2
func main() {
var num *int
fmt.Println("ポインタの値:", *num)
}
これは実行時にコンパイルエラーを吐く
panic: runtime error: invalid memory address or nil pointer dereference
Go言語の参照渡しについてサンプルコードを交えて
Go言語では、参照渡しを用いて、関数内で変数の値を変更することができる。
package main
import "fmt"
func modifyValue(numPtr *int) {
*numPtr = 20
}
func main() {
num := 10
fmt.Println("変更前の値:", num)
modifyValue(&num)
fmt.Println("変更後の値:", num)
}
実行結果は以下の通り
変更前の値: 10
変更後の値: 20
modifyValue
という関数を定義している。
この関数は、ポインタを受け取り、そのポインタを経由して変数の値を変更することができる。
※注意
modifyValue
関数の引数をポインタではなく、通常の値渡しに変更すると、関数内での値の変更が呼び出し元の変数に反映されなくなる。
package main
import "fmt"
func modifyValue(num int) {
num = 20
}
func main() {
num := 10
fmt.Println("変更前の値:", num)
modifyValue(num)
fmt.Println("変更後の値:", num)
}
実行結果は以下
変更前の値: 10
変更後の値: 10
通常の値渡しでは、関数に引数として渡された値はコピーされて関数内で使用される。
ゆえに関数内での変更はコピーされた値に対して行われ、呼び出し元の変数自体には影響を与えない。
Go言語におけるメソッド定義の際も同様である
以下のサンプルコードを用いる
package main
import "fmt"
type Rectangle struct {
width float64
height float64
}
func (r *Rectangle) Scale(factor float64) {
r.width *= factor
r.height *= factor
}
func main() {
rect := Rectangle{width: 10, height: 5}
fmt.Println("変更前:", rect)
rect.Scale(2)
fmt.Println("変更後:", rect)
}
実行結果
変更前: {10 5}
変更後: {20 10}
-
Rectangle
構造体を定義 - ポインタが渡るScaleメソッドを定義
-
main
関数の中でRectangleのメソッドとして呼び出す
まとめ
Go言語のポインタを理解する上で理解しておくべきことをまとめた
参照