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

Susan Sarandon
Lepaskan: 2024-10-24 12:47:31
asal
118 orang telah melayarinya

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>
Salin selepas log masuk

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>
    Salin selepas log masuk
  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>
    Salin selepas log masuk

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>
Salin selepas log masuk

Output:

Before:  {A 2}
true
After:  {NEW_VALUE 2}
Salin selepas log masuk

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!

sumber:php
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!