首页 > 后端开发 > Golang > 正文

如何使用反射修改嵌套结构体字段来实现持久化?

Susan Sarandon
发布: 2024-10-24 12:47:31
原创
118 人浏览过

How Can We Modify Nested Struct Fields Using Reflection to Achieve Persistence?

使用反射设置嵌套结构体字段

问题:

我们如何使用反射以持久的方式修改嵌套结构体字段的值?

代码:

<code class="go">type ProductionInfo struct {
    StructA []Entry
}

type Entry struct {
    Field1 string
    Field2 int
}

func SetField(source interface{}, fieldName string, fieldValue string) {
    v := reflect.ValueOf(source)
    tt := reflect.TypeOf(source)

    for k := 0; k < tt.NumField(); k++ {
        fieldValue := reflect.ValueOf(v.Field(k))

        fmt.Println(fieldValue.CanSet())
        if fieldValue.CanSet() {
            fieldValue.SetString(fieldValue.String())
        }
    }
}

func main() {
    source := ProductionInfo{}
    source.StructA = append(source.StructA, Entry{Field1: "A", Field2: 2})

    SetField(source, "Field1", "NEW_VALUE")
}</code>
登录后复制

问题:

  1. 传递错误的值:我们正在尝试设置顶级 ProductionInfo 结构的字段,而不是嵌套的 Entry 结构。这会导致错误,因为 ProductionInfo 没有 Field1 字段。
  2. 传递非指针:反射无法修改非指针结构的字段。我们需要传递一个指向 Entry 结构体的指针。

解决方案:

  1. 修改对 SetField 的调用以定位嵌入的 Entry struct:

    <code class="go">SetField(source.StructA[0], "Field1", "NEW_VALUE")</code>
    登录后复制
  2. 更改函数以接受和修改指向 Entry 的指针:

    <code class="go">func SetField(source *Entry, fieldName string, fieldValue string) {
     v := reflect.ValueOf(source).Elem()
    
     fmt.Println(v.FieldByName(fieldName).CanSet())
    
     if v.FieldByName(fieldName).CanSet() {
         v.FieldByName(fieldName).SetString(fieldValue)
     }
    }</code>
    登录后复制

最终代码:

<code class="go">package main

import (
    "fmt"
    "reflect"
)

type ProductionInfo struct {
    StructA []Entry
}

type Entry struct {
    Field1 string
    Field2 int
}

func SetField(source *Entry, fieldName string, fieldValue string) {
    v := reflect.ValueOf(source).Elem()

    if v.FieldByName(fieldName).CanSet() {
        v.FieldByName(fieldName).SetString(fieldValue)
    }
}

func main() {
    source := ProductionInfo{}
    source.StructA = append(source.StructA, Entry{Field1: "A", Field2: 2})

    fmt.Println("Before: ", source.StructA[0])
    SetField(&source.StructA[0], "Field1", "NEW_VALUE")
    fmt.Println("After: ", source.StructA[0])
}</code>
登录后复制

输出:

Before:  {A 2}
true
After:  {NEW_VALUE 2}
登录后复制

以上是如何使用反射修改嵌套结构体字段来实现持久化?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!