4

I wrote the code:

switch v.(type) {
        case []interface{}:
            fmt.Println(reflect.TypeOf(v))
            for index, element := range v {
                fmt.Println("Inside for")
            }
        default:
            fmt.Println("I don't know how to handle this.")
        }

Now, my reflect.TypeOf(v) outputs the type as []interface {} . But, I'm not able to iterate over the array of interfaces. I encounter the error:cannot range over v (type interface {}). Could someone please explain me why ? Also, what's the workaround ?

2 Answers 2

9

In a type switch, if you wish to access the variable casted to the appropriate type just use something like switch x := v.(type) and in each case of the switch x will be of the appropriate value. The spec has an example of this. You can even do switch v := v.(type) and within the switch statement there will be a shadowed version of v.

E.g.:

switch x := v.(type) {
case []interface{}:
        fmt.Printf("got %T\n", x)
        for i, e := range x {
                fmt.Println(i, e)
        }
default:
        fmt.Printf("I don't know how to handle %T\n", v)
}

playground

Also note that you can just use "%T" with fmt.Printf instead of (directly) using the reflect package when you just want to print the type of a variable.

Finally, note that a type switch is what you want if you have multiple non-default clauses, but if, as in your example, you really only have one type you are interested in then instead you should do something like:

if x, ok := v.([]interface{}); ok {
        fmt.Printf("got %T\n", x)
        for i, e := range x {
                fmt.Println(i, e)
        }
} else {
        fmt.Printf("I don't know how to handle %T\n", v)
}
Sign up to request clarification or add additional context in comments.

Comments

2

You can always use v.([]interface{}). I ran into the same problem when trying to parse hetrogeneous json objects that had to be treated as interfaces.

Although that might not work in your loop unless you know something about your data beforehand.

2 Comments

I just changed my switch v.(type) to switch vv := v.(type) and everything started working fine when I range over vv. Thanks anyway.
I should have noted in my answer that if you only have the two cases in the switch (i.e. you only handle one type) you really should be using vv, ok := v.([]interface{}) and just checking ok. A type switch is for when you want to handle multiple types.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.