GO语言for range 在数组和切片中的使用
程序员文章站
2022-06-03 08:38:10
...
for range能完成数据的迭代,支持字符串、数组、数组指针、切片、字典、通道类型,返回索引、键值数据。再次我们只讨论在数组和切片中的使用。
1.在数组中迭代数据
main(){
numbers:=[6]int{1,2,3,4,5,6}
for i,v:= range numbers{
fmt.Printf("%X %X %v %v\n",&i,&v,i,v)
v++
}
fmt.Println(numbers)
}
输出
C00000A0C0 C00000A0C8 0 1
C00000A0C0 C00000A0C8 1 2
C00000A0C0 C00000A0C8 2 3
C00000A0C0 C00000A0C8 3 4
C00000A0C0 C00000A0C8 4 5
C00000A0C0 C00000A0C8 5 6
[1 2 3 4 5 6]
细心的同学可能发现了,索引和值的地址都没有变化,定义的局部变量会被重复使用。而且局部变量的改变,并不会修改原变量的值。尽管v自增了,但是原数组还是没变。
2.range会复制目标数据
main(){
data1:=[5]int{1,2,3,4,5}
for i,v:= range data1{ //i,v会从data1复制品中取值
if i==0 {
data1[0] += 100
data1[1] += 200
data1[2] += 300
}
fmt.Printf("v:%d,data1:%d\n",v,data1[i])
}
fmt.Println("----------------")
data2:=[]int{1,2,3,4,5}
for i,v:= range data1{ //仅复制slice,不包括底层数组,i,v会从复制出来的切片中取值
if i==0 {
data2[0] += 100
data2[1] += 200
data2[2] += 300
}
fmt.Printf("v:%d,data2:%d\n",v,data2[i])
}
}
以上会输出
v:1,data1:101
v:2,data1:202
v:3,data1:303
v:4,data1:4
v:5,data1:5
----------------
v:101,data2:101
v:202,data2:202
v:303,data2:303
v:4,data2:4
v:5,data2:5
在range开始迭代时,会拷贝一个副本,对数组来说,修改原数组不会修改被迭代的数组,而对切片来说,range拷贝的切片和原切片都指向同一底层数组,所以修改了原切片也会影响迭代的切片。
3.如果range目标表达式是函数调用,也仅被执行一次
main(){
for i,v:=range data(){
fmt.Println(i,v)
}
}
func data()[]int {
fmt.Println("origin data")
return []int{1,2,3}
}
输出
origin data
0 1
1 2
2 3
上一篇: Go切片中两个冒号的理解
下一篇: servlet的执行原理与生命周期