Go言語でメソッドを実装する

Go言語は type で定義した構造体、もしくは別名を付けた型定義に対してメソッドを作成できる。
書式は以下。[]内のものが実際に指定する値。

func ( レシーバ[変数 型] ) メソッド名 ( 引数[変数 型] ) 戻り値[型] { 処理 }

例えば、 Student 構造体に Hello メソッドを作ってみるとする。

type Student struct {
  Name string
  Age int
}

func main() {
  taro := Student{"Tanaka Taro", 11}
  taro.Hello()
}

func (s Student) Hello() {
  fmt.Printf("Hello, %s.\n", s.Name)
}

実行すると以下のようになる。

Hello, Tanaka Taro.

関数と同様参照渡しも使える。
多分メソッドを作成する場合参照渡しが基本になるんじゃないだろうか。
なんとなくだけど、メソッドを使った上で別の変数にそれを代入するのはちょっと煩わしい気がする。
以下では PutAge() メソッドで年齢を更新し、 PrintAge() メソッドで出力してみている。

type Student struct {
  Name string
  Age int
}

func main() {
  taro := Student{"Tanaka Taro", 11}
  taro.PrintAge()

  taro.PutAge(14)
  taro.PrintAge()
}

func (s *Student) PutAge(age int) {
  s.Age = age
}

func (s Student) PrintAge() {
  fmt.Printf("%s age is %d\n", s.Name, s.Age)
}

実行すると以下のようになる。

Tanaka Taro age is 11
Tanaka Taro age is 14

値が書き換わっているが、 PutAge() メソッドで参照渡しをしているため、直接 taro.Age の値を操作できるというわけだ。すごい。
書いてて思ったがRubyでいうところの破壊的変更っぽいか?どうだろう。
大きい値は値渡しをしてしまうと関数呼び出しの際にコピーしてしまうため、大きい値や構造体の場合は参照渡しをした方が良いとのこと。
うーん...なんだか脳死で参照渡しにしてしまいそうだな...。
このケースだと値渡しで、このケースなら参照渡し、みたいなのがあると嬉しいなあ。