インターフェイス

インターフェイスとは、異なる型の構造体を同じ型として扱うための抽象型のようなものだ。Java のインターフェイスと同様らしいけど Java のことはよく知らない。インターフェイスにはメソッドの型だけが定義されていて、そのメソッドすべてを実装した構造体はインターフェイスの型として扱えるようになる。

次の例では、インターフェイス Point を定義している。Point 型は distance0 というメソッドを持っている。Point2dPoint3d というのが具体的な構造体で、そのどちらもが 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