为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
明月笑刀无情 2022-06-13 16:39:36
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{} 是某物的一部分?
查看完整描述

3 回答

?
杨__羊羊

TA贡献1943条经验 获得超7个赞

类型断言失败,因为 a[]string不是[]interface{}. 有关详细信息,请参阅常见问题解答。


使用反射包来确定接口中的具体值是否为切片:


func f(slice interface{}) {

    isSlice := reflect.ValueOf(slice).Kind() == reflect.Slice

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

}

在操场上运行它。


您还可以使用反射包来遍历值:


v := reflect.ValueOf(slice)

isSlice := v.Kind() == reflect.Slice

if isSlice {

    for i := 0; i < v.Len(); i++ {

        fmt.Printf("%d: %v\n", i, v.Index(i).Interface())

    }

}


查看完整回答
反对 回复 2022-06-13
?
蛊毒传说

TA贡献1895条经验 获得超3个赞

该程序打印isSlice = false, anySlice = []interface {}(nil). 这是为什么?


因为slice不包含 a []interface{},所以它包含 a []string。这些是不同的类型,Go 没有给你任何协变容器类型的概念。


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


是的,您可以使用反射:


func f(slice interface{}) {

    typ := reflect.TypeOf(slice)

    if typ.Kind() == reflect.Slice {

        elemType := typ.Elem()

        fmt.Println("slice of", elemType.Name())

    } else {

        fmt.Println("not a slice")

    }

}

实际上,对这些信息做任何事情可能会更复杂。


查看完整回答
反对 回复 2022-06-13
?
MMMHUHU

TA贡献1834条经验 获得超8个赞

请注意,如果您将断言更改为:slice.([]string) things will work as expected。string当您考虑 Go如何处理interface{}类型断言时,这是有道理的。以下将导致编译错误:


package main


func main() {

    s := "some string"

    i := s.(interface{})

}

错误:


invalid type assertion: s.(<inter>) (non-interface type string on left)

由于 Go 不将字符串视为类型,因此从[]stringto也应该失败是有道理的。[]interface{}interface{}


查看完整回答
反对 回复 2022-06-13
  • 3 回答
  • 0 关注
  • 256 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信