简体   繁体   English

如何将多个变量的接口一起转换为动态类型

[英]How to cast multiple variables' interfaces to dynamic types together

I know that for a single variable x , to check if it is of a certain type B , just do我知道对于单个变量x ,要检查它是否属于某种类型B ,只需执行

switch b.(type) {
case *B:
  fmt.Println("find it!")
default:
  fmt.Println("can't find it")
}

But now I have a slice of 4 variables, and I'd like to know if their types follow a certain pattern (eg of type A,B,C,D ).但是现在我有 4 个变量的一部分,我想知道它们的类型是否遵循某种模式(例如A,B,C,D类型)。

I know I can do it with a tedious forloop, with many if s and case s wrapping together, but I wonder if there's a more elegant way to achieve what I want.我知道我可以用一个乏味的 forloop 来完成它,将许多ifcase包装在一起,但我想知道是否有更优雅的方法来实现我想要的。

You could use reflect against some "truth" slice that you define.您可以对您定义的某些“真实”切片使用reflect This function will take in 2 slices and compare their types, returning an error if the types do not match in the same order.这个 function 将接受 2 个切片并比较它们的类型,如果类型不以相同的顺序匹配则返回错误。

So arr is your []interface{} slice.所以arr是你的[]interface{}切片。 exp is the expected slice, such as exp是预期的切片,例如

// The values don't matter, only the type for the "truth" slice.
exp := []interface{}{int(0), "", Foo{}, Bar{}}

See https://goplay.tools/snippet/5nja8M00DSt参见https://goplay.tools/snippet/5nja8M00DSt

// SameTypes will compare 2 slices. If the slices have a different length,
// or any element is a different type in the same index, the function will return
// an error.
func SameTypes(arr, exps []interface{}) error {
    if len(arr) != len(exps) {
        return errors.New("slices must be the same length")
    }

    for i := range arr {
        exp := reflect.TypeOf(exps[i])
        found := reflect.TypeOf(arr[i])
        if found != exp {
            return fmt.Errorf("index '%d' expected type %s, got %s", i, exp, found)
        }
    }

    return nil
}

Keep in mind Foo{} and &Foo{} are different types.请记住Foo{}&Foo{}是不同的类型。 If you don't care if it's a pointer, you will have to do additional reflect code.如果您不关心它是否是指针,则必须执行额外的反射代码。 You can do this to get the value of the ptr if the type is a pointer.如果类型是指针,您可以这样做以获取 ptr 的值。

x := &Foo{}
t := reflect.TypeOf(x)
// If t is a pointer, we deference that pointer
if t.Kind() == reflect.Ptr {
    t = t.Elem()
}

// t is now of type Foo

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM