いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-50 (go1.14の新機能をちょこっと試す(インターフェースのオーバーラップ可能))

概要

go1.14がrc1まで出たので、ちょこっと新機能試してみました。

go1.14で個人的に嬉しい機能がこれ。

github.com

今までは、以下のようにインターフェースを作ったらコンパイルエラーになってました。

type (
    // インターフェース1 Sayメソッドを持つ
    if01 interface {
        Say() string
    }

    // インターフェース2 こいつもSayメソッドを持つ
    if02 interface {
        Say() string
    }

    // インターフェース3 if01とif02を埋め込み
    if03 interface {
        if01
        if02
    }
}

埋め込みしてるインターフェースのどっちも同じシグネチャのメソッドを持っているのでコンパイルエラーになるんですね。

これが、go1.14だと許容されるようになります。

このIssue、ず~と前から議論されててやっとAcceptされました。なんと2013年から始まってる。

go1.14をダウンロード

Goは、ちょこっと別のバージョン試すときに go get でGo言語自体をダウンロードできるので便利です。

$ GO111MODULE=off go get golang.org/dl/go1.14rc1

$ go1.14rc1 download

$ go1.14rc1 version
go1.14rc1 download

$ go1.14rc1 mod init iftest

$ cat go.mod
module iftest

go 1.14

これで、go1.14rc1で使えます。

devlights.hatenablog.com

サンプル

package main

import (
    "fmt"
)

type (
    // インターフェース1 Sayメソッドを持つ
    if01 interface {
        Say() string
    }

    // インターフェース2 こいつもSayメソッドを持つ
    if02 interface {
        Say() string
    }

    // インターフェース3 if01とif02を埋め込み
    if03 interface {
        if01
        if02
    }

    // 実装用構造体
    impl01 struct{}
)

func NewIf() if03 {
    i := new(impl01)
    return i
}

// if01, if02, if03の実装
func (i *impl01) Say() string {
    return "hello world"
}

func main() {
    // go1.14 だとコンパイルエラー無しに動く
    // go1.13 だとコンパイルエラーが出る
    obj := NewIf()
    fmt.Println(obj.Say())
 
    v, ok := obj.(if01)
    fmt.Printf("%#v\t%v\n", v, ok)

    v, ok = obj.(if02)
    fmt.Printf("%#v\t%v\n", v, ok)

    m1(obj)
    m2(obj)
}

func m1(i if01) {
    fmt.Println(i.Say())
}

func m2(i if02) {
    fmt.Println(i.Say())
}

go1.13でビルドすると

go1.13でビルドすると以下のようになります。

$ go mod edit -go=1.13
$ go build
# iftest
./main.go:18:3: duplicate method Say
./main.go:35:17: ambiguous selector obj.Say

go1.14でビルドすると

go1.14でビルドするとちゃんとコンパイルできます。

$ go1.14rc1 mod edit -go=1.14
$ go1.14rc1 build
$ ./iftest
hello world
&main.impl01{}  true
&main.impl01{}  true
hello world
hello world

参考情報

medium.com


過去の記事については、以下のページからご参照下さい。

  • いろいろ備忘録日記まとめ

devlights.github.io

サンプルコードは、以下の場所で公開しています。

  • いろいろ備忘録日記サンプルソース置き場

github.com

github.com

github.com