概要
go1.14がrc1まで出たので、ちょこっと新機能試してみました。
go1.14で個人的に嬉しい機能がこれ。
今までは、以下のようにインターフェースを作ったらコンパイルエラーになってました。
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
で使えます。
サンプル
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
参考情報
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場