概要
Tour of Go の - Type Switch についてのサンプル。
前回、Goの型検証という仕組みついて書きました。
インターフェースと特定の具象型、もしくは別のインターフェース型に変換可能か検証して可能であるなら、その型に変換するという機能ですね。
今回のType Switchという機能は、型検証をうまくつかうための仕組みです。
GoのSwitchは、とてもフレキシブルな構造をしていて、型検証をswitchで表現することもできるようになっています。
単純にif文を何個も書いて型検証をしても当然問題ないのですが、この type switch を使ったほうが見やすくなります。
使い方は以下のような形です。
switch v := i.(type) { case T: インターフェース i の値がT型に変換できた場合 case S: インターフェース i の値がS型に変換できた場合 default: それ以外 }
注意点として、i.(type)
としている部分の(type)
のところは、実際の型を書くのではなくて、このまま(type)
と書きます。この (type)
の部分が case の部分の型で置き換えられて評価されます。
サンプル
package tutorial import "fmt" type ( ifGoTour22 interface { ifGoTour221 ifGoTour222 } ifGoTour221 interface { func1() string } ifGoTour222 interface { func2() string } ifGoTour221Impl struct { } ifGoTour222Impl struct { } ifGoTour22BothImpl struct { } ifGoTour22NotImpl struct { } ) func (i *ifGoTour22BothImpl) func2() string { return fmt.Sprintf("[func2] %T", i) } func (i *ifGoTour22BothImpl) func1() string { return fmt.Sprintf("[func1] %T", i) } func (i *ifGoTour222Impl) func2() string { return fmt.Sprintf("[func2] %T", i) } func (i *ifGoTour221Impl) func1() string { return fmt.Sprintf("[func1] %T", i) } // TypeSwitch は、 Tour of Go - Type switches (https://tour.golang.org/methods/16) の サンプルです。 func TypeSwitch() error { // ------------------------------------------------------------ // Type Switch // Go言語には、Type Switch という機能がある. // これは、 Type Assertions を switch で定義して直列に使用できる機能. // つまり、そのインターフェースの中の具象型への変換に関して // 複数の候補が存在する場合に、通常のswitch文のようにcase分けして // 判定できるという機能。 if 文を並べるよりも見やすい。 // // 以下の構文で記述する. // switch v := i.(type) { // case T: // インターフェース i の値がT型に変換できた場合 // case S: // インターフェース i の値がS型に変換できた場合 // default: // 上記以外の場合 // } // // switch のところの i.(type) という部分であるが、ここは // (type)の部分を望みの型で指定するのではなく、このまま (type) と // 書く。この (type) の部分が case の部分の型で置き換えられて // 評価される。 // ------------------------------------------------------------ var ( sli1 []interface{} sli2 []interface{} ) sli1 = make([]interface{}, 0) sli1 = append(sli1, 100) sli1 = append(sli1, "helloworld") sli1 = append(sli1, true) for _, v := range sli1 { switch d := v.(type) { case int: fmt.Printf("[int] %v\n", d) case string: fmt.Printf("[string] %v\n", d) case bool: fmt.Printf("[bool] %v\n", d) } } sli2 = make([]interface{}, 0) sli2 = append(sli2, &ifGoTour221Impl{}) sli2 = append(sli2, &ifGoTour222Impl{}) sli2 = append(sli2, &ifGoTour22BothImpl{}) sli2 = append(sli2, &ifGoTour22NotImpl{}) for _, v := range sli2 { switch d := v.(type) { case ifGoTour22: fmt.Println(d.func1(), d.func2()) case ifGoTour221: fmt.Println(d.func1()) case ifGoTour222: fmt.Println(d.func2()) default: fmt.Printf("[それ以外] %T\n", d) } } return nil }
try-golang/tutorial_gotour_22_typeswitch.go at master · devlights/try-golang · GitHub
実行すると以下な感じ。
[Name] "tutorial_gotour_type_switch" [int] 100 [string] helloworld [bool] true [func1] *tutorial.ifGoTour221Impl [func2] *tutorial.ifGoTour222Impl [func1] *tutorial.ifGoTour22BothImpl [func2] *tutorial.ifGoTour22BothImpl [それ以外] *tutorial.ifGoTour22NotImpl
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場