[Golang]メソッド関連(レシーバー/起動/値レシーバー/ポインタレシーバー)についてのサンプル集

# 急ぎの方へ　いきなり今回のサンプルコード全容
```golang:今回のサンプルコード全容
package main
import "fmt"

type user struct {
	name string
	height int
	gender string
}

func (u user)show() {
	fmt.Printf("名前：%s / 身長：%d / 性別：%s\n", u.name, u.height, u.gender)
}

func (u *user)update() {
	u.height = 181
}

func main() {
	u := user{name:"徳川", height:180, gender:"男"}
	u.update() // 更新するメソッド（ポインタレシーバー）
	u.show() // 出力するメソッド（値レシーバー）
}
```

# Go言語でのメソッドとは
- オブジェクト指向型に出てくるようなクラスや、その中で定義される「いわゆる一般的な」メソッドではない。
- メソッドは、[構造体](https://qiita.com/riotam/items/e15399d0bbcba8c77987)などのデータに紐付いた関数。

# レシーバーを書く
たとえば、下の`user`という構造体に紐付けた、`show`メソッドを書きたい場合…

```golang:構造体「user」
type user struct {
	name string
	height int
	gender string
}
```

```golang:書き方：構造体userに紐付いたメソッド
func (/*このメソッド内での変数名*/ /*紐付けたい構造体名*/) /*メソッド名*/() {
	// ここに処理を書く
}
```

このように記述します。
少しややこしいので、具体例を出します。

今回は、ただ単にuserフィールドにアクセスして、出力するだけの処理を書きます。
もちろん、userという構造体に紐付けられています。

```golang:具体例：構造体「user」に紐付けた「show」メソッド
func (u user)show() {
	fmt.Printf("名前：%s / 身長：%d / 性別：%s\n", u.name, u.height, u.gender)
}
```
このメソッド内では、`u`と書くことで`user`フィールドへアクセスしています。

# メソッドを起動させる

```golang:書き方：メソッドを起動させる
func /*何かのメソッドの中*/() {
	// 何かの処理
	/*フィールドをnewしたもの*/./*起動させたいメソッド名*/()

}
```
↑こんな感じです。
またしても分かりにくい感じになったので、具体例を出します。

```golang:具体例：メソッドを起動させる
func main() {
	u := user{name:"徳川", height:180, gender:"男"}
	u.show()
}
```
なお、`user`構造体は、一番上のものと同じです。
このように、`u.show()`とすることで、`u(=user構造体)`に紐付いた形で関数を使うことができる。

# このままでは元データを更新できないので注意
## 元データを更新できない？
さきほど登場した、具体例↓

```golang:具体例：構造体「user」に紐付けた「show」メソッド
func (u user)show() {
	fmt.Printf("名前：%s / 身長：%d / 性別：%s\n", u.name, u.height, u.gender)
}
```
↑では、user構造体を**そのまま**値渡ししている状態です。
この例のように、ただ出力するだけなら問題ないのですが、**メソッドから元のデータを書き換えたい場合、これでは対応できません。**

具体例です。
たとえば徳川くんの身長が1cm伸びて`u.height = 181`に変わったとしましょう。
~~ちょっと無茶な成長期になってしまいました。~~

そのためのメソッドを以下のように書きます。

```golang:具体例：身長が1cm伸びたので更新するための「update」メソッド
func (u user)update() {
	u.height = 181 // u.heightを180から181に更新
}
```

これで以下のように実行しても…

```golang:具体例：「update」メソッドの起動
func main() {
	u := user{name:"徳川", height:180, gender:"男"}
	u.update()
	fmt.Println(u) // => {徳川 180 男} ←身長が更新されていない…
}
```
このように、そのままuser型で引数を指定しても、本体のデータを更新することができず、身長は180cmのままで更新(変更)がされません。

## 元データを変更するには、引数をポインタにする
ポインタの指定の仕方は簡単です。
`*`を付け加えましょう。

具体例です。

```golang:具体例：「*」をつけてポインタレシーバーにしたメソッド
func (u *user)update() {
	u.height = 181
}
```
↑こうすることで、データの本体が更新されます。

```golang:具体例：「*」をつけてポインタレシーバーにしたメソッド
func main() {
	u := user{name:"徳川", height:180, gender:"男"}
	u.update() // u.height = 181　に更新するメソッド
	fmt.Println(u) // => {徳川 181 男} ←うまく更新された！
}
```
うまくいきました。
**データそのものを変更させる場合には、ポインタレシーバーにしましょう。**

## 注意！　Go言語に参照渡しは「存在しない」
@c-yan さんに、何度かご指摘頂いている内容ですが、Go言語には参照渡しは存在しません。
まとめていただいている記事は[こちら](https://qiita.com/c-yan/items/2be6aa12170fec5e929c)です。

僕の参考にしていた教材も、「…参照渡しにするには〜…」という表現を頻繁に使っており、みなさんが勘違いしやすい部分なのかもしれません。

# まとめ
というワケで今回は長くなってしまいましたが、具体例として書いたコードをまとめると、以下の通りです。
（一番最初に出したコードと同じです。）

```golang:今回のサンプルコード全容
package main
import "fmt"

type user struct {
	name string
	height int
	gender string
}

func (u user)show() {
	fmt.Printf("名前：%s / 身長：%d / 性別：%s\n", u.name, u.height, u.gender)
}

func (u *user)update() {
	u.height = 181
}

func main() {
	u := user{name:"徳川", height:180, gender:"男"}
	u.update() // 更新するメソッド（ポインタレシーバー）
	u.show() // 出力するメソッド（値レシーバー）
}
```

最後までありがとうございました。