ホームページ > バックエンド開発 > Golang > リフレクションを使用してネストされた構造体フィールドを変更して永続性を実現するにはどうすればよいでしょうか?

リフレクションを使用してネストされた構造体フィールドを変更して永続性を実現するにはどうすればよいでしょうか?

Susan Sarandon
リリース: 2024-10-24 12:47:31
オリジナル
218 人が閲覧しました

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. 間違った値を渡す: ネストされた Entry 構造体の代わりに、最上位の ProductionInfo 構造体のフィールドを設定しようとしています。 ProductionInfo には Field1 フィールドがないため、エラーが発生します。
  2. 非ポインターを渡す: リフレクションは、非ポインター構造体のフィールドを変更できません。 Entry 構造体へのポインタを渡す必要があります。

解決策:

  1. 埋め込まれた Entry をターゲットにするように SetField の呼び出しを変更します。 struct:

    <code class="go">SetField(source.StructA[0], "Field1", "NEW_VALUE")</code>
    ログイン後にコピー
  2. エントリへのポインタを受け入れて変更するように関数を変更します:

    <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>
    ログイン後にコピー

最終コード:

<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 中国語 Web サイトの他の関連記事を参照してください。

ソース:php
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート