如何在Go中更新地图值

时间:2017-03-10 11:04:38

标签: dictionary go data-structures struct

我想用字符串键和结构值构建一个映射,我可以使用它来更新map key标识的map中的struct value。

我已经尝试了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

2 个答案:

答案 0 :(得分:15)

您无法更改与地图中的键相关联的值,您只能重新分配值。

这为您提供了两种可能的选择:

  1. 在地图中存储指针,因此您可以修改指向对象(不在地图数据结构中)。

  2. 存储结构值,但修改后,需要将其重新分配给密钥。

  3. 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上试试这个。

答案 1 :(得分:0)

我正在学习 Golang,Google 带我来到这里。一种方法是创建一个 DataStore 结构。我想出了这个[见这里][1]。请告诉我这是否是一个好方法。


import (
    "fmt"
)

type Data struct {
    key   string
    value string
}

type DataStore struct {
    datastore map[string]Data
}

func newDataStore() DataStore {
    return DataStore{make(map[string]Data)}
}

/*
Puts the key and value in the DataStore.
If the key (k) already exists will replace with the provided value (v).
*/
func (ds *DataStore) put(k, v string) {
    dx := Data{key: k, value: v}
    ds.datastore[k] = dx
}

/*
Returns true, if the DataStore has the key (k)
*/
func (ds *DataStore) containsKey(k string) bool {
    if _, ok := ds.datastore[k]; ok {
        return ok
    }
    return false
}

/*
Puts the key and value in the DataStore, ONLY if the key (k) is not present.
Returns true, if the put operation is successful,
false if the key (k) ia already present in the DataStore
*/
func (ds *DataStore) putIfAbsent(k, v string) bool {
    if val, ok := ds.datastore[k]; ok {
        fmt.Println("datastore contains key: ", k, "with value =", val, " --- ", ok)
        return false
    }

    fmt.Println("datastore does not contain ", k)
    dx := Data{key: k, value: v}
    ds.datastore[k] = dx
    return true
}

/*
Returns the Data value associated with the key (k).
*/
func (ds *DataStore) get(k string) Data {
    return ds.datastore[k]
}

/*
Removes the entry for the given key(k)
*/
func (ds *DataStore) removeKey(k string) {
    delete(ds.datastore, k)
}

/*
Removes the entry for the given key(k)
*/
func (ds *DataStore) removeKeys(k ...string) {
    for _, d := range k {
        delete(ds.datastore, d)
    }
}

/*
Prints the keys and values
*/
func (ds *DataStore) print() {
    for k, v := range ds.datastore {
        fmt.Println(k, " ", v)
    }
}

func main() {
    fmt.Println("Hello, playground")
    ds := newDataStore()
    ds.print()
    ds.put("D1", "V1")
    ds.put("D2", "V2")
    ds.put("D3", "V3")  
    fmt.Println("datastore with initial values")

    ds.print()

    ds.put("D1", "UpdatedData for D1")
    ds.put("D2", "UpdatedData for D2")
    ds.put("D3", "UpdatedData for D3")
    fmt.Println("datastore with updated values")

    ds.print()
    
    fmt.Println("datastore: putIfAbsent");
    ds.putIfAbsent("D3", "Duplicate Key")
    ds.putIfAbsent("D4", "V4")
    ds.putIfAbsent("D5", "V5")
    
    fmt.Println("datastore with new values")

    result := ds.get("D1")
    fmt.Println("fetching the value for D1: result: ", result)

    testKey := "D4"
    //testKeys := [2]string{"D5", "D2"}
    
    fmt.Println("datastore: containsKey: ")

    if ok := ds.containsKey(testKey); ok {
        fmt.Println("has key ", testKey, ok)
    } else {
        fmt.Println("has no key ", testKey, ok)
    }

    ds.print()
    ds.removeKey(testKey)

    fmt.Println("afer removing ", testKey)
    ds.print()

    fmt.Println("afer removing ", "D5", "D1")
    ds.removeKeys("D5", "D1")
    ds.print()
}```



  [1]: https://play.golang.org/p/4FEGkImcCKB