首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将其解封为运行时在Go中确定的结构数组。

将其解封为运行时在Go中确定的结构数组。
EN

Stack Overflow用户
提问于 2016-06-08 22:04:55
回答 1查看 908关注 0票数 3

我试图动态地创建一个结构片段,我可以将数据编组到其中,但在运行时基于某种未知的结构类型执行。我之所以这样做,是因为我希望有一段共同的代码,可以对实现特定接口的任何东西进行解组。

例如(伪码)

代码语言:javascript
复制
func unmarshalMyData(myInterface MyInterface, jsonData []byte) {
   targetSlice := myInterface.EmptySlice()
   json.Unmarshal(jsonData, &targetSlice)
}

我试过几种不同的选择。最有希望的是使用reflect包来构造切片。不幸的是,在解组之后,动态创建的片具有一种[]interface{}类型。如果在解组之前打印出动态创建的片的类型,它就会打印[]*main.myObj。有人能解释原因吗?参见操场链接:https://play.golang.org/p/vvf1leuQeY

是否有其他方法可以动态地创建一个可以正确解除封送的结构片段?

我知道json.RawMessage,但有几个原因我不能使用它.在我的json中没有"type“字段。此外,我正在解组的代码对正在解组的结构没有编译时知识。它只知道struct实现了特定的接口。

有些代码让我不明白为什么动态创建的片在解组后不维护其类型:

代码语言:javascript
复制
package main

import (
    "encoding/json"
    "fmt"
    "reflect"
)

func main() {
    input := `[{"myField":"one"},{"myField":"two"}]`
    myObjSlice := []*myObj{}
    fmt.Printf("Type of myObjSlice before unmarshalling %T\n", myObjSlice)
    err := json.Unmarshal([]byte(input), &myObjSlice)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Type of myObjSlice after unmarshalling %T\n", myObjSlice)

    myConstructedObjSlice := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(&myObj{})), 0, 0).Interface()
    fmt.Printf("Type of myConstructedObjSlice before unmarshalling %T\n", myConstructedObjSlice)
    err = json.Unmarshal([]byte(input), &myConstructedObjSlice)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Type of myConstructedObjSlice after unmarshalling %T\n", myConstructedObjSlice)
}

type myObj struct {
    myField string
}

产出:

代码语言:javascript
复制
Type of myObjSlice before unmarshalling []*main.myObj
Type of myObjSlice after unmarshalling []*main.myObj
Type of myConstructedObjSlice before unmarshalling []*main.myObj
Type of myConstructedObjSlice after unmarshalling []interface {}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-08 22:27:14

您正在使用反射构建[]*myObj,但随后将*interface{}传递给json.Unmarshal。json包将指针的目标视为interface{}类型,因此使用其默认类型将其解封为。您需要创建一个指向所创建的片类型的指针,因此对Interface()方法的调用将返回您想要解编组到的确切类型,即*[]*myObj

代码语言:javascript
复制
sliceType := reflect.SliceOf(reflect.TypeOf(&myObj{}))
slicePtr := reflect.New(sliceType)

err = json.Unmarshal([]byte(input), slicePtr.Interface())
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37713749

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档