「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > リフレクションを使用して構造体フィールド値を設定するときに SetCan() が常に False を返す問題を解決する方法は?

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

2024 年 11 月 9 日に公開
ブラウズ:875

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

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

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

落とし穴の特定

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

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

問題の解決

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

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

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

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

コードの動作

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

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])
}

出力:

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

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

リリースステートメント この記事は次の場所に転載されています: 1729662680 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3