Go语言 如何将接口转换为接口片?

polkgigr  于 2022-12-07  发布在  Go
关注(0)|答案(5)|浏览(151)

我的输入是一个interface{},我知道它可以是任何类型的数组。
我想读取输入中的一个元素,所以我尝试将interface{}转换为[]interface{},但是go会给予我以下错误:
死机:接口转换:接口{}是[]Map[字符串]整型,而不是[]接口{}
我怎么能做转换?(如果可能的话,没有反映)。
Playground test
谢谢

lymnna71

lymnna711#

该解决方案涉及reflectpackage

package main

import (
    "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]
o8x7eapl

o8x7eapl2#

实际上,我现在正在处理这个问题,因为我的问题涉及到从json对象(map[string]interface{})中获取内容,该对象可能包含也可能不包含特定的键({“someKey”:[a,B,c,...]),如果它确实包含该键,那么我们需要获取该键(必须是interface{}类型)并将其转换为[]interface{}。到目前为止,我找到的方法是使用json马歇尔/unmarshall。这对我来说似乎有点笨拙,如果我找到更优雅的解决方案,将进行更新。在那之前,您可以使用我的方法:https://play.golang.org/p/4VAwQQE4O0b

type a map[string]interface{}
type b []string

func main() {
    obj := a{
        "someKey": b{"a", "b", "c"},
    }
    if obj["someKey"] != nil { // check the value exists
        var someArr []interface{}

        //marshal interface to byte and then unmarshal to []interface{}
        somebytes, _ := json.Marshal(obj["someKey"])
        err := json.Unmarshal(somebytes, &someArr)
        if err != nil {
            fmt.Println("Error in unmarshal")
        }
        fmt.Println(someArr)
    }
}
p4rjhz4m

p4rjhz4m3#

接口的作用是定义你想要使用的行为,如果你使用一个空接口,你就不知道那个切片中的类型。
如果你想打印它,你可以使用println或printf,而不需要转换。
如果您想访问它,并且必须允许任何类型,则可以使用reflect(使用起来缓慢而复杂)。
如果要访问它,并使用可为其定义函数的通用行为/数据,请定义一个接口,例如:

type Doer interface {
 Do() error
}
parentStruct := []Doer{...}
testStruct.Do()

如果这些都不起作用,那就等待Go 2和泛型。

7vux5j2d

7vux5j2d4#

对于任何在2022年发现这一点的人,现在我们有了泛型,你可以这样做:

func convertSlice[T any](data []T) []interface{} {
    output := make([]interface{}, len(data))
    for idx, item := range data {
        output[idx] = item
    }
    return output
}
kqhtkvqz

kqhtkvqz5#

我认为您所看到是类型Assert

package main

import (
    "fmt"
)

func main() {

    parentStruct := map[string]interface{}{
         "test": []map[string]int{
          {"a": 1, "b": 2},
          {"c": 3},
        },
   }

   testStruct := parentStruct["test"].([]map[string]int)

   fmt.Println(testStruct)
}

阅读此链接:https://golang.org/ref/spec#Type_assertions
https://play.golang.org/p/81uL2hgrN3l

相关问题