range
Golang range類似迭代器操作,返回 (索引, 值) 或 (鍵, 值)。
for 循環的 range 格式可以對 slice、map、數組、字符串等進行迭代循環。格式如下:
for key, value := range oldMap {
newMap[key] = value
}
1st value | 2nd value | ||
---|---|---|---|
string | index | s[index] | unicode, rune |
array/slice | index | s[index] | |
map | key | m[key] | |
channel | element |
可忽略不想要的返回值,或 "_"
這個特殊變量。
package main
func main() {
s := "abc"
// 忽略 2nd value,支持 string/array/slice/map。
println("忽略 2nd value,支持 string/array/slice/map")
for i := range s {
println(s[i])
}
// 忽略 index。
println("忽略 index")
for _, c := range s {
println(c)
}
// 忽略全部返回值,僅迭代。
println("忽略全部返回值,僅迭代")
for range s {
}
m := map[string]int{"a": 1, "b": 2}
// 返回 (key, value)。
println("map返回 (key, value)")
for k, v := range m {
println(k, v)
}
// 返回結果
//忽略 2nd value,支持 string/array/slice/map
//97
//98
//99
//忽略 index
//97
//98
//99
//忽略全部返回值,僅迭代
//map返回 (key, value)
//a 1
//b 2
}
注意,range 會複製對象。
package main
import "fmt"
func main() {
a := [3]int{0, 1, 2}
for i, v := range a { // index、value 都是從複製品中取出。
if i == 0 { // 在修改前,我們先修改原數組。
a[1], a[2] = 999, 999
fmt.Println(a) // 確認修改有效,輸出 [0, 999, 999]。
}
a[i] = v + 100 // 使用複製品中取出的 value 修改原數組。
}
fmt.Println(a) // 輸出 [100, 101, 102]。
}
輸出結果:
[0 999 999]
[100 101 102]
建議改用引用類型,其底層數據不會被複制。
package main
func main() {
s := []int{1, 2, 3, 4, 5}
for i, v := range s { // 複製 struct slice { pointer, len, cap }。
if i == 0 {
s = s[:3] // 對 slice 的修改,不會影響 range。
s[2] = 100 // 對底層數據的修改。
}
println(i, v)
}
}
另外兩種引用類型 map、channel 是指針包裝,而不像 slice 是 struct。
for 和 for range有什麼區別?
主要是使用場景不同
for可以
遍歷array和slice
遍歷key爲整型遞增的map
遍歷string
for range可以完成所有for可以做的事情,卻能做到for不能做的,包括
遍歷key爲string類型的map並同時獲取key和value
遍歷channel
循環控制Goto、Break、Continue
循環控制語句
循環控制語句可以控制循環體內語句的執行過程。
GO 語言支持以下幾種循環控制語句:
1.1.1. Goto、Break、Continue
- 三個語句都可以配合標籤(label)使用
- 標籤名區分大小寫,定以後若不使用會造成編譯錯誤
- continue、break配合標籤(label)可用於多層循環跳出
- goto是調整執行位置,與continue、break配合標籤(label)的結果並不相同
參考鏈接: