src is a slice whose element type is interface{}. So each element you obtain is of static type interface{}, so their "kind" will be reflect.Interface. Adding a new reflect.Interface case will reveal that:
case reflect.Interface:
fmt.Println("value", each.Interface(), "is interface")
Output will be (try it on the Go Playground):
value noval is interface
value 0 is interface
value <nil> is nil
If you want the "wrapped" element in the interface, use Value.Elem():
} else if each.Kind() == reflect.Interface {
switch each.Elem().Kind() {
case reflect.String:
fmt.Println("value", each.Interface(), "is string")
case reflect.Int, reflect.Int16:
fmt.Println("value", each.Interface(), "is int")
default:
fmt.Println("value", each.Interface(), "is ?")
}
}
Then output will be (try it on the Go Playground):
value noval is string
value 0 is int
value <nil> is nil
Also note that you're "switching" over the kind of the values, not over their actual types. What this means is that values of multiple types may end up in specific cases, like in this one:
type mystr string
src := []interface{}{"noval", 0, nil, mystr("my")}
srcType := reflect.ValueOf(src)
// ...
Output of this will be (try it on the Go Playground):
value noval is string
value 0 is int
value <nil> is nil
value my is string
The value mystr("my") is detected as string, because it is of string "kind", but its type is not string but mystr. This may or may not be what you want. If you want to distinguish between a value of type string and mystr, then you should "switch" over the actual type of values like in this example:
} else if each.Kind() == reflect.Interface {
switch each.Elem().Type() {
case reflect.TypeOf(""):
fmt.Println("value", each.Interface(), "is string")
case reflect.TypeOf(0):
fmt.Println("value", each.Interface(), "is int")
case reflect.TypeOf(mystr("")):
fmt.Println("value", each.Interface(), "is mystr")
default:
fmt.Println("value", each.Interface(), "is ?")
}
}
Then output will be (try it on the Go Playground):
value noval is string
value 0 is int
value <nil> is nil
value my is mystr
As you can see "nova" is detected as a value of type string, and mystr("my") is properly detected as a value of type mystr.
Also note that for what you're trying to do, you don't need reflection, just use a type switch:
src := []interface{}{"noval", 0, nil}
for _, v := range src {
switch v.(type) {
case string:
fmt.Println("value", v, "is string")
case int:
fmt.Println("value", v, "is int")
case nil:
fmt.Println("value", v, "is nil")
default:
fmt.Println("value", v, "is ?")
}
}
Output (try it on the Go Playground):
value noval is string
value 0 is int
value <nil> is nil