我很难理解下面的代码,我让它工作但仍然不明白。如果有人可以揭开它的神秘面纱,那将非常有帮助在下面的代码中,标志名称未更新为“已更改”package mainimport "fmt"type Command struct { Name string Flags []Flag}type Flag struct { Name string Shorthand string}func getCommand() *Command { return &Command{Name: "Hello", Flags: []Flag{{"version", "v"}}}}func change(cmd *Command) { for _, flg := range cmd.Flags { flg.Name = "Changed" }}func main() { cmd := getCommand() change(cmd) fmt.Println(cmd.Flags[0])}正确的代码。标志名称更改为“已更改”package mainimport "fmt"type Command struct { Name string Flags []*Flag}type Flag struct { Name string Shorthand string}func getCommand() *Command { return &Command{Name: "Hello", Flags: []*Flag{{"version", "v"}}}}func change(cmd *Command) { for _, flg := range cmd.Flags { flg.Name = "Changed" }}func main() { cmd := getCommand() change(cmd) fmt.Println(cmd.Flags[0])}我敢肯定,我的困惑可能是微不足道的,但这浪费了我几个小时
2 回答
牧羊人nacy
TA贡献1862条经验 获得超7个赞
在您的第一个版本中,当您这样做时:
for _, flg := range cmd.Flags {
flg.Name = "Changed"
}
flg是类型的局部变量Flag。在循环的每次迭代中for,range设置flg为 中下一项的副本cmd.Flags。所以当你改变它时,在那个循环之外没有任何变化。
在您的第二个版本中,当您执行该循环时,flg是 type 的局部变量*Flag,因此当 range 将其设置为 in 中下一个项目的副本时cmd.Flags,flg它指向您尝试改变的数据,并且改变它实际上会改变该数据.
不负相思意
TA贡献1777条经验 获得超10个赞
for _, flg := range cmd.Flags {
flg.Name = "Changed"
}
这部分是确切的罪魁祸首。range 返回的第一个值是索引(此处忽略),第二个值是实际数据的副本。当您在循环中使用它时(flg.Name=...),您正在将值分配给副本的名称字段。你可以这样做:
for index, _ := range cmd.Flags {
cmd.Flags[index].Name = "Changed"
}
在第二种情况下,您将引用(或内存地址)副本的名称字段分配给标志,因此该内存地址的值会更改。
- 2 回答
- 0 关注
- 117 浏览
添加回答
举报
0/150
提交
取消