传递地址
var all []*Item
var items []Item = []Item{{id: 1, name: "a"}, {id: 2, name: "b"}}
for _, item := range items {
all = append(all, &item)
}
fmt.Println(all)
//最后结果为{2,b} {2,b}
变量item的地址在他被声明的时候就已经确定,for循环中item不会在每次循环时重新定义,所以3次for循环里的item指向同一个地址
后续每次for循环item的地址不变,但是值会发生变化,所以all最后存入的值在for循环结束后全都变为items最后一个元素。
传递值
var all []Item
var items []Item = []Item{{id: 1, name: "a"}, {id: 2, name: "b"}}
for _, item := range items {
all = append(all, item)
}
fmt.Println(all)
//最后结果为{1,a} {2,b}
item以值的形式传入到all中,每次for循环item都会被赋一个新的值,所以最后结果符合预期。
for循环下的协程
var add []int
for _, value := range []int{1, 2, 3, 4, 5, 6} {
go func() {
add = append(add, value)
}()
}
time.Sleep(time.Millisecond * 1000)
fmt.Println(add)
//结果为[5 6 6 6 6]、[3 3 6 6 6 6]等情况
for循环在协程初始化之前就已经循环若干次,此时value = 3或者5等等,所以协程append到add中值为上面的情况
time.Sleep(time.Millisecond * 1000)用来阻塞进程退出。
for循环闭包
//闭包
func main() {
var prints []func()
for _, v := range []int{1, 2, 3} {
prints = append(prints, func() { fmt.Println(v) })
}
for _, print := range prints {
print()
}
//最后结果均为3
}
闭包指的是一个函数和与其相关的引用环境组合而成的实体,这里的v也是以指针的方式传递进闭包函数,所以传入的v在for循环结束后都变为3(错误猜想)
闭包函数只是打印变量v的值,v并没有传参到闭包函数中。所以for循环结束后,v为3,打印结果均为3。