Go 語(yǔ)言的通道
Go 語(yǔ)言中有一個(gè)特殊的類(lèi)型?chan
,這是在 Go 語(yǔ)言的多線程操作中非常重要的一個(gè)數(shù)據(jù)類(lèi)型。它的一般用于線程之間的數(shù)據(jù)傳輸,所以這個(gè)操作類(lèi)型叫做"通道(channel)"。
1. 通道的聲明和定義
通道可以理解為一種特殊的變量,所以它的聲明和其它變量的聲明并沒(méi)有太大的區(qū)別,聲明通道變量的寫(xiě)法如下:
var c chan int //聲明一個(gè)存放int類(lèi)型數(shù)據(jù)的通道
- 1
但是它聲明之后并不能直接使用,需要使用內(nèi)置函數(shù)?make()
?來(lái)創(chuàng)建一下通道變量才可以使用:
Tips:由于chan的底層是一個(gè)指針,在Go語(yǔ)言中指針初始值為空,是需要實(shí)例化的。make就是示例化了chan。
- 1 ?
var c chan int //聲明一個(gè)存放int類(lèi)型數(shù)據(jù)的通道
- 2?
c = make(chan int, 1) //創(chuàng)建一個(gè)長(zhǎng)度為1的通道
在這種情況下最好使用:=
來(lái)同時(shí)聲明和創(chuàng)建:
- 1?
c := make(chan int, 1) //聲明并創(chuàng)建一個(gè)存放int類(lèi)型數(shù)據(jù)的通道
2. 通道的使用
在 Go 語(yǔ)言中,使用?<-
?符號(hào)來(lái)向通道中塞取數(shù)據(jù)。放在通道右邊?chan <-
,就是塞數(shù)據(jù),放在通道左邊?<- chan
?,就是取數(shù)據(jù)。
代碼示例:
- 1?
func main() {
- 2? ? ? ?
c := make(chan int, 1)
- 3? ? ? ?
c <- 10 //將10塞入通道中
- 4? ? ? ?
i := <-c //將10從通道中取出,并賦值給變量i
- 5? ? ? ?
fmt.Println(i)
- 6?
}
執(zhí)行結(jié)果:

3. 通道結(jié)合 select 流程控制
在 Go 語(yǔ)言中為了更方便的利用通道的功能,提供了一個(gè)僅用于通道的流程控制語(yǔ)句:select...case
。使用這個(gè)語(yǔ)句可以同時(shí)監(jiān)聽(tīng)數(shù)個(gè)通道,非常適合用于并發(fā)時(shí)的進(jìn)程調(diào)度,或者模塊之間的解耦合。這些在后續(xù)的文章中會(huì)有詳細(xì)介紹,下面通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)了解一下?select...case
?語(yǔ)句。
代碼示例:
- 1?
package main
- 2
- 3?
import "fmt"
- 4
- 5?
func main() {
- 6? ? ? ?
c := make(chan int, 1)
- 7
- 8? ? ? ?
for a := 0; a < 2; a++ {
- 9? ? ? ? ? ? ? ?
select {
- 10? ? ? ? ? ? ?
case i := <-c:
- 11? ? ? ? ? ? ? ? ? ? ? ?
fmt.Println("從通道中取出", i)
- 12? ? ? ? ? ? ?
case c <- 10:
- 13? ? ? ? ? ? ? ? ? ? ? ?
fmt.Println("將 10 塞入通道中")
- 14? ? ? ? ? ? ?
}
- 15? ? ? ?
}
- 16?
}
- 第 8 行:寫(xiě)一個(gè)兩次的循環(huán),若是在多線程中,一般寫(xiě)成死循環(huán);
- 第 9 行:select 關(guān)鍵字做為 select 語(yǔ)句的起始;
- 第 10 行:若 c 通道中存在數(shù)據(jù),則取出,并執(zhí)行后續(xù)語(yǔ)句;
- 第 12 行:若通道未滿,將 10 塞入通道中。
Tips:select語(yǔ)句和switch語(yǔ)句一樣,case都只會(huì)執(zhí)行一個(gè),然后立刻跳出語(yǔ)句
執(zhí)行結(jié)果:

4. 小結(jié)
本文介紹了 Go 語(yǔ)言中特有的類(lèi)型通道(chan)的用法,以及select...case
這個(gè) Go 語(yǔ)言中獨(dú)有的流程控制語(yǔ)句。通道使用的時(shí)候注意需要?make()
?內(nèi)置函數(shù)先創(chuàng)建,不然只是個(gè)空指針,無(wú)法使用。select...case
的?case?之后只能跟獲取通道數(shù)據(jù)或者塞數(shù)據(jù)進(jìn)通道。
文章來(lái)源于網(wǎng)絡(luò),侵刪!