Go言語構造体と値渡し、参照渡しおさらい

ちょっとGo言語ハンズオンをやっているのだけど、メソッドが出てきてから脳の処理が追いつかなくなってきました。
理解がね...追いついていないのです…。

なのでとりあえず書き出そうかと。

構造体

通常使うとしたら以下

type 構造体の名称 struct {
...
}

// 例
type Student struct {
  Name string
  Age int
}

あまり使わなさそうだが変数に直接定義する場合

var 変数 struct {
...
}

// 例
var taro struct {
  Name string
  Age int
}

構造体を利用する場合は以下

// 前者
taro := Student{"Tanaka Taro", 11}

// もしくは
taro := Student{
  Name: "Tanaka Taro",
  Age: 11,
}

// 後者
taro.Name = "Tanaka Taro"
taro.Age = "11"

これはわかる。まだ。

構造体の値渡しと参照渡し

構造体を引数とした関数を作る場合、値渡しと参照渡しの2つの方法がある。
値渡しの例は以下

func main() {
  taro := Student{"Tanaka Taro", 11}
  // 変数 taro を引数として関数 plus1 を呼び出し、結果を変数 taro_1 に格納する
  taro_1 := plus1(taro)
  // 変数は taro と taro_1 の2つを保持することになる
  fmt.Println(taro)
  fmt.Println(taro_1)
}

func plus1(s Student) Student {
  // s.Age に +1 してから再度書き込む
  s.Age += 1
  // 戻り値は Student型(構造体) なので、 s.Age に +1 した変数 s を return する
  return s
}

参照渡しの例は以下

func main() {
  taro := Student{"Tanaka Taro", 11}
  // 関数 plus1 に変数 taro のポインタを渡す
  plus1(&taro)
  fmt.Println(taro)
}

// ポインタを渡されているため、型の前に * を付けて値を参照できるようにする
func plus1(s *Student) {
  // ポインタ s の Age を操作するため、 (*s) として参照先とし、参照先の Age に +1 する
  // ただし、 s.Age += 1 としてもいける(ポインタレシーバというやつか?)。
  (*s).Age += 1
}

値渡し参照渡しが引っかかりポイントとしてある。
参照渡しの時 (*s) としなくても正しくコンパイルが通るのは以下の暗黙的変換が効いているからだろうか…?

skatsuta.github.io

書籍は読み進めても書いていなかった...。どういうことなんだ...。

とりあえず一旦そういうものとして理解するしかないか...。
この辺なんて検索すれば出てくるのだろうか。