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

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

Susan Sarandon
Susan Sarandonオリジナル
2024-10-24 12:47:31118ブラウズ

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

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。