英文:
Maps in Go - how to avoid double key lookup?
问题
假设我想要在一个映射中更新某个现有的值,或者在找不到键时执行其他操作。我该如何做到这一点,而不需要进行两次查找?以下是相应的Go语言代码:
value, ok := m[key]
if ok {
// 更新值,无需进行第二次查找
m[key] = calcNewValue(value)
} else {
// 执行其他操作
m[key] = 42
}
在Go语言中,使用map[key]
的方式可以直接获取映射中的值,并通过ok
变量来判断是否找到了对应的键。如果找到了键,则可以直接更新值;如果未找到键,则可以执行其他操作,例如插入新的键值对。
英文:
Suppose I want to update some existing value in a map, or do something else if the key is not found. How do I do this, without performing 2 lookups? What's the golang equivalent of the following C++ code:
auto it = m.find(key);
if (it != m.end()) {
// update the value, without performing a second lookup
it->second = calc_new_value(it->second);
} else {
// do something else
m.insert(make_pair(key, 42));
}
答案1
得分: 5
Go语言不像C++那样公开映射的内部(key,value)对数据结构,因此无法完全复制这一点。
一种可能的解决方法是将映射的值设置为指针,这样可以保持映射中的相同值,但可以更新它们指向的内容。例如,如果m
是一个map[int]*int
,你可以通过以下方式更改一个值:
v := m[10]
*v = 42
话虽如此,如果减少哈希查找次数所带来的节省被额外的内存管理开销所消耗,我不会感到惊讶。因此,值得对你选择的任何解决方案进行基准测试。
英文:
Go does not expose the map's internal (key,value) pair data structure like C++ does, so you can't replicate this exactly.
One possible work around would be to make the values of your map pointers, so you can keep the same values in the map but update what they point to. For example, if m
is a map[int]*int
, you could change a value with:
v := m[10]
*v = 42
With that said, I wouldn't be surprised if the savings from reducing the number of hash lookups will be eaten by the additional memory management overhead. So it would be worth benchmarking whatever solution you settle on.
答案2
得分: 2
你不能。实际上,这种情况与Python的字典相同。然而,这并不重要。在Go语言中,查找和赋值都是摊还O(1)的时间复杂度。将这两个操作结合起来的时间复杂度也是相同的。
英文:
You cannot. The situation is actually the same with Python dicts. However it shouldn't matter. Both lookup and assignment to a Go map are amortized O(1). Combining the two operations has the same time complexity.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论