我的代码循环遍历-S
数组,并创建一个包含字符串键和Task
值的Map:
Task
此代码的输出如下:
package main
import (
"fmt"
)
type Task struct {
Name string
Project string
}
func main() {
taskMap := map[string]*Task{}
taskList := []Task{
{
Name: "name1",
Project: "project1",
},
{
Name: "name2",
Project: "project2",
},
{
Name: "name3",
Project: "project3",
},
}
for _, task := range taskList {
taskMap[task.Name] = &task
}
// Print results
for k, v := range taskMap {
fmt.Println(k, v)
}
}
这不是我的预期,因为它每次都打印相同。我对这里发生了什么有一点线索,因为如果我用以下代码替换循环,它会按预期工作:
name1 &{name3 project3}
name2 &{name3 project3}
name3 &{name3 project3}
所以不知何故,对上次访问的任务的引用显然是存储在for _, task := range taskList {
taskMap[task.Name] = &Task{
Name: task.Name,
Project: task.Project,
}
}
的每个键中的任务。
有没有办法在不借助手动复制每个字段的情况下执行此操作?
答案 0 :(得分:5)
您获得所有密钥的相同值,因为您在into_inner
循环中引用了相同的task
变量。使用以下代码段来获取对切片中项目的引用。
for
BTW(浅)复制变量,您可以将其分配给新变量,如
for idx, task := range taskList {
taskMap[task.Name] = &taskList[idx]
}
将在每次迭代中创建一个新的for _, task := range taskList {
x := task
taskMap[task.Name] = &x
}
变量,并在地图中使用指向该变量的指针。
答案 1 :(得分:0)
您正在存储task
的地址而不是值。
您可以改为将taskList
切换为一片指针:taskList := []*Task{
并使用taskMap[task.Name] = task
。