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

リフレクションを使用して CanSet() と構造体で構造体フィールドを変更する方法

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

How to Use Reflection to Modify Struct Fields with CanSet() and Structs?

リフレクションを使用した構造体フィールドの変更: CanSet() および Structs

リフレクションを使用して構造体フィールドを変更する場合は、原則を理解することが重要ですフィールドのアクセシビリティと変更の背後にあります。

CanSet() for Structs

この例では、構造体フィールドに対して false を返す CanSet() が発生しました。これは、デフォルトでは、Go ではリフレクションを使用して構造体のエクスポートされていない (プライベート) フィールドを変更することができないためです。これは、内部構造体の状態の偶発的または悪意のある変更を防ぐためのセキュリティ対策です。

問題への対処

リフレクションを使用して構造体フィールドの値を設定するには、次の点を考慮してください。手順:

  1. 値の変更: SetField() 関数を呼び出すときは、構造体の値自体ではなく、構造体へのポインターを渡します。これにより、コピーではなく実際の構造体を変更できます。
  2. ポインターには Value.Elem() を使用します: 構造体へのポインターを渡す場合は、reflect.ValueOf を使用する必要があります。 (source).Elem() を使用して、ポイントされた構造体のreflect.Valueを取得します。これにより、実際の構造体の値に移動します。
  3. フィールド アクセスに FieldByName を使用する: 構造体のすべてのフィールドをループする代わりに、v.FieldByName(fieldName) を使用して、必要な特定のフィールドにアクセスします。変更します。これにより、正しいフィールドにアクセスできるようになり、効率が向上します。

修正コード

問題に対処する修正コードは次のとおりです:

func SetField(source interface{}, 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)
    }
}

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

このコードは、Entry 構造体の Field1 値を正常に変更できるようになりました。

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

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

Copyright© 2022 湘ICP备2022001581号-3