和map類似,channel也一個對應make創建的底層數據結構的引用。
當我們復制一個channel或用於函數參數傳遞時,我們只是拷貝了一個channel引用,因此調用者和被調用者將引用同一個channel對象。和其它的引用類型一樣,channel的零值也是nil。
定義一個channel時,也需要定義發送到channel的值的類型。channel可以使用內置的make()函數來創建:
chan是創建channel所需使用的關鍵字。Type 代表指定channel收發數據的類型。
make(chan Type) //等價於make(chan Type, 0)
make(chan Type, capacity)
當 參數capacity= 0 時,channel 是無緩沖阻塞讀寫的;當capacity > 0 時,channel 有緩沖、是非阻塞的,直到寫滿 capacity個元素才阻塞寫入。
channel非常像生活中的管道,一邊可以存放東西,另一邊可以取出東西。channel通過操作符 <- 來接收和發送數據,發送和接收數據語法:
channel <- value //發送value到channel
<-channel //接收並將其丟棄
x := <-channel //從channel中接收數據,並賦值給x
x, ok := <-channel //功能同上,同時檢查通道是否已關閉或者是否為空
默認情況下,channel接收和發送數據都是阻塞的,除非另一端已經准備好,這樣就使得goroutine同步變的更加的簡單,而不需要顯式的lock。
package main import ( "fmt" ) func main() { c := make(chan int, 0) go func() { defer fmt.Println("子協程結束") fmt.Println("子協程正在運行……") //發送數據6到c c <- 6 }() //等待接收c數據賦值給num num := <-c fmt.Println(num) fmt.Println("main協程結束") }
