LoginSignup
1
0

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-05-03

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
}
1
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
1
0