For loop 为什么正常for循环允许为结构字段赋值,而for范围不允许';你不在戈兰工作吗?

For loop 为什么正常for循环允许为结构字段赋值,而for范围不允许';你不在戈兰工作吗?,for-loop,go,range,for-range,For Loop,Go,Range,For Range,用于范围: for _, acc := range accounts{ accDetails, _ := repo.GetAccountDets(ctx, acc.number, acc.status) acc.Details = *accDetails } 上面的那个不行 但是,下面的方法是有效的 for i:=0; i < len(accounts); i++ { accDetails, _ := repo.GetAccountDets(

用于范围:

for _, acc := range accounts{
        accDetails, _ := repo.GetAccountDets(ctx, acc.number, acc.status)
        acc.Details = *accDetails
}
上面的那个不行

但是,下面的方法是有效的

for i:=0; i < len(accounts); i++ {
       accDetails, _ := repo.GetAccountDets(ctx, accounts[i].number, accounts[i].status)
       accounts[i].Details = *accDetails
}
i:=0的
;i
为什么呢?
我不认为在这里添加account struct details在形式为
for I,v:=range slice{…}
的for循环中有任何值,变量
v
与它循环的元素类型相同,每次迭代都将下一个项的内容从slice/map复制到
v
。因此,如果
v
是一个结构,并且您将值分配给结构成员,那么这些值永远不会复制回它所复制的切片中。 如果切片是指向结构的指针切片,则
v
是指向结构的指针的副本,您对
v
的成员所做的更改将反映在原始切片元素上。 解决此问题的一种方法是使用索引:

for i:=range accounts {
   accounts[i].Field=value
}

我想说的是,这个问题超出了Golang,它与底层数据结构或容器有关。在第二种情况下,您似乎已经知道容器“len(accounts)”的长度,因此它是可以顺序访问的固定存储。不一定总是这样。如果帐户是一个不断增加(或减少)的容器,该怎么办?你认为那个容器的长度是多少。取而代之的是,你所要问的是“账户”里有什么内容,就给我吧。你打算怎么做?好的,您设置了一个虚拟变量,它只允许访问或模拟容器的内容(因此携带所有属性或“结构字段”)。另外,它可能会在后续代码中抛出,并适当考虑作用域,用于“只读”目的。

每当您在for循环中初始化变量时,该变量的局部作用域仅限于for循环,在范围内,您将在acc变量中创建元素的副本

for _, acc := range accounts{
        accDetails, _ := repo.GetAccountDets(ctx, acc.number, acc.status)
        acc.Details = *accDetails
}
acc只是账户中元素的本地副本,如果在acc中添加任何内容,则不会影响账户切片

但在你的另一个例子中

for i:=0; i < len(accounts); i++ {
       accDetails, _ := repo.GetAccountDets(ctx, accounts[i].number, accounts[i].status)
       accounts[i].Details = *accDetails
}

第一个赋值给局部变量
acc
。第二个指定给slice元素。回答你的问题了吗?@CeriseLimón那么,有没有办法分配使用范围循环,或者根本没有办法?
对于i,acc:=范围帐户{…帐户[i]。详细信息=*accDetails}
@CeriseLimón你首先回答的。如果你把它作为一个答案,我会选择它。@sofs1请注意,下面的答案和一些重复的答案似乎暗示,由于省略,不可能在
范围
循环中直接使用
来修改其内容,只有在处理非指针值时才是如此。如果
帐户
切片/数组/通道/映射包含指针,则可以直接通过迭代变量修改各个值,而无需使用索引。
for i := range accounts{
       accDetails, _ := repo.GetAccountDets(ctx, accounts[i].number, accounts[i].status)
       accounts[i].Details = *accDetails
}