我很难理解下面的代码,虽然可以正常工作,但仍然不明白。
如果有人可以揭开它的神秘面纱,那将真的很有帮助
在下面的代码中,标记名称未更新为“已更改”。
package main
import "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 main
import "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])
}
我敢肯定,我的困惑可能微不足道,但这浪费了我几个小时
最佳答案
在您的第一个版本中,当您这样做时:
for _, flg := range cmd.Flags {
flg.Name = "Changed"
}
flg
是Flag
类型的局部变量。在for
循环的每次迭代中,range
将flg
设置为cmd.Flags
中下一项的副本。因此,当您更改它时,该循环之外没有任何更改。在第二个版本中,当您执行该循环时,
flg
是*Flag
类型的局部变量,因此当range将其设置为cmd.Flags
中下一个项目的副本时,flg
指向您要进行突变的数据,并对其进行突变。实际更改该数据。