Search code examples
gointerface

How do you cast an array of unknown type to type []any?


Assuming only arrays are passed as arguments to the arr parameter, I would like each call of unpackArray() to return the argument casted from its original array type to type []any.

package main

func unpackArray(arr any) []any {
    return arr.([]any)
}

func main() {
    myArr1 := []string {"Hey"}
    myArr2 := []int {60}
    unpackArray(myArr1)
    unpackArray(myArr2)
}

However, this code yields error panic: interface conversion: interface {} is []string, not []interface {}. So it is not allowing me to cast an interface whose static type is not type []any to type []any.

So, given I know that arr's static type is some type of array, and without changing the arr parameter's initialization type from any, how could I convert arr to type []any using this function?

(I am encountering the same problem with maps where I cannot cast from an arbitrary map type to type map[any]any, but I am guessing the solution to this issue would be similar to the solution for arrays.)


Solution

  • Go does not have a builtin "cast" like this, but you can write a function to do it.

    You may use reflection to convert a slice of any type to []any:

    func unpackArray(s any) []any {
        v := reflect.ValueOf(s)
        r := make([]any, v.Len())
        for i := 0; i < v.Len(); i++ {
            r[i] = v.Index(i).Interface()
        }
        return r
    }
    

    You can also use generics in Go 1.18 or later:

    func unpackArray[S ~[]E, E any](s S) []any {
        r := make([]any, len(s))
        for i, e := range s {
            r[i] = e
        }
        return r
    }
    

    Both versions of these functions work as requested in the question:

    myArr1 := []string {"Hey"}
    myArr2 := []int {60}
    unpackArray(myArr1)
    unpackArray(myArr2)
    

    Notes:

    • Go does not have "cast" like some other languages. Go has the somewhat related type assertion and conversion features.
    • The expression arr.([]any) is a type assertion. The expression asserts that the concrete value in the interface arr has type []any. The expression does not do any conversion.
    • The code in the question uses slices , not arrays as written in the title.