いっきのblog

技術とか色々

Goのインタフェースについて学ぶ

以前初めてGoに触った感想をまとめたが、インタフェースについては書いてなかったのでまとめる。 kzkohashi.hatenablog.com

インタフェースの定義

A Tour of Goの内容をベースに話していく。
go-tour-jp.appspot.com

インターフェースの定義は以下のように、type xxx interfaceで作成し、その中に実装するメソッドを定義する。
ここでは、AbserインターフェースにAbs関数を定義している。

type Abser interface {
    Abs() float64
}

ややこしいんだけど、interface{}型とは全く違う概念みたいなので、注意しとく。
interface{}型はintboolなど全ての値を取りうる型とのこと。

var a interface{}
a = 1 // int
a = 1.0 // float
a = "あ" // string

こちらが参考になった。ただ、ゆるく使うにしてもどう使うんだろう。
初心者に送りたいinterfaceの使い方[Golang] – Since I want to start “blog” that looks like men do, I do start. – Medium

インタフェースの実装

次にインタフェースを実装する。
float型のMyFloatを定義し、先ほどインターフェスで定義したAbsメソッドを実装する。

type MyFloat float64

func (f MyFloat) Abs() float64 {
    if f < 0 {
        return float64(-f)
    }
    return float64(f)
}

ちゃんと理解していなかったんだが、typeは構造体で使うというより、指定した型を別名でつけれるようものとのこと。
上記のMyFloatリテラルfloatの別名として、新しい型として定義されたものだ。
言われてみると当たり前な気はするけど、忘れないようにと。以下の記事がとても参考になった。

qiita.com

また、以下のようにstructにもAbsメソッドを実装している。

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

準備は整ったので、実際に使用してみる。
すこし変更させてもらって、実装したどちらのメソッドも実行している。

func main() {
    var a,b Abser
    f := MyFloat(-math.Sqrt2)
    v := Vertex{3, 4}

    a = f  // a MyFloat implements Abser
        // a = &v
    b = &v // a *Vertex implements Abser

    fmt.Println(a.Abs())
    fmt.Println(b.Abs())
}

終わりに

勉強っぽい感じの作りなんで、実際のインタフェースの使い所など学んで行きたい。
以下の記事ではGoでのインタフェースを書く注意点が書いてあるので参考になった。

qiita.com

次はGoルーチンとチャネルを書こうかな。