Go 語(yǔ)言中的 range
在線程不安全的 map 中我們學(xué)習(xí)了 map 的遍歷,里面使用了一個(gè)叫?range?的關(guān)鍵字來(lái)對(duì) map 進(jìn)行遍歷操作。當(dāng)時(shí)還提到了切片和數(shù)組都可以使用這個(gè)方法遍歷。本文就來(lái)詳細(xì)學(xué)習(xí)一下?range?關(guān)鍵字的用法。
Tips:本文提及的 map 均是線程不安全的 map。線程安全的 map 及其遍歷方法參照 Go 語(yǔ)言中的map 一文。
1. 基本用法
range?可以用來(lái)遍歷的對(duì)象有數(shù)組、切片、map、字符串以及通道。遍歷的對(duì)象不同,range?的返回值也會(huì)有所不同。遍歷數(shù)組、切片和字符串時(shí),它返回的就是數(shù)據(jù)的索引和值。遍歷map時(shí)返回的就是map的key和value。而遍歷通道時(shí)則只返回通道中的數(shù)據(jù)。
代碼示例:
- 1?
package main
- 2
- 3?
import (
- 4? ? ? ?
"fmt"
- 5?
)
- 6
- 7?
func main() {
- 8? ? ? ? ?
str := "Codey"
- 9? ? ? ? ?
intArray := [5]int{1, 2, 3, 4, 5}
- 10? ? ? ?
intSlice := []int{1, 2, 3, 4, 5}
- 11? ? ? ?
m := map[string]string{"Apple": "蘋(píng)果", "Orange": "橘子", "Banana": "香蕉"}
- 12? ? ? ?
c := make(chan int, 10)
- 13? ? ? ?
c <- 10
- 14? ? ? ?
c <- 11
- 15? ? ? ?
c <- 12
- 16? ? ? ?
c <- 13
- 17? ? ? ?
c <- 14
- 18? ? ? ?
fmt.Println("---字符串的遍歷---")
- 19? ? ? ?
//遍歷字符串
- 20? ? ? ?
for k, v := range str {
- 21? ? ? ? ? ? ? ?
fmt.Printf("索引:%d,值:%cn", k, v)
- 22? ? ? ?
}
- 23? ? ? ?
fmt.Println("---數(shù)組的遍歷---")
- 24? ? ? ?
//遍歷數(shù)組
- 25? ? ? ?
for k, v := range intArray {
- 26? ? ? ? ? ? ? ?
fmt.Printf("索引:%d,值:%dn", k, v)
- 27? ? ? ?
}
- 28? ? ? ?
fmt.Println("---切片的遍歷---")
- 29? ? ? ?
//遍歷切片
- 30? ? ? ?
for k, v := range intSlice {
- 31? ? ? ? ? ? ? ?
fmt.Printf("索引:%d,值:%dn", k, v)
- 32? ? ? ?
}
- 33? ? ? ?
fmt.Println("---map的遍歷---")
- 34? ? ? ?
//遍歷map
- 35? ? ? ?
for k, v := range m {
- 36? ? ? ? ? ? ? ?
fmt.Printf("key:%s,value:%sn", k, v)
- 37? ? ? ?
}
- 38? ? ? ?
fmt.Println("---通道的遍歷---")
- 39? ? ? ?
//遍歷通道
- 40? ? ? ?
for v := range c {
- 41? ? ? ? ? ? ? ?
fmt.Printf("值:%dn", v)
- 42? ? ? ? ? ? ? ?
if len(c) == 0 {
- 43? ? ? ? ? ? ? ? ? ? ? ?
break
- 44? ? ? ? ? ? ? ?
}
- 45? ? ? ?
}
- 46?
}
執(zhí)行結(jié)果:
若是在開(kāi)發(fā)過(guò)程中只想用到遍歷對(duì)象的索引或者值,比如說(shuō)一個(gè)map以汽車的車牌號(hào)為key存儲(chǔ)了一些汽車的信息,但是你只想要操作車牌號(hào)。可以使用_
來(lái)接收不需要使用的值。如果是只想用索引的話,可以直接只用一個(gè)參數(shù)接收遍歷對(duì)象傳出的值,默認(rèn)只會(huì)接收索引。
代碼示例:
- 1?
package main
- 2
- 3?
import (
- 4? ? ? ? ?
"fmt"
- 5?
)
- 6
- 7?
func main() {
- 8
- 9? ? ? ? ?
m := map[string]string{"Apple": "蘋(píng)果", "Orange": "橘子", "Banana": "香蕉"}
- 10? ? ? ?
fmt.Println("---map的key值---")
- 11? ? ? ?
//只取key
- 12? ? ? ?
for k := range m {
- 13? ? ? ? ? ? ? ?
fmt.Printf("key:%sn", k)
- 14? ? ? ?
}
- 15? ? ? ?
fmt.Println("---map的value值---")
- 16? ? ? ?
//只取value
- 17? ? ? ?
for _, v := range m {
- 18? ? ? ? ? ? ? ?
fmt.Printf("value:%sn", v)
- 19? ? ? ?
}
- 20 ?
}
執(zhí)行結(jié)果:
2. 注意事項(xiàng)
在使用 range 的時(shí)候需要注意,我們無(wú)法通過(guò)range輸出的值來(lái)修改遍歷的對(duì)象,因?yàn)閞ange相當(dāng)于聲明了兩個(gè)變量,這兩個(gè)變量逐一復(fù)制了遍歷對(duì)象中的值,歸根結(jié)底還是因?yàn)?Go 語(yǔ)言只有值傳遞,沒(méi)有引用傳遞。
代碼示例:
- 1?
package main
- 2
- 3?
import (
- 4? ? ? ? ?
"fmt"
- 5?
)
- 6
- 7?
func main() {
- 8
- 9? ? ? ? ??
intSlice := []int{1, 2, 3, 4, 5}
- 10
- 11? ? ? ??
//遍歷切片
- 12? ? ? ?
for k, v := range intSlice {
- 13? ? ? ? ? ? ?
fmt.Printf("索引:%d,索引地址:%pn", k, &k)
- 14? ? ? ? ? ? ? ?
fmt.Printf("值:%d,值地址:%pn", v, &v)
- 15? ? ? ? ?
}
- 16?
}
執(zhí)行結(jié)果:
3. 小結(jié)
本文主要介紹了 Go 語(yǔ)言中?range?關(guān)鍵字的用法,Go語(yǔ)言中可以 range 的對(duì)象有:字符串、數(shù)組、切片、map 和通道。其中用于接收 range 出來(lái)的值的變量是一個(gè)/兩個(gè)不斷被賦值的變量,所以這些變量的修改無(wú)法影響到正在被遍歷的對(duì)象本身。
文章來(lái)源于網(wǎng)絡(luò),侵刪!