今回はGo言語の値レシーバーとポインタレシーバーについてやっていきます!
この記事の後に、こちらの記事まで読んでいただくとよりGo言語に関する理解が深まると思います!
#値レシーバーとは
package main
import "fmt"
type Vertex struct {
X, Y int
}
func (v Vertex) Area() int {
return v.X * v.Y
}
//値レシーバー
func (v Vertex) Scale(i int) {
v.X = v.X * i
v.Y = v.Y * i
}
func main() {
v := Vertex{3, 4}
v.Scale(10)
fmt.Println(v.Area()) // => 12
}
こちらは値レシーバになります。
めっちゃ乱暴にいうと*がなければ値レシーバーになります。値渡しとか言われるようです。
v.Scale(10)で引数を渡しており、Scale関数の中では v.X = 3 * 10 v.Y = 4 * 10 となります。
しかし、値渡しでは直接Vertexの中身を書き換えることができません。あくまでもScale関数のスコープ内で値が書き換わっただけです。
よってArea関数では初期値のX,Yが使われるので返り値として 3 * 4 = 12が出力されます。
【補足】
func (v Vertex) Area()と書くことによってVertexとArea()関数を紐づけることができます。
こちらのメソッドを呼び出すときは、**v.Area()**と書くと呼び出すことができます。
Goにはクラスという概念がありませんが、このようにすることによってオブジェクト指向のような書き方ができます。
(rubyでいうとUser.hogeみたいな感じですね)
#値レシーバー
package main
import "fmt"
type Vertex struct {
X, Y int
}
func (v Vertex) Area() int {
return v.X * v.Y
}
//ポインタレシーバー(*がついただけ)
func (v *Vertex) Scale(i int) {
v.X = v.X * i
v.Y = v.Y * i
}
func main() {
v := Vertex{3, 4}
v.Scale(10)
fmt.Println(v.Area()) // => 1200
}
変数名のとなりに*をつけただけです!
これをすることによって構造体の中身を書き換えることができます。
よってScale関数の引数で渡されたときに v.X = 30, v.Y = 40 となりそれがそのままArea関数に渡ります。
よってv.Area()の出力結果は1200となります!
#最後まで読んでいただきありがとうございます!
なにか間違いや、ご質問などありましたら気軽にコメントもらえると嬉しいです!!