LoginSignup
0
0

More than 3 years have passed since last update.

Go 言語仕様8(ポインタ)

Last updated at Posted at 2021-02-13

概要

Go 言語の仕様まとめ。

前回:
Go 言語仕様7(goroutine と channel)

内容

  • ポインタ

ポインタ

ポインタとは、変数のアドレスのこと。
アドレスとは、変数が格納されるメモリ上の区分のこと。
ポインタを使い、変数のアドレスを参照することで、元の変数の値を更新できる。

ポインタを使う上で出てくるのが、値型と参照型。
値型はアドレスを参照しないため、呼び出し先の関数で値の更新をしても、呼び出し元の変数は更新されない。

値型
func Plus(i int) {
    i = i + 10
    fmt.Println(i) // 20
}

func main() {
    var num int = 10
    fmt.Println(num) // 10

    Plus(num)

    // Plus関数の変数iとはアドレスが異なるため、Plus関数内の計算結果は変数numに反映されない
    fmt.Println(num) // 10
}

ポインタ型の変数(アドレスを格納できる変数)を参照渡ししてみる。

参照渡し
func Plus(i int) {
    i = i + 10
    fmt.Println(i) // 20
    fmt.Println(&i)
}

func main() {
    var num int = 10
    fmt.Println(num) // 10

    // numのアドレス
    fmt.Println(&num)

    Plus(num)

    // Plus関数の変数iとはアドレスが異なるため、Plus関数内の計算結果は変数numに反映されない
    fmt.Println(num) // 10

    // ポインタ型の宣言
    var p *int
    // ポインタ型の変数には、アドレスが代入できる
    p = &num
    fmt.Println(p)
    // アドレスを経由して元の変数の値を参照する
    fmt.Println(*p)

    // 変数pを更新すれば、アドレスを経由して元の変数numも更新される
    *p = 999
    fmt.Println(*p) // 999
    fmt.Println(num) // 999
}

変数pでは変数numのアドレスを持っているため、変数pと変数numのアドレスは同じ。
つまり、同じ変数の値を見ている。

変数 アドレス
num アドレスA 100
p アドレスA アドレスA

  

map, slice, channelなどは参照型に分類され、ポインタ型を使わないでも、デフォルトで参照渡しになる。

参照型
func Plus(s []int) {
    for i, v := range s {
        s[i] = v * 2
    }
}

func main() {
    sl := []int{10, 20, 30}
    Plus(sl)
    fmt.Println(sl) // [20 40 60]
}

次回

Go 言語仕様9(構造体)

0
0
0

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