Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimanakah Kami Boleh Mengubah Suai Medan Struktur Bersarang Menggunakan Refleksi untuk Mencapai Kegigihan?

Bagaimanakah Kami Boleh Mengubah Suai Medan Struktur Bersarang Menggunakan Refleksi untuk Mencapai Kegigihan?

Susan Sarandon
Susan Sarandonasal
2024-10-24 12:47:31118semak imbas

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

Menggunakan Refleksi untuk Menetapkan Medan Struktur Bersarang

Masalah:

Bagaimanakah kita boleh menggunakan refleksi untuk mengubah suai nilai medan struct bersarang dengan cara yang berterusan?

Kod:

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

Isu:

  1. Melalukan nilai yang salah: Kami cuba menetapkan medan struct ProductionInfo peringkat atas, bukannya struct Entry bersarang. Ini menyebabkan ralat kerana ProductionInfo tidak mempunyai medan Field1.
  2. Melalui bukan penuding: Refleksi tidak boleh mengubah suai medan struct bukan penuding. Kita perlu menghantar penuding kepada struct Entri.

Penyelesaian:

  1. Ubah suai panggilan ke SetField untuk menyasarkan Entri terbenam struct:

    <code class="go">SetField(source.StructA[0], "Field1", "NEW_VALUE")</code>
  2. Tukar fungsi untuk menerima dan mengubah suai penunjuk ke Entri:

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

Kod Akhir :

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

Output:

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

Atas ialah kandungan terperinci Bagaimanakah Kami Boleh Mengubah Suai Medan Struktur Bersarang Menggunakan Refleksi untuk Mencapai Kegigihan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn