Home  >  Article  >  Backend Development  >  How to Pass Nested Structures by Reference for Reflection?

How to Pass Nested Structures by Reference for Reflection?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-10-24 01:49:01477browse

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn