src 是一个元素类型为interface{} 的切片。所以你获得的每个元素都是静态类型interface{},所以它们的“种类”将是reflect.Interface。添加一个新的reflect.Interface 案例将揭示:
case reflect.Interface:
fmt.Println("value", each.Interface(), "is interface")
输出将是(在Go Playground 上尝试):
value noval is interface
value 0 is interface
value <nil> is nil
如果你想要界面中的“包裹”元素,请使用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 ?")
}
}
然后输出将是(在Go Playground上试试):
value noval is string
value 0 is int
value <nil> is nil
还请注意,您是在“切换”值的种类,而不是它们的实际类型。这意味着多种类型的值可能会在特定情况下结束,比如在这个例子中:
type mystr string
src := []interface{}{"noval", 0, nil, mystr("my")}
srcType := reflect.ValueOf(src)
// ...
输出将是(在Go Playground 上尝试):
value noval is string
value 0 is int
value <nil> is nil
value my is string
mystr("my") 的值被检测为string,因为它属于string"kind",但它的类型不是string 而是mystr。这可能是也可能不是您想要的。如果您想区分 string 和 mystr 类型的值,那么您应该“切换”实际的 type 值,如下例所示:
} 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 ?")
}
}
然后输出将是(在Go Playground 上尝试):
value noval is string
value 0 is int
value <nil> is nil
value my is mystr
如您所见,"nova" 被检测为string 类型的值,mystr("my") 被正确检测为mystr 类型的值。
另请注意,对于您想要做的事情,您不需要反思,只需使用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 ?")
}
}
输出(在Go Playground 上试试):
value noval is string
value 0 is int
value <nil> is nil