How can I use a Go Type Switch to match a generic slice, array, map, or channel?
package main
import (
"fmt"
"reflect"
)
func WhatIsIt(x interface{}) {
switch X := x.(type) {
case bool:
fmt.Printf("Type Switch says %#v is a boolean.
", X)
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
fmt.Printf("Type Switch says %#v is an integer.
", X)
case float32, float64, complex64, complex128:
fmt.Printf("Type Switch says %#v is a floating-point.
", X)
case string:
fmt.Printf("Type Switch says %#v is a string.
", X)
case []interface{}:
fmt.Printf("TypeSwitch says %#v is a slice.
", X)
case map[interface{}]interface{}:
fmt.Printf("TypeSwitch says %#v is a map.
", X)
case chan interface{}:
fmt.Printf("TypeSwitch says %#v is a channel.
", 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.
", X)
default:
fmt.Printf("Type handler not implemented: %#v
", 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))
}
Here is the output:
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.
As you can see from the output, the case []interface{}
fails to match the slice that I send in. I need to resort to using the reflect
package instead.
If I explicitly write case []int
, then it works for my given example, but it's impossible to know all the input types ahead of time, so I need a more general solution. I want to avoid using the reflect
package if the Type Switch is able to handle this.
Is there any way to use the Type Switch to determine if an object is a slice/array/map/chan/etc...?