Pointers 围棋中的指针混淆
我很难理解下面的代码,我有它的工作,但仍然不理解它。 如果有人能揭开它的神秘面纱,那真的很有帮助 下面的代码标志名称未更新为“已更改” 正确的代码。标志名称更改为“已更改”Pointers 围棋中的指针混淆,pointers,go,Pointers,Go,我很难理解下面的代码,我有它的工作,但仍然不理解它。 如果有人能揭开它的神秘面纱,那真的很有帮助 下面的代码标志名称未更新为“已更改” 正确的代码。标志名称更改为“已更改” 我相信,我的困惑可能微不足道,但在您的第一个版本中,当您这样做时,它浪费了我几个小时的时间: for _, flg := range cmd.Flags { flg.Name = "Changed" } flg是Flag类型的局部变量。在for循环的每次迭代中,range将flg设置为cmd.Flags中下一项的副
我相信,我的困惑可能微不足道,但在您的第一个版本中,当您这样做时,它浪费了我几个小时的时间:
for _, flg := range cmd.Flags {
flg.Name = "Changed"
}
flg
是Flag
类型的局部变量。在for
循环的每次迭代中,range
将flg
设置为cmd.Flags
中下一项的副本。所以当你改变它时,在这个循环之外什么都不会改变
在第二个版本中,当您执行该循环时,
flg
是一个类型为*Flag
的局部变量,因此当range将其设置为cmd.Flags
中下一项的副本时,flg
指向您试图变异的数据,而变异它实际上会更改该数据。在第一个版本中,执行此操作时:
for _, flg := range cmd.Flags {
flg.Name = "Changed"
}
for _, flg := range cmd.Flags {
flg.Name = "Changed"
}
flg
是Flag
类型的局部变量。在for
循环的每次迭代中,range
将flg
设置为cmd.Flags
中下一项的副本。所以当你改变它时,在这个循环之外什么都不会改变
在第二个版本中,当您执行该循环时,flg
是一个类型为*Flag
的局部变量,因此当range将其设置为cmd.Flags
中下一项的副本时,flg
指向您试图变异的数据,而变异它实际上会更改该数据
for _, flg := range cmd.Flags {
flg.Name = "Changed"
}
这部分正是罪魁祸首。range返回的第一个值是索引(此处忽略),第二个值是实际数据的副本。当您在循环中使用它(flg.Name=…)时,您正在将该值分配给副本的Name字段。您可以这样做:
for index, _ := range cmd.Flags {
cmd.Flags[index].Name = "Changed"
}
在第二种情况下,将引用副本(或内存地址)的名称字段指定给标志,因此该内存地址处的值会发生更改
这部分正是罪魁祸首。range返回的第一个值是索引(此处忽略),第二个值是实际数据的副本。当您在循环中使用它(flg.Name=…)时,您正在将该值分配给副本的Name字段。您可以这样做:
for index, _ := range cmd.Flags {
cmd.Flags[index].Name = "Changed"
}
在第二种情况下,您将引用副本(或内存地址)的名称字段分配给标志,因此该内存地址处的值将发生更改。当您在一个切片上进行范围调整时,迭代变量(
flg
在这种情况下)将从切片中分配一个元素副本。修改副本不会修改切片中的原始副本。当您使用指针时,会发生相同的复制,但这一次是指针的复制,原始指针和复制的指针都指向相同的值,并且从任何指针或直接对值所做的任何修改都将对指向该值的任何和所有指针“可见”。当您在一个切片上移动时,迭代变量(flg
在本例中)被分配一个来自切片的元素副本。修改副本不会修改切片中的原始副本。使用指针时,会发生相同的复制,但这次是指针的复制,原始指针和复制的指针都指向相同的值,并且从任何指针或直接对值所做的任何修改都将“可见”指向任何和所有指向该值的指针。因此,如果我使用for循环而不是range,我应该能够在代码版本中不使用它而进行变异?如果我使用for循环而不是range,我应该能够在代码版本中不使用它而进行变异?正确:我认为我的代码中使用循环是错误的。仍在学习go:)正确:我认为在我的代码中使用循环是错误的。还在学习:)