简体   繁体   中英

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

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 ).

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.

You could use reflect against some "truth" slice that you define. This function will take in 2 slices and compare their types, returning an error if the types do not match in the same order.

So arr is your []interface{} slice. exp is the expected slice, such as

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

See 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. 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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