1

I need to check if interface{} is an array and create corresponding slice if it is. Unfortunately I do not know array length in advance.

For example:

import (
  "reflect"
)
func AnythingToSlice(a interface{}) []interface{} {
  rt := reflect.TypeOf(a)
  switch rt.Kind() {
  case reflect.Slice:
    slice, ok := a.([]interface{})
    if ok {
      return slice
    }
    // it works

  case reflect.Array:
    // return a[:]
    // it doesn't work: cannot slice a (type interface {})   
    //
    array, ok := a.([reflect.ValueOf(a).Len()]interface{})
    // :-((( non-constant array bound reflect.ValueOf(a).Len()
    if ok {
       return array[:]
    }

  }
  return []interface{}(a)
}
2
  • 2
    Chances are you're never going to see an array of interface{}, so you would need to copy the elements anyway. You also can't slice an array value if it's not addressable, so it would need to pass a pointer to an array of interface{}, which you're even less likely to encounter. Since Go types are invariant, and it's likely you need to copy the values anyway, what is the actual problem you're trying to solve? Commented Aug 15, 2017 at 14:20
  • It's only private style taken from scripting programming. When I am parsing JSON I want implicitly convert some values to arrays. For example: { "a" : [1, 2, 3] // it's ok "b": 1 // it must be converted to [1] "c": {} // it must be converted to [{}] } So I need universal function to convert anything to slice. I understand that Golang isn't JS, Python or Perl but is's only first my Golang samples. Commented Aug 17, 2017 at 7:18

1 Answer 1

3

An explicit type is required in a type assertion. The type cannot be constructed through reflection.

Unless the argument is a []interface{}, the slice or array must be copied to produce a []interface{}.

Try this:

func AnythingToSlice(a interface{}) []interface{} {
    v := reflect.ValueOf(a)
    switch v.Kind() {
    case reflect.Slice, reflect.Array:
        result := make([]interface{}, v.Len())
        for i := 0; i < v.Len(); i++ {
            result[i] = v.Index(i).Interface()
        }
        return result
    default:
        panic("not supported")
    }
}

https://play.golang.org/p/3bXxnHOK8_

Sign up to request clarification or add additional context in comments.

1 Comment

So having an array I cant get its slice directly and must create a copy. It's pity but I understand the trouble.

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.