Golang學習筆記(十九):Channel初步接觸

張君鴻發表於2019-03-22

Go語言是原生支援併發程式設計的,而Channel正是Go語言中實現併發不可或缺的型別,一起來學習一下吧。

什麼是channel

我們知道gotoutine是Go語言中的併發執行單元,我們可以建立多個goroutine實現程式的併發,而goroutine之間的通訊機制則由 channel來實現。

channel是Go語言中的一種特殊型別,我們可以宣告一個channel可以傳送的型別,然後通過向channel傳送或接收值到達通訊的目的。

channel的建立

使用關鍵字chan後跟一個可傳送的資料型別,這樣就可以宣告一個channel變數,如下所示

var ch chan int
複製程式碼

channel是引用型別,因此剛宣告的channel而未初始化的變數初值是nil,向未初始化的channel型別傳送數值,會引發panic錯誤,可以使用make方法初始化channel:如下所示

ch = make(chan int)
複製程式碼

經過make方法初始化的channel,會引用底層的資料結構,相同型別的channel可以進行相等比較,如果引用相同的底層結構,則為相等。所有的channel型別都可以跟nil比較。

傳送與接收操作

channel的作用便用於通訊的,所以對channel有兩個操作,傳送和接收,在一個gotoutine傳送數值,在另一個goroutine接收數值,達到通訊中共享記憶體的目的。

package main
import "fmt"

func main() {
    ch := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            ch <- i
        }
        close(ch)
    }()
    for {
        x ,ok := <- ch
        if !ok{
            break
        }
        fmt.Println(x)
    }
}

複製程式碼

在上面的例子中,我們使用匿名函式建立了一個gotourine,在其中向ch傳送10個數值,併發主goroutine中接收,傳送完畢之後,可可使用close()函式關閉channel。

注意,如果向已關閉的channel傳送數值,會引發pannic錯誤。如果從已關閉的channel中接收值,則會一直收該資料型別的零值,Go語言中無法判斷channel是否關閉,但可以接收第二個bool型別的值來判斷是否獲取到有效的值,在上面的例子,使用Ok來表示這個值。

相關文章