Heim  >  Artikel  >  Backend-Entwicklung  >  Wie können wir verschachtelte Strukturfelder mithilfe von Reflexion ändern, um Persistenz zu erreichen?

Wie können wir verschachtelte Strukturfelder mithilfe von Reflexion ändern, um Persistenz zu erreichen?

Susan Sarandon
Susan SarandonOriginal
2024-10-24 12:47:31118Durchsuche

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

Reflexion verwenden, um verschachtelte Strukturfelder festzulegen

Problem:

Wie können wir Reflexion nutzen? den Wert eines verschachtelten Strukturfelds so ändern, dass er bestehen bleibt?

Code:

<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>

Probleme:

  1. Übergabe des falschen Werts: Wir versuchen, das Feld der ProductionInfo-Struktur der obersten Ebene anstelle der verschachtelten Entry-Struktur festzulegen. Dies führt zu Fehlern, da ProductionInfo kein Field1-Feld hat.
  2. Übergabe eines Nicht-Zeigers: Reflection kann die Felder von Nicht-Zeiger-Strukturen nicht ändern. Wir müssen einen Zeiger auf die Entry-Struktur übergeben.

Lösung:

  1. Ändern Sie den Aufruf von SetField so, dass er auf den eingebetteten Eintrag abzielt struct:

    <code class="go">SetField(source.StructA[0], "Field1", "NEW_VALUE")</code>
  2. Ändern Sie die Funktion, um einen Zeiger auf den Eintrag zu akzeptieren und zu ändern:

    <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>

Endgültiger 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>

Ausgabe:

Before:  {A 2}
true
After:  {NEW_VALUE 2}

Das obige ist der detaillierte Inhalt vonWie können wir verschachtelte Strukturfelder mithilfe von Reflexion ändern, um Persistenz zu erreichen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn