Golangのポインタのアンパサンド(&) とアスタリスク(*)の使い方を整理する

thumnail
2019-05-31

&と*の使い方に不安&と*という記号・構文をよく見かける。ポインタを扱う記号で、何となく使い方もわかってはいるのだが、実際、雰囲気で理解している感が否めないのでしっかり言語化してこの記事にまとめておくことにした。

&(アンパサンド)

変数の値のポインタを抽出するための構文

&(アンパサンド)は変数の値のポインタを抽出するために使う構文だ。

var x int64 = 3
fmt.Println(x)  // 3
fmt.Println(&x) // 0xc000094000

xはint64型の値だ。この値のポインタを取り出したいときに&を使えばよい。もちろんポインタ自体も他の変数に代入可能だ。

    var x int64 = 3
    fmt.Println(x)  // 3
    fmt.Println(&x) // 0xc000094000
    y := &x
    fmt.Println(y) // 0xc00008e000

確保されるメモリを観察してみる

ポインタをみるとメモリの確保のされ方を理解することができる。次のコードを見て欲しい。

    var x int64 = 3
    var y int64 = 3
    fmt.Println(&x) // 0xc0000160c0
    fmt.Println(&y) // 0xc0000160c8

x, yの2つのint64型の変数を定義した。これは64bit (8byte)のメモリを確保したことになり、それぞれ、8byte分の領域を確保して並んでいることがわかる。ちなみにポインタは確保した領域の先頭のアドレスを指す。

*(アスタリスク)

ポインタから変数の値を抽出する構文

アスタリスク(*)はポインタから変数の値を抽出する構文だ。次のコードを見て欲しい。

    var x int64 = 3
    y := &x
    fmt.Println(y) // 0xc000094000
    fmt.Println(*y) // 3

xのポインタをyに代入する。yはポインタ型なので*(アスタリスク)を使って値を抽出することができている。

ポインタ型であることを明示

アスタリスク(*)は関数の引数をポインタ型を指定するときに使用する。

    func square(i *int64) {
        *i = *i * *i
    }

square関数はint64のポインタ型を引数として取る。適当にこの関数を使ってみる。

    func main() {
        var x int64 = 3
        fmt.Println(x) // 3
        square(&x)
        fmt.Println(x) // 9
    }
    
    func square(i *int64) {
        *i = *i * *i
    }

squareにはint64のポインタ型を渡さないといけないので&を付与してポインタを抽出している。xの値はsquare関数によって値が書き換えられていることが確認できる。

profile

KATUO

web developer

六本木で月間利用者数数千万のサービスを運営するミドルベンチャーでWeb系エンジニアをやってます。フロントエンドはVue.js/Nuxt.js,サーバーサイドはGolang, クラウドはAWS, GCPを良く扱います。お仕事・イベント等の依頼はContactのフォームからお願いします。

KATUBLO

Copyright since 2018 KATUO All Rights Reserved.