Golang——for循环的两种用法
PS,作者写的简单易懂明确。只是讲 go 的二种 for 循环。
06 August 2014
一般语言都支持两种遍历方式,这里做下介绍。最后介绍一个 For Range 不恰当的使用引起的 Bug。
从大一开始学C++,所接触过的for
循环只有一种方式,for (int i = 0; i < count; i++) {...}
。后来接触了Java,知道Java 5 引入了一种新特性,可以通过for (a : aa)
遍历整个数组。虽然知道,但是也没用过,因为之前那种方法足够了。
现在主力语言是Go。Go也支持传统的写法for i := 0; i < count; i++ {...}
。同样,还有一种for i, a := range aa {...}
。这个跟Java相比,除了能够遍历,还能得到当前遍历的索引值,所以在Go中,更倾向于后面这种方法,灵活度更高。
今天要对一个数据进行遍历,对每个元素进行稍加修改,才发现,原来这两种方式是有很大区别的。当时使用第二种方式修改之后,一直发现没有修改成功。后来进过调试,才发现是for
循环的问题。
测试代码在这里
a := []string{}
a = append(a, "hello")
a = append(a, ", ")
a = append(a, "world")
fmt.Println(a)
for i := 0; i < len(a); i++ {
fmt.Println(&a[i])
}
for _, aa := range a {
aa += "@"
fmt.Println(&aa)
}
for i := 0; i < len(a); i++ {
a[i] += "@"
fmt.Println(&a[i])
}
fmt.Println(a)
通过range
方式获得的变量,打印出它的地址,和之前的数组a
的地址相比,是不同的地址。
[hello , world]
0x10322280
0x10322288
0x10322290
0x1030e100
0x1030e100
0x1030e100
0x10322280
0x10322288
0x10322290
[hello@ , @ world@]
这里就可以证明,通过range
方式获得的变量,和a[i]
变量是不同的,只是里面存的值一样而已。所以,如果做出了修改操作,也不会修改到原来的数组。
果断再去看一下大Java的语法。结果也是一样的。
class TestFor {
public static void main(String[] args) {
String[] a = {"hello", ", ", "world"};
System.out.println(a[0] + a[1] + a[2]);
for (String aa : a) {
aa += "@";
}
System.out.println(a[0] + a[1] + a[2]);
}
}
如果遍历数组,还需要对数组元素进行操作,建议用传统for循环因为可以定义角标通过角标操作元素。如果只为遍历获取,可以简化成高级for循环,它的出现为了简化书写。
传统的for
,写起来不太方便,但是功能强大;如果只是单纯得遍历,可以使用新的写法,简化代码。