首頁 > 後端開發 > 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 欄位。
傳遞非指標:

反射無法修改非指標結構的欄位。我們需要傳遞一個指向 Entry 結構體的指標。

    解決方案:
  1. <code class="go">SetField(source.StructA[0], "Field1", "NEW_VALUE")</code>
    登入後複製
  2. 修改SetField 的呼叫以定位嵌入的Entry struct:
  3. <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>
    登入後複製
  4. 更改函數以接受和修改指向Entry 的指針:

<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學習者快速成長!