web-dev-qa-db-ja.com

Goでマップ値を更新する方法

文字列キーと構造体の値でマップを作成します。マップキーで識別されたマップの構造体の値を更新できます。

私は thisthis を試しましたが、希望の出力が得られません。

私が本当に欲しいのはこれです:

Received ID: D1 Value: V1
Received ID: D2 Value: V2
Received ID: D3 Value: V3
Received ID: D4 Value: V4
Received ID: D5 Value: V5

Data key: D1 Value: UpdatedData for D1
Data key: D2 Value: UpdatedData for D2
Data key: D3 Value: UpdatedData for D3
Data key: D4 Value: UpdatedData for D4
Data key: D5 Value: UpdatedData for D5

Data key: D1 Value: UpdatedData for D1
Data key: D2 Value: UpdatedData for D2
Data key: D3 Value: UpdatedData for D3
Data key: D4 Value: UpdatedData for D4
Data key: D5 Value: UpdatedData for D5
16
Mehulkumar

マップ内のキーに関連付けられた値を変更することはできません。値を再割り当てすることしかできません。

これにより、2つの可能性が残ります。

  1. pointedオブジェクト(マップデータ構造内にない)を変更できるように、ポインターをマップに格納します。

  2. 構造体の値を格納しますが、変更する場合は、キーに再割り当てする必要があります。

1.ポインターの使用

マップへのポインタの格納:dataManaged := map[string]*Data{}

マップを「埋める」とき、ループの変数は使用できません。ループが繰り返されるたびに上書きされるためです。代わりにそのコピーを作成し、そのコピーのアドレスを保存します。

for _, v := range dataReceived {
    fmt.Println("Received ID:", v.ID, "Value:", v.Value)
    v2 := v
    dataManaged[v.ID] = &v2
}

出力は期待どおりです。 Go Playground で試してください。

2.変更された構造体の再割り当て

マップに構造体の値を保存することにこだわる:dataManaged := map[string]Data{}

キーと値のペアを反復処理すると、値のコピーが得られます。したがって、値を変更した後、値を再度割り当てます。

for m, n := range dataManaged {
    n.Value = "UpdatedData for " + n.ID
    dataManaged[m] = n
    fmt.Println("Data key:", m, "Value:", n.Value)
}

Go Playground でこれを試してください。

21
icza