ホームページ  >  記事  >  バックエンド開発  >  リフレクションを使用して構造体フィールド値を設定するときに SetCan() が常に False を返す問題を解決する方法は?

リフレクションを使用して構造体フィールド値を設定するときに SetCan() が常に False を返す問題を解決する方法は?

Barbara Streisand
Barbara Streisandオリジナル
2024-10-24 04:19:30483ブラウズ

How to Overcome SetCan() Always Returning False When Setting Struct Field Values Using Reflection?

構造体の SetString を使用したリフレクションの探索

リフレクションは、Go 構造を動的に操作するための強力なツールを提供します。この例では、リフレクションを使用して構造体フィールドの値を設定しようとすると、CanSet() が常に false を返すという一般的な問題が発生します。この障害によりフィールドの変更が妨げられ、私たちは困惑したままになります。

落とし穴の特定

提供されたコード スニペットは、2 つの基本的なエラーを強調しています:

  1. ポインターの代わりに値を渡す: 値による構造体は、リフレクションを通じて変更できません。代わりに、構造体へのポインターを渡し、変更が実際のオブジェクトに確実に適用されるようにする必要があります。
  2. 要素のターゲット指定が間違っています: コードは最初、ProductionInfo 構造体ではなく、ProductionInfo 構造体全体で動作します。 Field1 値を変更する必要がある特定のエントリ。これを修正するには、目的の Entry 要素に注目する必要があります。

問題の解決

これらの落とし穴に対処した後、コードを改良できます。

<code class="go">func SetField(source interface{}, fieldName string, fieldValue string) {
    v := reflect.ValueOf(source).Elem() // Obtain the value of the pointed object
    fmt.Println(v.FieldByName(fieldName).CanSet())
    if v.FieldByName(fieldName).CanSet() {
        v.FieldByName(fieldName).SetString(fieldValue)
    }
}</code>

変更された SetField() 関数では、

  1. Elem() を使用して、指定されたオブジェクトの値に移動し、実際の構造体を確実に操作します。
  2. 変更する特定のフィールドにアクセスするには、FieldByName() を使用します。

コードの動作

これらの変更により、コードは次のようになります。 Field1 の値が正常に更新されました:

<code class="go">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}

結果は、Entry 構造体内の Field1 の変更が成功したことを示しています。

以上がリフレクションを使用して構造体フィールド値を設定するときに SetCan() が常に False を返す問題を解決する方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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