欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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