检查 interface{} 是否是某物的切片 ([]interface{})

func main() {

    strSlice := []string{"a", "b", "c"}

    f(strSlice)

}


func f(slice interface{}) {

    anySlice, isSlice := slice.([]interface{})

    fmt.Printf("isSlice = %t, anySlice = %#v\n", isSlice, anySlice)

}

游乐场: https: //play.golang.org/p/UN25mIOqmOd


该程序打印isSlice = false, anySlice = []interface {}(nil). 这是为什么?我本来希望这种类型的断言是可能的。


并且:有没有办法动态检查 interface{} 是某物的一部分?


明月笑刀无情
浏览 257回答 3
3回答

杨__羊羊

类型断言失败,因为 a[]string不是[]interface{}. 有关详细信息,请参阅常见问题解答。使用反射包来确定接口中的具体值是否为切片:func f(slice interface{}) {&nbsp; &nbsp; isSlice := reflect.ValueOf(slice).Kind() == reflect.Slice&nbsp; &nbsp; fmt.Printf("isSlice = %t, anySlice = %#v\n", isSlice, slice)}在操场上运行它。您还可以使用反射包来遍历值:v := reflect.ValueOf(slice)isSlice := v.Kind() == reflect.Sliceif isSlice {&nbsp; &nbsp; for i := 0; i < v.Len(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("%d: %v\n", i, v.Index(i).Interface())&nbsp; &nbsp; }}

蛊毒传说

该程序打印isSlice = false, anySlice = []interface {}(nil). 这是为什么?因为slice不包含 a []interface{},所以它包含 a []string。这些是不同的类型,Go 没有给你任何协变容器类型的概念。并且:有没有办法动态检查 interface{} 是某物的一部分?是的,您可以使用反射:func f(slice interface{}) {&nbsp; &nbsp; typ := reflect.TypeOf(slice)&nbsp; &nbsp; if typ.Kind() == reflect.Slice {&nbsp; &nbsp; &nbsp; &nbsp; elemType := typ.Elem()&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("slice of", elemType.Name())&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("not a slice")&nbsp; &nbsp; }}实际上,对这些信息做任何事情可能会更复杂。

MMMHUHU

请注意,如果您将断言更改为:slice.([]string) things will work as expected。string当您考虑 Go如何处理interface{}类型断言时,这是有道理的。以下将导致编译错误:package mainfunc main() {&nbsp; &nbsp; s := "some string"&nbsp; &nbsp; i := s.(interface{})}错误:invalid type assertion: s.(<inter>) (non-interface type string on left)由于 Go 不将字符串视为类型,因此从[]stringto也应该失败是有道理的。[]interface{}interface{}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go