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

Susan Sarandon
Freigeben: 2024-10-24 12:47:31
Original
118 Leute haben es durchsucht

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>
Nach dem Login kopieren

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>
    Nach dem Login kopieren
  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>
    Nach dem Login kopieren

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>
Nach dem Login kopieren

Ausgabe:

Before:  {A 2}
true
After:  {NEW_VALUE 2}
Nach dem Login kopieren

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!

Quelle:php
Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!