0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Go言語のポインタについて理解する

Last updated at Posted at 2023-05-24

Go言語におけるポインタとは

ポインタはメモリ上のアドレスを表し、そのアドレスに格納された値に対して直接アクセスすることができる。

ポインタの基本をサンプルコードを交えて

func main() {
    var num int = 10

    var pointer *int

    pointer = &num

    fmt.Println("ポインタの値:", pointer)

    fmt.Println("ポインタ経由の値:", *pointer)

    *pointer = 20

    fmt.Println("変更後の値:", num)
}
  1. 整数型のnumを定義
  2. 整数型ポインタ変数pointerを定義
  3. pointerにはnumのアドレス情報が格納されている
  4. *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}
  1. Rectangle構造体を定義
  2. ポインタが渡るScaleメソッドを定義
  3. main関数の中でRectangleのメソッドとして呼び出す

まとめ

Go言語のポインタを理解する上で理解しておくべきことをまとめた

参照

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?