go

Use reflect to make a new struct from unknown struct type


I have a function that expects to receive an array of pointers to structs of unknown definitions. I want to be able to create a new instance of the unknown struct, assign values to it, and then append it to the given array.

// Someone using this package example:
type Foo Struct {
    Val int
    Nested []Bar
}

type Bar struct {
   Val int
}

func main() {
    var foos []*Foo
    Mutate(&foos)
    
    // Expect foos[0] to be:
    // Foo{Val: 1, Nested: { Bar{Val: 2} } }
}

// My function (no access to definition of Foo)
func Mutate(target any) {
    // This is where i am stuck
    t := reflect.TypeOf(target).Elem()
    // => []*main.Foo
    // I have no idea of how to create a new instance 
    // of main.Foo or even see what fields it has.
}

Solution

  • Try this code:

    func Mutate(target any) {
        // Get reflect.Value for slice.
        slice := reflect.ValueOf(target).Elem()
    
        // Create pointer to value. Set a field in the value.
        valuet := slice.Type().Elem().Elem()
        valuep := reflect.New(valuet)
        value := valuep.Elem()
        value.FieldByName("Val").SetInt(1)
    
        // Append value pointer to slice set resulting slice
        // in target.       
        slice.Set(reflect.Append(slice, valuep))
    }
    

    https://play.golang.com/p/fAxkHexQheC