本文最初发表在我的个人博客,查看原文,获得更好的阅读体验
与大多数语言不同,Go中没有do或while循环,只有一个简单通用的for循环;for循环有四种写法,其中只有第一种需要分号:
基本的 for 循环由三部分组成,它们用分号隔开: 初始化语句:在第一次迭代前执行 条件表达式:在每次迭代前求值 后置语句:在每次迭代的结尾执行
初始化语句通常为一句短变量声明,该变量声明仅在for语句的作用域中可见。
一旦条件表达式的布尔值为false,循环迭代就会终止。
注意:和 C、Java、JavaScript 之类的语言不同,Go 的 for 语句后面的三个构成部分外没有小括号, 大括号{ }则是必须的。
简短声明可以很容易地在循环中声明索引变量:
package main import "fmt" func main() { sum := 0 for i := 0; i < 10; i++ { sum += i } fmt.Println(sum) }初始化语句和后置语句是可选的:
package main import "fmt" func main() { sum := 1 for ; sum < 1000; { sum += sum } fmt.Println(sum) }此时可以去掉分号,相当于C和Java中的 while 循环:
package main import "fmt" func main() { sum := 1 for sum < 1000 { sum += sum } fmt.Println(sum) }如果省略循环条件,该循环就不会结束,因此无限循环可以写得很紧凑。
package main import "fmt" func main() { for { fmt.Println("这是一个无限循环") } }上述示例还可以写成如下,但没必要:
package main import "fmt" func main() { for true { fmt.Println("这是一个无限循环") } }另外,针对数组(array),切片(slice),字符串(string),映射(map),或者从信道(channel)中读取数据,Go还提供了for-range循环,方便迭代元素:
类似于Java中的for-each循环
对于映射:
for key, value := range oldMap { newMap[key] = value }对于数组:
for index, value := range oldArr { newArr[index] = value }示例:
package main import "fmt" func main() { m := map[string]int{ "x": 1, "y": 2, } fmt.Println("映射m:") for k, v := range m { fmt.Printf("%v=%v\n", k, v) } arr := [3]int{2, 3, 5} fmt.Println("数组arr:") for i, v := range arr { fmt.Printf("i%v=%v\n", i, v) } }输出:
映射m: x=1 y=2 数组arr: i0=2 i1=3 i2=5如果只需要range中的第一项(键或索引)去掉第二项即可:
for key := range m { if key != "" { delete(m, key) } }如果只需要range中的第二项(值),可以使用空白标识符(下划线_)丢弃第一项:
sum := 0 for _, value := range array { sum += value }对于字符串,for-range就更有用了,通过解析UTF-8来分解单个Unicode码点,错误的编码会占用一个字节,并使用符文(rune)U+FFFD替换,rune(同时也是内置类型)是Go中关于单个Unicode码点的术语
for pos, char := range "日本\x80語" { // \x80 is an illegal UTF-8 encoding fmt.Printf("character %#U starts at byte position %d\n", char, pos) }会输出:
character U+65E5 '日' starts at byte position 0 character U+672C '本' starts at byte position 3 character U+FFFD '�' starts at byte position 6 character U+8A9E '語' starts at byte position 7Go没有逗号运算符,,而且++,--是语句而不是表达式。因此如果你想在for循环中运行多个变量,需要使用平行赋值:
// Reverse a for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 { a[i], a[j] = a[j], a[i] }参考: https://golang.org/doc/effective_go.html#for https://golang.org/ref/spec#For_statements