【Go】for range语法糖
语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。
举个例子:在 C 语言里用 a[i] 表示 *(a+i),用 a[i][j] 表示 *(*(a+i)+j),由此可见语法糖不是“现代语言”独有,这种写法简洁明了,易于理解。
内存地址即 内存值所在的内存空间的编号(下简称地址)
首先,我们先来看go语言中的for循环:
for i := 0; i< 10; i++ {
//……
}
基本流程:
再看看go中for range的写法:
ints = []int{1,2,3}
//index为索引下标,vaule为
for index,value := range ints {
//fmt.Println(index,value)//不使用index和vaule会报错
}
这里可以简单的理解为for range将一个数组中的索引和值按顺序循环了一次。
执行结果:
0 1
1 2
2 3
但,我感觉go中太安全了!
为什么?
因为go很喜欢值传递。for range结构中也是如此。简单地说,不再是原来的ints数组了,虽然它们的值是相等的,但在for range结构中无法利用返回的index和value值修改原来的数组。
意思是,在for range中操作的index和value其实只是一份原来数组的复制品!看个例子:
ints := []int{1,2,3}
for index,value := range ints {
fmt.Printf("ints[%d]的地址:%p\n",index,&ints[index])
fmt.Printf("第%d个v的地址:%p\n",index,&value)
}
执行结果:
ints[0]的地址:0xc000014180
第0个v的地址:0xc00000a0b8
ints[1]的地址:0xc000014188
第1个v的地址:0xc00000a0b8
ints[2]的地址:0xc000014190
第2个v的地址:0xc00000a0b8
可以看出,for range中value的地址和外部ints数组的地址并不相同,而且,value的地址没有发生变化。
刚才的for range和以下的写法的效果是同等的:
ints = []int{1,2,3}
arrlen := len(ints)
var value interface{}
//这里已经提前确定了for循环的次数,因此在for range中增加被遍历数组长度也没关系
for index:=0; index<arrlen; index++ {
vaule = ints[i]
fmt.Printf("ints[%d]的地址:%p\n",index,&ints[index])
fmt.Printf("第%d个value的地址:%p\n",index,&value)
}
执行结果:
ints[0]的地址:0xc000014180
第0个value的地址:0xc000042240
ints[1]的地址:0xc000014188
第1个value的地址:0xc000042240
ints[2]的地址:0xc000014190
第2个value的地址:0xc000042240
和上面for range的结果基本一致~
到此,我们来总结一下,for range是go的语法糖,使用值拷贝的形式获取到了被遍历数组等结构的索引和值。
所以,如果想要在for range中更改ints的值,可以直接使用ints[i]来进行更改,如下。
ints := []int{1,2,3}
for index,value := range ints {
ints[index] = value+1
}