我试图动态地创建一个结构片段,我可以将数据编组到其中,但在运行时基于某种未知的结构类型执行。我之所以这样做,是因为我希望有一段共同的代码,可以对实现特定接口的任何东西进行解组。
例如(伪码)
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实现了特定的接口。
有些代码让我不明白为什么动态创建的片在解组后不维护其类型:
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
}产出:
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 {}发布于 2016-06-08 22:27:14
您正在使用反射构建[]*myObj,但随后将*interface{}传递给json.Unmarshal。json包将指针的目标视为interface{}类型,因此使用其默认类型将其解封为。您需要创建一个指向所创建的片类型的指针,因此对Interface()方法的调用将返回您想要解编组到的确切类型,即*[]*myObj。
sliceType := reflect.SliceOf(reflect.TypeOf(&myObj{}))
slicePtr := reflect.New(sliceType)
err = json.Unmarshal([]byte(input), slicePtr.Interface())https://stackoverflow.com/questions/37713749
复制相似问题