Search code examples
goreflectionreflect

How to determine type of values in a slice of interface{}


Consider the following code:

package main

import (
    "fmt"
    "reflect"
)

func f(v interface{}) {
    fmt.Println(reflect.TypeOf(v).Elem())
    fmt.Println(reflect.ValueOf(v))
}
func main() {
    var aux []interface{}
    aux = make([]interface{}, 2)
    aux[0] = "foo"
    aux[1] = "bar"
    f(aux)
}

The output is:

interface {}
[foo bar]

How can I determine the type of the elements that are contained in a slice of interface{}, in this particular example I need to know in my function f that this slice of interface{} contains string values.

My use case is, using reflection, I am trying to set a struct field depending on the type of values my slice of interface{} parameter holds.


Solution

  • The value you pass in is of type []interface{}, so the element type will be interface{}. If you want to see what the element types are, you need to reflect on those individually:

    func f(i interface{}) {
        v := reflect.ValueOf(i)
        for i := 0; i < v.Len(); i++ {
            e := v.Index(i)
            fmt.Println(e.Elem().Type())
            fmt.Println(e)
        }
    }
    

    If you know you will always have a []interface{}, use that as the argument type to make iteration and type checking easier:

    func f(things []interface{}) {
        for _, thing := range things {
            v := reflect.ValueOf(thing)
            fmt.Println(v.Type())
            fmt.Println(v)
        }
    }