Go 語言中有一個特殊的類型 chan
,這是在 Go 語言的多線程操作中非常重要的一個數據類型。它的一般用于線程之間的數據傳輸,所以這個操作類型叫做 " 通道 (channel)"。
1. 通道的聲明和定義
通道可以理解為一種特殊的變量,所以它的聲明和其它變量的聲明并沒有太大的區別,聲明通道變量的寫法如下:
var c chan int //聲明一個存放int類型數據的通道
但是它聲明之后并不能直接使用,需要使用內置函數 make()
來創建一下通道變量才可以使用:
Tips:由于 chan 的底層是一個指針,在 Go 語言中指針初始值為空,是需要實例化的。make 就是實例化了 chan。
var c chan int //聲明一個存放int類型數據的通道
c = make(chan int, 1) //創建一個長度為1的通道
在這種情況下最好使用:=
來同時聲明和創建:
c := make(chan int, 1) //聲明并創建一個存放int類型數據的通道
2. 通道的使用
在 Go 語言中,使用 <-
符號來向通道中塞取數據。放在通道右邊 chan <-
,就是塞數據,放在通道左邊 <- chan
,就是取數據。
代碼示例:
func main() {
c := make(chan int, 1)
c <- 10 //將10塞入通道中
i := <-c //將10從通道中取出,并賦值給變量i
fmt.Println(i)
}
執行結果:
3. 通道結合 select 流程控制
在 Go 語言中為了更方便的利用通道的功能,提供了一個僅用于通道的流程控制語句:select...case
。使用這個語句可以同時監聽數個通道,非常適合用于并發時的進程調度,或者模塊之間的解耦合。這些在后續的文章中會有詳細介紹,下面通過一個簡單的例子來了解一下 select...case
語句。
代碼示例:
package main
import "fmt"
func main() {
c := make(chan int, 1)
for a := 0; a < 2; a++ {
select {
case i := <-c:
fmt.Println("從通道中取出", i)
case c <- 10:
fmt.Println("將 10 塞入通道中")
}
}
}
- 第 8 行:寫一個兩次的循環,若是在多線程中,一般寫成死循環;
- 第 9 行:select 關鍵字做為 select 語句的起始;
- 第 10 行:若 c 通道中存在數據,則取出,并執行后續語句;
- 第 12 行:若通道未滿,將 10 塞入通道中。
Tips:select 語句和 switch 語句一樣,case 都只會執行一個,然后立刻跳出語句
執行結果:
4. 小結
本文介紹了 Go 語言中特有的類型通道(chan)的用法,以及 select...case
這個 Go 語言中獨有的流程控制語句。通道使用的時候注意需要 make()
內置函數先創建,不然只是個空指針,無法使用。select...case
的 case 之后只能跟 獲取通道數據或者塞數據進通道。