1、for range指针赋值
Ops的数据保存在两个表中,一个是ops_tab,另一个是staff_tab,其中ops_tab的staff_id是staff_tab的外键,两个表都有staff_id字段。
type OpsDetail struct {
OpsId string
StaffId string
Ops *model.OpsTab
Staff *model.StaffTab
}
现要写一个方法将两个表关联起来,保存到上面那个结构体
opsId2OpsDetailMap := make(map[string]*OpsDetail)
for _, ops := range opsList {
opsId2OpsDetailMap[ops.OpsId] = &OpsDetail{
OpsId: ops.OpsId,
Ops: &ops,
StaffId: ops.StaffId,
Staff: nil,
}
staffIdSet.Add(ops.StaffId)
}
staffId2StaffMap := make(map[string]*model.StaffTab)
for _, staff := range staffList {
staffId2StaffMap[staff.StaffId] = &staff
}
这两段代码有看出来什么问题吗?
解
问题出在图中那两个框里,每一次循环后面的ops就会覆盖这个值,最后OpsDetail所有的Ops指针指向最后一个Ops。
期望:
现实:
如何修改
for idx := range opsList {
ops := opsList[idx]//设置临时变量
opsId2OpsDetailMap[ops.OpsId] = &OpsDetail{
OpsId: ops.OpsId,
Ops: &ops,
StaffId: ops.StaffId,
Staff: nil,
}
}
2、for range闭包
这个类似第一个
s := []string{"1", "2", "3"}
for _, v := range s {
go func() {
println(v)
}()
}
结果:
3
3
3
分析:
for循环执行速度很快,携程都还没跑起来就已经循环结束了,指针指向最后一个元素
3、for range非指针赋值
s := []Info{
Info{
Name: "test",
},
}
for _, v := range s {
v.Name = "new"
}
fmt.Println(s[0].Name)
结果:test
分析:
在for多次循环中,value是值赋值的方式。因此上面的for _, v := range s 过程中,其实是针对于每个Info的结构体,赋值了一份给了变量v。 因此,修改v的Name属性,并不会影响原有切片中的元素的值得。
如何解决:
for i := range s {
s[i].Name = "newvalue"
}
4、for循环遍历更新slice不会改变运行次数
s := []int{1, 2}
for i := range s {
fmt.Println(i)
s = append(s, i)
}
fmt.Println(s)
输出:
1
2
[1 2 0 1]
最好不要一边遍历一边修改。