在Golang类型断言中使用反射数组类型是可能的吗?

huangapple go评论103阅读模式
英文:

Is it possible to use reflected array type in Golang type assertions?

问题

我需要检查interface{}是否为数组,并在是数组时创建相应的切片。不幸的是,我事先不知道数组的长度。

例如:

  1. import (
  2. "reflect"
  3. )
  4. func AnythingToSlice(a interface{}) []interface{} {
  5. rt := reflect.TypeOf(a)
  6. switch rt.Kind() {
  7. case reflect.Slice:
  8. slice, ok := a.([]interface{})
  9. if ok {
  10. return slice
  11. }
  12. // 它起作用了
  13. case reflect.Array:
  14. // return a[:]
  15. // 它不起作用:无法对a进行切片(类型为interface{})
  16. //
  17. array, ok := a.([reflect.ValueOf(a).Len()]interface{})
  18. // :-((( 非常量数组边界reflect.ValueOf(a).Len()
  19. if ok {
  20. return array[:]
  21. }
  22. }
  23. return []interface{}(a)
  24. }
英文:

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:

  1. import (
  2. "reflect"
  3. )
  4. func AnythingToSlice(a interface{}) []interface{} {
  5. rt := reflect.TypeOf(a)
  6. switch rt.Kind() {
  7. case reflect.Slice:
  8. slice, ok := a.([]interface{})
  9. if ok {
  10. return slice
  11. }
  12. // it works
  13. case reflect.Array:
  14. // return a[:]
  15. // it doesn't work: cannot slice a (type interface {})
  16. //
  17. array, ok := a.([reflect.ValueOf(a).Len()]interface{})
  18. // :-((( non-constant array bound reflect.ValueOf(a).Len()
  19. if ok {
  20. return array[:]
  21. }
  22. }
  23. return []interface{}(a)
  24. }

答案1

得分: 3

在类型断言中需要显式指定类型。该类型不能通过反射构造。

除非参数是 []interface{} 类型,否则必须复制切片或数组以生成 []interface{}。

尝试这样做:

  1. func AnythingToSlice(a interface{}) []interface{} {
  2. v := reflect.ValueOf(a)
  3. switch v.Kind() {
  4. case reflect.Slice, reflect.Array:
  5. result := make([]interface{}, v.Len())
  6. for i := 0; i < v.Len(); i++ {
  7. result[i] = v.Index(i).Interface()
  8. }
  9. return result
  10. default:
  11. panic("not supported")
  12. }
  13. }

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

英文:

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:

  1. func AnythingToSlice(a interface{}) []interface{} {
  2. v := reflect.ValueOf(a)
  3. switch v.Kind() {
  4. case reflect.Slice, reflect.Array:
  5. result := make([]interface{}, v.Len())
  6. for i := 0; i &lt; v.Len(); i++ {
  7. result[i] = v.Index(i).Interface()
  8. }
  9. return result
  10. default:
  11. panic(&quot;not supported&quot;)
  12. }
  13. }

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

huangapple
  • 本文由 发表于 2017年8月15日 22:03:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/45694512.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定