0

用于范围:

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
}

这是为什么?我认为在此处添加帐户结构详细信息没有任何价值

4

3 回答 3

1

我想说,这个问题超越了 Golang,它与底层数据结构或容器有关。在第二种情况下,您似乎已经知道容器“len(accounts)”的长度,因此它是一个可以按顺序访问的固定存储。不必总是如此。如果帐户是一个不断增加(或减少)的容器怎么办?你会如何取那个容器的长度。相反,您要问的只是“帐户”中的任何内容都可以给我。你打算怎么做?好吧,您设置了一个虚拟变量,它只允许访问或模仿容器的内容(因此带有它的所有属性或“结构字段”)。另外,它可以在后续代码中抛出,

于 2020-05-05T04:27:21.300 回答
1

在 form 的 for 循环中for i,v:=range slice {...},变量v与它循环的元素具有相同的类型,并且每次迭代都将下一项的内容从 slice/map 复制到v。因此,如果v是一个结构并且您为结构成员分配值,则这些成员永远不会复制回它从中复制的切片中。如果切片是指向结构的指针切片,则v是指向结构的指针的副本,并且您对v的成员所做的更改将反映在原始切片元素上。解决此问题的一种方法是使用索引:

for i:=range accounts {
   accounts[i].Field=value
}
于 2020-05-05T04:25:57.757 回答
0

每当您在 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
}

您没有为帐户中的元素制作本地副本,而是通过帐户[i]直接访问它们,它将更新帐户切片。

如果您仍想使用范围,那么您可以通过仅使用索引来实现。

for i := range accounts{
       accDetails, _ := repo.GetAccountDets(ctx, accounts[i].number, accounts[i].status)
       accounts[i].Details = *accDetails
}
于 2020-05-05T04:28:10.807 回答