インターフェイスとは、異なる型の構造体を同じ型として扱うための抽象型のようなものだ。Java のインターフェイスと同様らしいけど Java のことはよく知らない。インターフェイスにはメソッドの型だけが定義されていて、そのメソッドすべてを実装した構造体はインターフェイスの型として扱えるようになる。
次の例では、インターフェイス Point
を定義している。Point
型は distance0
というメソッドを持っている。Point2d
と Point3d
というのが具体的な構造体で、そのどちらもが distance0
メソッドを実装しているので、Point
型として1つのスライスに格納されている。
package main import ( "fmt" "math" ) type Point interface { distance0() float64 } type Point2d struct { x, y float64 } func newPoint2d(x, y float64) *Point2d { p := new(Point2d) p.x, p.y = x, y return p } func (p *Point2d) distance0() float64 { return math.Sqrt(p.x * p.x + p.y * p.y) } type Point3d struct { x, y, z float64 } func newPoint3d(x, y, z float64) *Point3d { p := new(Point3d) p.x, p.y, p.z = x, y, z return p } func (p *Point3d) distance0() float64 { return math.Sqrt(p.x * p.x + p.y * p.y + p.z * p.z) } func sumOfDistance0(ary []Point) float64 { sum := 0.0 for _, p := range ary { sum += p.distance0() } return sum } func main() { a := []Point{ newPoint2d(0, 0), newPoint2d(10, 10), newPoint3d(0, 0, 0), newPoint3d(10, 10, 10), } fmt.Println(a[0].distance0()) fmt.Println(a[1].distance0()) fmt.Println(a[2].distance0()) fmt.Println(a[3].distance0()) fmt.Println(sumOfDistance0(a)) }
^o^ > go run interface.go 0 14.142135623730951 0 17.320508075688775 31.462643699419726