LoginSignup
0
0

More than 5 years have passed since last update.

Golangのポインタにあれこれ

Last updated at Posted at 2018-04-11

どうも, @nomurakkoooです.
今回はGoを触っていてポインタについて少し調べたので書きます.
初心者レベルです. よろしくどうぞ

ポインタとは

GoとかCとかでよく見る*とか&.
変数のアドレスを参照して値を取得したり, 更新したりするやつという認識です.
間違えていたら優しく教えてください.

*&ってなに

簡単にいうと*は変数に対するアドレスの中身の参照で&は変数のアドレスヘのアクセスです.

&の方はしっくり来る例えがパッと思い浮かびませんでした.
こんなのあるよとかこっちの方が良くない?とかあったら是非教えてください.

簡単な例を挙げると

e.g.1
1: package main
2:
3: import "fmt"
4:
5: func main() {
6:     var pointer *string
7:     var name string = "nomurakkooo"
8:
9:     pointer = &name
10:
11:    fmt.Println("&name: ", &name)
12:    fmt.Println("pointer: ", pointer)
13:    fmt.Println("name: ", name)
14:    fmt.Println("*pointer: ", *pointer) 
15: }
実行結果
&name:  0xc42007e050
pointer:  0xc42007e050
name:  nomurakkooo
*pointer:  nomurakkooo

なぜ使うのか

関数に引数を渡す時, それは全てコピーを渡している.

関数内で引数として渡された値を更新したいときや引数が大きすぎてコピーしたくないなーってときに使おう.

ちなみに, コピーを渡すということは変数を参照するアドレスは変化している.
変化しているからこそ参照元の値が更新されないというわけですね.

関数へのポインタ渡しについて

前記の「なぜ使うのか」 というところにもつながる.
引数をポインタで渡すことにより参照元のアドレス, 値の共有を行う.

簡単に渡してみる

e.g.2
1: package main
2:
3: import "fmt"
4:
5: type Nomurakkooo struct {
6:   first  string
7:   last string
8: }
9:
10: func updateName(name *Nomurakkooo) {
11:  name.first = "nomurakkooo"
12:  name.last = "rakko"
13:
14:  fmt.Println("関数内:", name.first, name.last)
15: }
16:
17: func main() {
18:  fullName := Nomurakkooo{first: "nomura", last: "kouta"}
19:
20:  fmt.Println("更新前:", fullName)
21:
22:  updateName(&fullName)
23:
24:  fmt.Println("更新後:", fullName)
25: }
実行結果
更新前: {nomura kouta}
関数内: nomurakkooo rakko
更新後: {nomurakkooo rakko}

構造体の場合は11, 12行目で(*name).firstとかじゃなくてええんかって思うのですがname.firstでも指定できるみたいです.
アドレスへの参照の仕方はをつけるで統一したほうが良い感は伝わって来るが実際どうなのでしょう.

わかる方いらっしゃいましたら教授いただけると幸いです.

まとめ

間違えて覚えてしまいそうなところなので気をつけよう!

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