Go 学习笔记(9)— 循环(for、for range访问数组、切片、字符串和通道、goto、continue、break)
1. for 循環格式
Go 語言僅支持一種循環語句即 for 循環,它有 3 種形式,只有其中的一種使用分號。
- 和 C 語言的 for 一樣
for init; condition; post { }
init : 一般為賦值表達式,給控制變量賦初值,初始語句是在第一次循環前執行的語句,一般使用初始語句執行變量初始化,如果變量在此處被聲明,其作用域將被局限在這個 for 的范圍內。
condition : 關系表達式或邏輯表達式,循環控制條件,每次循環開始前都會計算條件表達式,如果表達式為 true,則循環繼續,否則結束循環,條件表達式可以被忽略,忽略條件表達式后默認形成無限循環。
post: 一般為賦值表達式,給控制變量增量或減量;
可以看到比較大的一個不同在于 for 后面的條件表達式不需要用圓括號()括起來。左花括號{必須與 for 處于同一行。
Go 語言中的 for 循環與 C 語言一樣,都允許在循環條件中定義和初始化變量,唯一的區別是, Go 語言不支持以逗號為間隔的多個賦值語句,必須使用平行賦值的方式來初始化多個變量。
示例-1:
var i intfor ; ; i++ {if i > 10 {break}
}
- 和
C的while一樣
for condition { }
示例-2
var i int
for i <= 10 {i++
}
- 和
C的for(;;)一樣,無限循環
for { }
示例-3
var i intfor {if i > 10 {break}i++
}
2. for 循環示例
package mainimport "fmt"func main() {var b int = 15var a intnumbers := [6]int{1, 2, 3, 5} /* for 循環 */for a := 0; a < 10; a++ { // 左花括號{必須與 for 處于同一行fmt.Printf("a 的值為: %d\n", a)}for a < b {a++fmt.Printf("a 的值為: %d\n", a)}for i, x:= range numbers {fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)}
}
3. 嵌套 for 循環
package mainimport "fmt"func main() {/* 定義局部變量 */var i, j intfor i=2; i < 100; i++ {for j=2; j <= (i/j); j++ {if(i%j==0) {break; // 如果發現因子,則不是素數}}if(j > (i/j)) {fmt.Printf("%d 是素數\n", i);}}
}
4. for 循環應用
Go 語言中 range 關鍵字用于 for 循環中迭代數組 (array)、切片(slice)、通道(channel)或集合 (map) 的元素。通過 for range 遍歷的返回值有一定的規律:
- 數組、切片、字符串返回索引和值。
map返回鍵和值。- 通道(
channel)只返回通道內的值。
4.1 訪問數組
for index , value :=range arry{}
for index := range arry{}
for _, value :=range arry{}
在上面的例子中將 key 變成了下劃線_,這里的下劃線就是匿名變量。
- 可以理解為一種占位符
- 匿名變量本身不會進行空間分配,也不會占用一個變量的名字
- 在
for range可以對key使用匿名變量,也可以對value使用匿名變量
package mainimport "fmt"func main() {array := [3]int{10, 20, 30}for i, v := range array {fmt.Printf("index is %v, value is %v\n", i, v)}for _, v := range array {fmt.Printf("value is %v\n", v)}for i := range array {fmt.Printf("index is %v\n", i)}
}
輸出:
index is 0, value is 10
index is 1, value is 20
index is 2, value is 30
value is 10
value is 20
value is 30
index is 0
index is 1
index is 2
4.2 訪問切片
for index, value :=range slice{}
for index := range slice{}
for _, value :=range slice{}
代碼演示和數組類似,只需要做如下改動:
array := [3]int{10, 20, 30} // 數組
array := []int{10, 20, 30} // 切片
4.3 訪問字典
對于 map 類型來說,for range 遍歷時, key 和 value 分別代表 map 的索引鍵 key 和索引對應的值,一般被稱為 map 的鍵值對,因為它們是一對一對出現的。
for key , value := range map{}
for key := range map {}
4.4 訪問字符串
range 也可以用來枚舉 Unicode 字符串。第一個參數是字符的索引,第二個是字符(Unicode的值)本身。
for index, value := range string
for index := range string
示例:
package mainimport "fmt"func main() {s := "hello"for i := range s {fmt.Printf("value is %v\n", s[i])}
}
4.5 訪問通道
for range 可以遍歷通道( channel ),但是通道在遍歷時,只輸出一個值,即管道內的類型對應的數據。
for value :=range channel{}
代碼示例:
c := make(chan int)go func() {c <- 1c <- 2c <- 3close(c)
}()for v := range c {fmt.Println(v)
}
4. 循環控制語句
4.1 goto
goto 語句用于函數的內部的跳轉,需要配合標簽一起使用, 具體的格式如下:
goto Lable
goto Lable 的語義是跳轉到標簽名后的語句處執行, goto 語句有以下幾個特點:
goto語句只能在函數內跳轉;goto語句不能跳過內部變量聲明語句,這些變量在goto語句的標簽語句處又是可見的;
goto L // BAD ,跳過v := 3 這條語句是不允許的v := 3
L :
goto語句只能跳到同級作用域或者上層作用域內,不能跳到內部作用域內;
if n%2 == 1 {goto LL
}
for n > 0 {f()n--
LL:f()n--
}
代碼示例:
package mainimport "fmt"func main() {for x := 0; x < 10; x++ {for y := 0; y < 10; y++ {if y == 2 {// 跳轉到標簽goto breakHere}}}// 手動返回, 避免執行進入標簽return// 標簽
breakHere:fmt.Println("done")
}
4.2 continue
跳過當前循環的剩余語句,僅能用于 continue 語句,然后繼續進行下一輪循環,有兩種格式:
-
單獨使用,用于跳出
continue當前所在的for循環的本次迭代; -
和標簽一起使用,用于跳出標簽所標識的
for語句的本次選代,但標簽和continue必須在同一個函數內。
例如:
package mainimport "fmt"func main() {OuterLoop:for i := 0; i < 2; i++ {for j := 0; j < 5; j++ {switch j {case 2:fmt.Println(i, j)continue OuterLoop}}}}
4.3 break
break 用于函數內跳出 for 、 switch 、 select 語句的執行,有兩種使用格式:
-
單獨使用,用于跳出
break當前所在的for、switch、select語句的執行; -
和標簽一起使用,用于跳出標簽所標識的
for、switch、select語句的執行,可用于跳出多重循環,但標簽和break必須在同一個函數內。
例如:
package mainimport "fmt"func main() {Ll:for i := 0; ; i++ {for j := 0; ; j++ {if i >= 5 {// 跳到 Ll 標簽所在的 for 循環 i++ 處執行fmt.Println(i)break Ll//the following is not executed}if j > 10 {fmt.Println(j)// 默認僅跳到離 break 最近的內層循環 j++ 處執行break}}}}
不帶 label 的 break 語句中斷執行并跳出的,是同一函數內 break 語句所在的最內層的 for、switch 或 select。
func main() {var sl = []int{5, 19, 6, 3, 8, 12}var firstEven int = -1// find first even number of the interger slice
loop:for i := 0; i < len(sl); i++ {switch sl[i] % 2 {case 0:firstEven = sl[i]break loopcase 1:// do nothing}}println(firstEven) // 6
}
我們定義了一個 label:loop,這個 label 附在 for 循環的外面,指代 for 循環的執行。當代碼執行到break loop 時,程序將停止 label loop 所指代的 for 循環的執行。
總結
以上是生活随笔為你收集整理的Go 学习笔记(9)— 循环(for、for range访问数组、切片、字符串和通道、goto、continue、break)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Go 学习笔记(8)— 条件语句(if、
- 下一篇: 买过岭南万应薄荷活络膏的人有吗?怎么样啊