【问题标题】:How to update map values in Go如何在 Go 中更新地图值
【发布时间】:2017-07-31 16:59:13
【问题描述】:

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

我试过 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

【问题讨论】:

    标签: dictionary go data-structures struct


    【解决方案1】:

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

    这给你留下了 2 种可能性:

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

    2. 存储struct值,但是修改时需要重新赋值给key。

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

    【讨论】:

    • 一种方法比另一种方法有什么性能优势吗?
    • @ColinO'Dell 取决于您拥有的结构。衡量性能是否对您很重要。
    【解决方案2】:

    我正在学习 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
    

    【讨论】:

    • 您的超链接([参见此处][1])似乎不起作用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多