1. 程式人生 > >Go語言 美妙的channel(上)

Go語言 美妙的channel(上)

在 Go 程式語言中,channel 是一個閃耀的特性。它提供了一種強大的、在不使用鎖或臨界區的情況下,從某個 goroutine 向其他 goroutine 傳送資料流的方法。

今天我想討論關於 channel 的兩個重要的特性,這些特性不但使其在控制資料流方面極為有用,而且用在流程控制方面也十分有效。

一個已經被關閉的 channel 永遠都不會阻塞

第一個特性,我想談一談已經被關閉的 channel。當一個 channel 一旦被關閉,就不能再向這個 channel 傳送資料,不過你仍然可以嘗試從 channel 中獲取值。

package main
import"fmt" func main() { ch := make(chan bool, 2) ch <- true ch <- true close(ch) fori := 0; i < cap(ch) +1 ; i++ { v, ok := <- ch fmt.Println(v, ok) } }

在這個例子裡,我們建立了一個緩衝區為兩個值的 channel,填充緩衝區並且關閉掉它。

true
true truetrue falsefalse

執行這個程式,首先會向我們展示那兩個傳送到 channel 的值,然後第三次在 channel 上的嘗試會返回 flase 和 false。第一個 false 是 channel 型別的零值,channel 的型別是 chan bool,那麼就是 false。第二個表示 channel 的啟用狀態,當前是 false,表示 channel 被關閉。channel 會一直返回這些值。作為嘗試,可以修改這個例子使其從 channel 裡取 100 次值看看。

能夠檢測 channel 是否關閉是一個很有用的特性,可用於對 channel 進行 range 操作,並且當 channel 清空後退出迴圈。

package main import"fmt" func main() { ch := make(chan bool, 2) ch <- true ch <- true close(ch) forv := range ch { fmt.Println(v)// 被呼叫兩次 } }

但是其真正的價值是與 select 聯合時體現的。先從這個例子開始

package main import ( "fmt" "sync" "time" ) func main() { finish := make(chan bool)