Go語言 美妙的channel(上)
阿新 • • 發佈:2019-02-06
在 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)
for i
:= 0; i < cap(ch) +1 ; i++ {
v,
ok := <- ch
fmt.Println(v,
ok)
}
}
|
在這個例子裡,我們建立了一個緩衝區為兩個值的 channel,填充緩衝區並且關閉掉它。
true true
true true
false false
|
執行這個程式,首先會向我們展示那兩個傳送到 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)
for v
:= range ch {
fmt.Println(v) //
被呼叫兩次
}
}
|
但是其真正的價值是與 select 聯合時體現的。先從這個例子開始
package
main
import
(
"fmt"
"sync"
"time"
)
func
main() {
finish
:= make(chan bool )
|