猿问

如何将接口转换为接口切片?

我的输入是一个interface{},我知道它可以是任何类型的数组。

我想读取我输入的一个元素,所以我尝试将 my 转换interface{}[]interface{},但是 go 会给我以下错误:

恐慌:接口转换:interface {} 是 []map[string]int,而不是 []interface {}

我该如何进行转换?(如果可能,不反映)。

游乐场测试

谢谢


慕桂英4014372
浏览 164回答 6
6回答

墨色风雨

reflect 涉及包的解决方案。package mainimport (    "fmt"    "reflect")func main() {    var v interface{} = []string{"a", "b", "c"}    var out []interface{}    rv := reflect.ValueOf(v)    if rv.Kind() == reflect.Slice {        for i := 0; i < rv.Len(); i++ {            out = append(out, rv.Index(i).Interface())        }    }    fmt.Println(out)}// Output:// [a b c]

Qyouu

我现在实际上正在处理这个问题,因为我的问题涉及从 json 对象 (map[string]interface{}) 中获取一些东西,它可能包含也可能不包含特定的键 ({"someKey": [a, b, c, ...]),如果它确实包含那个键,那么我们想要获取那个(它必然是 interface{} 类型)并将其转换为 []interface{}。到目前为止我找到的方法是使用 json marshall/unmarshall。

收到一只叮咚

type a map[string]interface{}type b []stringfunc main() {&nbsp; &nbsp; obj := a{&nbsp; &nbsp; &nbsp; &nbsp; "someKey": b{"a", "b", "c"},&nbsp; &nbsp; }&nbsp; &nbsp; if obj["someKey"] != nil { // check the value exists&nbsp; &nbsp; &nbsp; &nbsp; var someArr []interface{}&nbsp; &nbsp; &nbsp; &nbsp; //marshal interface to byte and then unmarshal to []interface{}&nbsp; &nbsp; &nbsp; &nbsp; somebytes, _ := json.Marshal(obj["someKey"])&nbsp; &nbsp; &nbsp; &nbsp; err := json.Unmarshal(somebytes, &someArr)&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Error in unmarshal")&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(someArr)&nbsp; &nbsp; }}

饮歌长啸

我该如何进行转换?(如果可能,不反映)。请考虑类型开关。反射是昂贵的。func toSlice(i interface{}) []interface{} {&nbsp; &nbsp; var out []interface{}&nbsp; &nbsp; switch v := i.(type) {&nbsp; &nbsp; case []interface{}:&nbsp; &nbsp; &nbsp; &nbsp; for x := 0; x < len(v); x++ {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out = append(out, v[x])&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("invalid type: %T\n", v)&nbsp; &nbsp; }&nbsp; &nbsp; return out}

宝慕林4294392

接口的重点是定义你想要使用的行为,如果你使用一个空接口,你对那个切片中的类型一无所知。如果你想打印它,你可以使用 println 或 printf 没有转换。如果你想访问它,并且必须允许任何类型,你可以使用反射(使用起来缓慢且复杂)。如果您想访问它,并使用可以为其定义函数的常见行为/数据,请定义一个接口,例如:type Doer interface {&nbsp;Do() error}parentStruct := []Doer{...}testStruct.Do()如果这些都不起作用,请等待 Go 2 和泛型。

慕哥6287543

对于任何在 2022 年发现这一点的人,现在我们有了仿制药,您可以这样做:func convertSlice[T any](data []T) []interface{} {&nbsp; &nbsp; output := make([]interface{}, len(data))&nbsp; &nbsp; for idx, item := range data {&nbsp; &nbsp; &nbsp; &nbsp; output[idx] = item&nbsp; &nbsp; }&nbsp; &nbsp; return output}
随时随地看视频慕课网APP

相关分类

Go
我要回答