はじめに
Go初心者です。
メソッドとレシーバについてまとめてみました。
メソッド / レシーバとは
メソッドとはレシーバに呼び出される関数のこと。
レシーバとはメソッドを呼び出す側のオブジェクトのこと。
以下のコードだと、
(p Person)がレシーバで、 Greet()がメソッド。
type Person struct {
Name string
}
func (p Person) Greet() string {
return "Hi, " + p.Name
}
メソッドを使ってみる
メソッドはレシーバで定義した構造体の変数から呼ぶことができる。
下の例では、Person型の変数personが、Greetメソッドを呼んでいる。
type Person struct {
Name string
}
func (p Person) Greet() string {
return "Hi, " + p.Name
}
func main() {
person := Person{Name: "hoge"}
fmt.Println(person.Greet())
}
値レシーバとポインタレシーバ
レシーバには値レシーバとポインタレシーバの2種類がある。
ポインタレシーバ:ポインタ型を引数に渡すので、関数内でオブジェクトの値を変更できる。
値レシーバ:元の値とは別のコピーした値を引数に渡すので、関数内で元の値は変更できない。
以下のコードでは、
(p Person)をレシーバとして定義しているのが値レシーバ。
(p *Person)をレシーバとして定義しているのがポインタレシーバ。
type Person struct {
Name string
}
// 値レシーバ
func (p Person) Greet() string {
return "Hi, " + p.Name
}
// ポインタレシーバ
func (p *Person) Rename(newName string) string{
p.Name = newName
return p.Name
}
ポインタレシーバを使う場面
使う場面は2点ありそう
- その構造体型のデータの値を変えたい時
- メモリを効率的に利用したい時
値レシーバがコピーした引数を用いるのに対して、ポインタレシーバでは構造体そのもののデータを操作できる。
また、引数をコピーするとそれだけ余分にメモリを消費するため、メモリ消費を抑えたい場合はポインタレシーバを使うと良さそう。