1

I want to define a struct completely dynamically, so that I can get the following struct, but without defining it first?

type Data struct {
   a string
   b int `json:"b"`
}
d := Data{}
aclowkay
  • 3,577
  • 5
  • 35
  • 66
  • 4
    What's the use case? – bereal Aug 20 '19 at 06:05
  • 1
    The main issue here is that you cannot, via reflection, *set* any unexported field (since Go 1.8). Since `a` and `b` are both unexported, you will only be able to create a zero-valued `Data` object. – torek Aug 20 '19 at 06:08
  • 1
    Yes you can create structs via reflection. – mkopriva Aug 20 '19 at 06:10
  • 2
    The function https://godoc.org/reflect#StructOf will get you most of the way there. The unexported fields shown in the question are not supported. – Charlie Tumahai Aug 20 '19 at 06:25
  • 2
    I'm with @bereal here, why is this needed? There might be another way that doesn't rely on reflection and etc. – mazei513 Aug 20 '19 at 11:30

1 Answers1

11

An application can create a struct programmatically using reflect.StructOf, but all fields in the struct must be exported.

The question gets the struct as a value, but it's likely that a pointer to the struct is more useful to the application.

Given the above, this answer shows how to do the following without defining the type at compile time:

type Data struct {
   A string `json:"a"`
   B int `json:"b"`
}
var d interface{} = &Data{}

The code is:

t := reflect.StructOf([]reflect.StructField{
    {
        Name: "A",
        Type: reflect.TypeOf(int(0)),
        Tag:  `json:"a"`,
    },
    {
        Name: "B",
        Type: reflect.TypeOf(""),
        Tag:  `json:"B"`,
    },
})
d := reflect.New(t).Interface()

Here's a runnable example that sets some fields: https://play.golang.org/p/uik7Ph8_BRH

asethi
  • 126
  • 1
  • 3