2016-08-03 20 views
4

スライス、アレイ、マップ、またはチャンネルに一致するGoタイプスイッチを使用するにはどうすればよいですか?ここでGolang Type Switch:一般的なスライス/アレイ/マップ/ chanのマッチング方法は?

package main 

import (
    "fmt" 
    "reflect" 
) 

func WhatIsIt(x interface{}) { 
    switch X := x.(type) { 
     case bool: 
      fmt.Printf("Type Switch says %#v is a boolean.\n", X) 
     case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: 
      fmt.Printf("Type Switch says %#v is an integer.\n", X) 
     case float32, float64, complex64, complex128: 
      fmt.Printf("Type Switch says %#v is a floating-point.\n", X) 
     case string: 
      fmt.Printf("Type Switch says %#v is a string.\n", X) 
     case []interface{}: 
      fmt.Printf("TypeSwitch says %#v is a slice.\n", X) 
     case map[interface{}]interface{}: 
      fmt.Printf("TypeSwitch says %#v is a map.\n", X) 
     case chan interface{}: 
      fmt.Printf("TypeSwitch says %#v is a channel.\n", X) 
     default: 
      switch reflect.TypeOf(x).Kind() { 
       case reflect.Slice, reflect.Array, reflect.Map, reflect.Chan: 
        fmt.Printf("TypeSwitch was unable to identify this item. Reflect says %#v is a slice, array, map, or channel.\n", X) 
       default: 
        fmt.Printf("Type handler not implemented: %#v\n", X) 
      } 
    } 
} 

func main() { 
    WhatIsIt(true) 
    WhatIsIt(1) 
    WhatIsIt(1.5) 
    WhatIsIt("abc") 
    WhatIsIt([]int{1,2,3}) 
    WhatIsIt(map[int]int{1:1, 2:2, 3:3}) 
    WhatIsIt(make(chan int)) 
} 

が出力されます。

Type Switch says true is a boolean. 
Type Switch says 1 is an integer. 
Type Switch says 1.5 is a floating-point. 
Type Switch says "abc" is a string. 
TypeSwitch was unable to identify this item. Reflect says []int{1, 2, 3} is a slice, array, map, or channel. 
TypeSwitch was unable to identify this item. Reflect says map[int]int{1:1, 2:2, 3:3} is a slice, array, map, or channel. 
TypeSwitch was unable to identify this item. Reflect says (chan int)(0x104320c0) is a slice, array, map, or channel. 

あなたは出力からわかるように、case []interface{}は私が送ったスライスと一致するように失敗した私が代わりにreflectパッケージの使用に頼る必要があります。

明示的にcase []intと書いても、私の例ではうまくいきますが、すべての入力タイプを事前に知ることは不可能なので、より一般的な解決策が必要です。タイプスイッチがこれを処理できる場合は、reflectパッケージを使用しないでください。

タイプスイッチを使用して、オブジェクトがスライス/アレイ/マップ/ chan/etc ...であるかどうかを判断する方法はありますか?

答えて

11

タイプスイッチは特定のタイプで動作します。スイッチのすべてのタイプを列挙できない場合、唯一のオプションは反映パッケージを使用することです。

v := reflect.ValueOf(x) 
switch v.Kind() { 
case reflect.Bool: 
    fmt.Printf("bool: %v\n", v.Bool()) 
case reflect.Int, reflect.Int8, reflect.Int32, reflect.Int64: 
    fmt.Printf("int: %v\n", v.Int()) 
case reflect.Uint, reflect.Uint8, reflect.Uint32, reflect.Uint64: 
    fmt.Printf("int: %v\n", v.Uint()) 
case reflect.Float32, reflect.Float64: 
    fmt.Printf("float: %v\n", v.Float()) 
case reflect.String: 
    fmt.Printf("string: %v\n", v.String()) 
case reflect.Slice: 
    fmt.Printf("slice: len=%d, %v\n", v.Len(), v.Interface()) 
case reflect.Map: 
    fmt.Printf("map: %v\n", v.Interface()) 
case reflect.Chan: 
    fmt.Printf("chan %v\n", v.Interface()) 
default: 
    fmt.Println(x) 
} 
関連する問題