如何在Golang中返回一个未知类型的数组?

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

How to return an array of unknown type in Golang?

问题

所以我有一个方法,需要返回一个数组,但我不知道要返回什么类型的数组。
返回的数组类型取决于方法的逻辑。

我的方法看起来像这样...

func (c Case) GetFrdValues(frdFieldKey string) (interface{}, error) {
    for _, singleFrd := range c.CaseDetails.GetCase().GetFrds() {
        if singleFrd.GetIdentifier().GetFieldKey() == frdFieldKey {
            switch singleFrd.GetValue().WhichType() {
            case casespb.Value_StringValue_case:
                return []string{singleFrd.GetValue().GetStringValue()}, nil
            case casespb.Value_NumberValue_case:
                return [1]float64{singleFrd.GetValue().GetNumberValue()}, nil
            case casespb.Value_BoolValue_case:
                return [1]bool{singleFrd.GetValue().GetBoolValue()}, nil
            case casespb.Value_NullValue_case:
                return []string{}, nil
            case casespb.Value_ListValue_case:
                return GetValuesFromFrdListValue(singleFrd.GetValue().GetListValue())
            default:
                return []string{}, nil
            }
        }
    }
    return []string{}, fmt.Errorf("Frd Value contains unsupported value type %v", frdFieldKey)
}

这个方法很好用,因为它确实返回了我想要的值的数组。

然而,我需要在另一个方法中操作返回的数组。但是无法对列表(类型为interface{}的变量)进行迭代。

因此,返回的值应该是[]interface{}类型。但是如果我这样做,那么我在各个返回语句上会收到以下错误。

cannot use ([]string literal) (value of type []string) as []interface{} value in return statement.

我在Stack Overflow或者网上找不到任何关于这个问题的解答,所以非常感谢任何帮助!

英文:

So I have a method which needs to return an array but I don't know what type of array to return.
This type of array to return is down to the methods logic.

My method looks like this...

func (c Case) GetFrdValues(frdFieldKey string) (interface{}, error) {
	for _, singleFrd := range c.CaseDetails.GetCase().GetFrds() {
		if singleFrd.GetIdentifier().GetFieldKey() == frdFieldKey {
			switch singleFrd.GetValue().WhichType() {
			case casespb.Value_StringValue_case:
				return []string{singleFrd.GetValue().GetStringValue()}, nil
			case casespb.Value_NumberValue_case:
				return [1]float64{singleFrd.GetValue().GetNumberValue()}, nil
			case casespb.Value_BoolValue_case:
				return [1]bool{singleFrd.GetValue().GetBoolValue()}, nil
			case casespb.Value_NullValue_case:
				return []string{}, nil
			case casespb.Value_ListValue_case:
				return GetValuesFromFrdListValue(singleFrd.GetValue().GetListValue())
			default:
				return []string{}, nil
			}
		}
	}
	return []string{}, fmt.Errorf("Frd Value contains unsupported value type %v", frdFieldKey)
}

This works fine as it does still return an array of the values I want.

However I need to manipulate the returned array in a separate method. But cannot range over list (variable of type interface{}).

Therefore the returned value needs be like [] interface{}. However if I have it like that then I receive the error on my various return statements about.

cannot use ([]string literal) (value of type []string) as []interface{} value in return statement.

I can't find anything on stack overflow or the web about this, so any help would be greatly appreciated!

答案1

得分: 2

你可以使用反射来遍历一个未知类型的数组。这里有一个简化的示例,它只是打印出数组的元素。

package main

import (
	"fmt"
	"reflect"
)

func main() {
	doSomething([]string{"a", "b", "c"})
	doSomething([]int{1, 2, 3})
}

func doSomething(item interface{}) {
	reflectType := reflect.TypeOf(item)
	if reflectType.Kind() == reflect.Ptr {
		reflectType = reflectType.Elem()
	}

	if reflectType.Kind() != reflect.Slice {
		fmt.Println("received item is not a slice")
		return
	}

	val := reflect.ValueOf(item)

	itemLength := val.Len()
	for i := 0; i < itemLength; i++ {
		fmt.Println(val.Index(i))
	}
}

链接:https://play.golang.org/p/5umonjVp90D

英文:

You can use reflection to loop over an array of unknown type. Here is a simplified example that simply prints out the elements of an array.

https://play.golang.org/p/5umonjVp90D

package main

import (
	&quot;fmt&quot;
	&quot;reflect&quot;
)

func main() {
	doSomething([]string{&quot;a&quot;, &quot;b&quot;, &quot;c&quot;})
	doSomething([]int{1, 2, 3})
}

func doSomething(item interface{}) {
	reflectType := reflect.TypeOf(item)
	if reflectType.Kind() == reflect.Ptr {
		reflectType = reflectType.Elem()
	}

	if reflectType.Kind() != reflect.Slice {
		fmt.Println(&quot;received item is not a slice&quot;)
		return
	}

	val := reflect.ValueOf(item)

	itemLength := val.Len()
	for i := 0; i &lt; itemLength; i++ {
		fmt.Println(val.Index(i))
	}
}

huangapple
  • 本文由 发表于 2021年6月17日 20:04:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/68018980.html
匿名

发表评论

匿名网友

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

确定