Home >Backend Development >Golang >How to Pass Nested Structures by Reference for Reflection?
Passing Nested Structures by Reference for Reflection
Introduction
Consider the following Client and Contact data structures:
<code class="go">type Client struct { Id int Age int PrimaryContact Contact Name string } type Contact struct { Id int ClientId int IsPrimary bool Email string }</code>
Our goal is to use reflection to iterate over all Client struct fields, set default values for primitive fields, and recursively apply the same steps to any nested struct fields. However, we encounter a "reflect.Value.Set using unaddressable value" panic when trying to set values for PrimaryContact fields.
Passing by Reference
The problem arises because PrimaryContact is passed by value instead of by reference. To resolve this, we must pass PrimaryContact by reference. For that, we use Value.Addr() to obtain a pointer value for the struct field.
Solution
The following code demonstrates how to pass PrimaryContact by reference:
<code class="go">func setDefaultValue(v reflect.Value) error { if v.Kind() != reflect.Ptr { return errors.New("Not a pointer value") } v = reflect.Indirect(v) // ... (same code as before) case reflect.Struct: for i := 0; i < v.NumField(); i++ { err := setDefaultValue(v.Field(i).Addr()) if err != nil { return err } } } return nil }</code>
By using v.Field(i).Addr() to get the pointer value of each struct field, we can modify the actual struct fields instead of a copy.
Example
To illustrate the solution, let's consider the following Client instance:
<code class="go">a := Client{}</code>
After invoking our SetDefault() function, we get:
<code class="go">{Id:42 Age:42 PrimaryContact:{Id:42 ClientId:42 IsPrimary:true Email:Foo} Name:Foo}</code>
This demonstrates that the nested PrimaryContact struct fields have also been set to default values.
The above is the detailed content of How to Pass Nested Structures by Reference for Reflection?. For more information, please follow other related articles on the PHP Chinese website!