Goのポインタの使い方について理解を深める

Go言語の問題を解いていてポインタの使い方で苦戦した。
深い理解を目指していろいろ調べた備忘録。

問題内容

次のプログラムは、自身を1つずつ加算するメソッドIncを実装したつもりですが、
実際にはうまく動きません。意図通りに動くように修正してください。
また、動かない理由も説明してください。

package main

type Int int

func (n Int) Inc() {
   n++
}

func main() {
   var n Int
   println(n) // 0
   n.Inc()
   println(n) // 0
}

メソッドの中で+1してるのに、println(n)で0のままになってしまうという状態。

ポインタを使って、メソッド内の変数を参照する

package main

type Int int
// グローバルなデータ型であるintではメソッドを定義することができない(Goの仕様)
// int型のIntをエイリアスとして定義

func (a *Int) Inc() {
    // *Intでポインタを宣言することで,main()関数の中のInt型の変数nが
    // Inc()メソッドの中のInt型の変数aを参照することができる。

    println(a)  // 0x1042ffa0 -(1)
    println(&a) // 0x1042ffa4 -(2)
    // この時点で、aにnのアドレスが渡されている

    *a++
    // *をaに付与することで、main()のnが参照している値(a)を呼び出すことができる
}

func main() {
    var n Int
    println(n) // 0
    n.Inc()    // nの値が、参照先であるaが持つ値(1)に書き換わる
    println(n) // 1
}

メソッドには返り値がないため、メソッド内の変数にポインタを定義して
main()側から参照できる形にする必要がある。
アドレス演算子の有無でアドレスの出力変わるのは、なぜだろう...??

ポインタを使わずに書いた場合

返り値のデータ型を定義して、returnさせてみた。

package main

type Int int

func (a Int) Inc() Int {
    a++
    return a
}

func main() {
    var n Int
    println(n) // 0
    var b = n.Inc()
    println(b) // 1
}
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.