メソッドは、構造体(の型)と結びつけられた関数だ。Go はオブジェクト指向プログラミング言語ではないけど、このメソッドや構造体の埋め込み(これについては後で書くつもり)によって、オブジェクト指向的なプログラミングができるようになっている。
例を挙げよう。
前のエントリでは平面上の点を表す Point
構造体と、2点間の距離を求める distance
関数を作った。ここでもう一つ、3次元空間の点を表す Point3d
構造体を作る。この2点間の距離を求める関数を考えたとき、distance
という名前は使えない。すでに名前を使ってしまっているからだ。
ところが、これらをそれぞれの構造体のメソッドにすれば、両方とも distance
という名前にできる。
メソッドの一般亭な定義は次の通り。
func (仮引数 *型) 関数名(仮引数, ...) { 処理 }
ここで、関数名の前のカッコの中にある仮引数をレシーバと言い、このメソッドはレシーバの型と結びつけられる。これで、Point
と Point3d
の両方の構造体に、同じ distance
という名前のメソッドが定義できるわけだ。
実際に書いてみよう。
package main import ( "fmt" "math" ) type Point struct { x, y float64 } type Point3d struct { x, y, z float64 } func newPoint(x, y float64) *Point { p := new(Point) p.x, p.y = x, y return p } func newPoint3d(x, y, z float64) *Point3d { p := new(Point3d) p.x, p.y, p.z = x, y, z return p } func (p *Point) distance(q *Point) float64 { dx := p.x - q.x dy := p.y - q.y return math.Sqrt(dx * dx + dy * dy) } func (p *Point3d) distance(q *Point3d) float64 { dx := p.x - q.x dy := p.y - q.y dz := p.z - q.z return math.Sqrt(dx * dx + dy * dy + dz * dz) } func main() { p1 := newPoint(0.0, 0.0) p2 := newPoint(10.0, 10.0) q1 := newPoint3d(0.0, 0.0, 0.0) q2 := newPoint3d(10.0, 10.0, 10.0) fmt.Println(p1.distance(p2)) fmt.Println(q1.distance(q2)) }
^o^ > go run method.go 14.142135623730951 17.320508075688775