Get value of interface{ } without having access to type

Issue

How can I get the value of x as []interface{} ?

func main() {

    var x interface{} = SomeFunc()
    
    fmt.Println(x) // this prints [1 2].

    val := x.([]interface{}) // this will not work because '[]interface{}' is different type than 'a'

}

func SomeFunc() interface{} {
    // some type I dont have access to
    type a []interface{}

    var someArray a = make([]interface{}, 0)
    someArray = append(someArray, 1)
    someArray = append(someArray, 2)
    return someArray
}

Solution

Type asserting a concrete type works only for the exact (identical) concrete type stored in an interface value, you can’t type assert "similar" types (e.g. types having the same underlying type).

In your case what you want is get a value that is convertible to a known type (e.g. a value of type a convertible to a value of type []interface{}). As said above, this is not possible with type assertion.

The easiest is to import the package that holds the definition of the concrete type (and type assert a value of that type). If it’s not exported or not accessible, your only option is using reflection. You may use Value.Convert() to convert a value to a value of another type, a value of a type you can type assert. To check if the value is actually convertible, you may use Value.CanConvert().

y := reflect.ValueOf(x).Convert(reflect.TypeOf([]interface{}{})).Interface()

val := y.([]interface{})
fmt.Printf("%T %v\n", val, val)

This will output (try it on the Go Playground):

[1 2]
[]interface {} [1 2]

Answered By – icza

Answer Checked By – Dawn Plyler (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.