I am trying to dynamically create a slice of structures that I can combine my data, but doing it at runtime based on an unknown type of structure. I do this because I want to have one common bit of code that can unleash anything that implements a particular interface.
eg. (pseudo code)
func unmarshalMyData(myInterface MyInterface, jsonData []byte) { targetSlice := myInterface.EmptySlice() json.Unmarshal(jsonData, &targetSlice) }
I tried several different alternatives. The most promising is the use of the reflect package to create a slice. Unfortunately, after disassembling, a dynamically created slice has the type []interface{} . If I print the type of dynamically created slice before canceling it, it prints []*main.myObj . Can anyone explain why? See Link to the playground: https://play.golang.org/p/vvf1leuQeY
Is there any other way to dynamically create a slice of structures that correctly cancels?
I know json.RawMessage , but there are several reasons why I cannot use it ... there is no type field in my json. In addition, the code in which I am unmarshalling does not have time to compile the structure, that it is unmarshalling. He only knows that a structure implements a specific interface.
Some code that puzzles me why a dynamically created slice does not retain its type after parsing:
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 }
Output:
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 {}