英文:
How to create an associative map in golang?
问题
我正在尝试创建一个"关联"映射。问题在于superMap收集了aMap的所有值。
基本上,即使我只想在每次循环中存储一个aMap的实例,最终我会存储当前实例以及所有先前的循环。supermap[value] = amap[value]
。然而,下面的代码片段存储了supermap[value] = amap
。原因是我找不到任何修复这个问题的方法。如果我在每次循环后删除aMap的旧值,它们也会从supermap
中删除。
package main
import (
"fmt"
)
func main() {
aData := map[int]string{
0: "apple",
1: "samsung",
2: "htc",
3: "sony",
}
dir := []string{"user", "doc", "bin", "src"}
aMap := make(map[int]string)
superMap := make(map[string]map[int]string)
for k, v := range dir {
aMap[k] = aData[k]
superMap[v] = aMap
}
hello(superMap)
}
func hello(superMap map[string]map[int]string) {
fmt.Printf("superMap of user is %v \n", superMap["user"])
cnt := len(superMap["user"])
if cnt > 1 {
fmt.Printf("expected only one value received %v", cnt)
}
}
你可以在这里运行这段代码:Play
英文:
I'm trying to create an 'associative' map. The issue is that the superMap collects all the values of aMap.
Basically even if I want to store only one instance of amap on each look I endup storing the current instance plus all the previous loops. supermap[value] = amap[value]
. However the snippet below stores supermap[value] = amap
. The reason is that I can't find any way to fix this. If I delete the old values of aMap after each loop they are deleted from supermap
as well.
package main
import (
"fmt"
)
func main() {
aData := map[int]string{
0: "apple",
1: "samsung",
2: "htc",
3: "sony",
}
dir := []string{"user", "doc", "bin", "src"}
aMap := make(map[int]string)
superMap := make(map[string]map[int]string)
for k, v := range dir {
aMap[k] = aData[k]
superMap[v] = aMap
}
hello(superMap)
}
func hello(superMap map[string]map[int]string) {
fmt.Printf("superMap of user is %v \n", superMap["user"])
cnt := len(superMap["user"])
if cnt > 1{
fmt.Printf("expected only one value received %v", cnt)
}
}
答案1
得分: 5
根据Arjan在评论中的说法,你需要将aMap
的创建移到for循环中。原因是,在你发布的原始代码中,你正在处理内存中的一个aMap
实例。这意味着只创建了一个名为aMap
的映射,并且当你将另一个变量赋值为aMap
的值时,你正在“分配一个引用”。这意味着,任何保存引用(指向aMap
)的变量在状态发生变化时,所有其他变量也会观察到,因为它们都解析为内存中的同一个对象。
当aMap
移动到for/range循环中时,这意味着将创建4个单独的aMap
实例,每个实例都有自己的内存。修改其中一个aMap
的状态不会影响其他实例,因为它们是内存中的独立对象。现在,如果你将其中一个对象再次与另一个变量进行引用,那么你将陷入与第一种情况相同的困境。
package main
import (
"fmt"
)
func main() {
aData := map[int]string{
0: "apple",
1: "samsung",
2: "htc",
3: "sony",
}
dir := []string{"user", "doc", "bin", "src"}
superMap := make(map[string]map[int]string)
for k, v := range dir {
aMap := make(map[int]string) //在循环中创建多个映射实例
aMap[k] = aData[k]
superMap[v] = aMap
}
hello(superMap)
}
func hello(superMap map[string]map[int]string) {
fmt.Printf("user的superMap为%v \n", superMap["user"])
cnt := len(superMap["user"])
if cnt > 1 {
fmt.Printf("预期只接收到一个值,实际接收到%v个", cnt)
}
}
以上是翻译好的代码部分。
英文:
As Arjan said in the comment, you need to move the creation of aMap
into the for loop. The reason is because, in the original code you posted you are dealing with one instance of aMap
in memory. That means, only one map called aMap
is created and when you assign another variable to the value of aMap
you are assigning a reference. This means, any variable that hold a reference (to aMap
) where state is mutated, will be observed in all other variables also holding the reference because they all resolve to the same object in memory.
When the aMap
is moved into the for/range loop, this means that 4 individual instances of aMap
will be created all with their own memory. Mutating the state of one of those aMaps
will not affect the others because they are their own objects in memory. Now, if you took one of those objects and made a reference to it again with another variable then you'd end up in the same boat as the first case.
package main
import (
"fmt"
)
func main() {
aData := map[int]string{
0: "apple",
1: "samsung",
2: "htc",
3: "sony",
}
dir := []string{"user", "doc", "bin", "src"}
//aMap := make(map[int]string) //only one map instance is created in memory
superMap := make(map[string]map[int]string)
for k, v := range dir {
//multiple map instances are created in memory
aMap := make(map[int]string)
aMap[k] = aData[k]
superMap[v] = aMap
}
hello(superMap)
}
func hello(superMap map[string]map[int]string) {
fmt.Printf("superMap of user is %v \n", superMap["user"])
cnt := len(superMap["user"])
if cnt > 1 {
fmt.Printf("expected only one value received %v", cnt)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论