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
}