2016-01-02 14:07:09 +00:00
|
|
|
|
## 8.4. Channels
|
|
|
|
|
|
2016-01-03 04:07:46 +00:00
|
|
|
|
如果説goroutine是Go語音程序的併發體的話,那麽channels它們之間的通信機製。一個channels是一個通信機製,它可以讓一個goroutine通過它給另一個goroutine發送值信息。每個channel都有一個特殊的類型,也就是channels可發送數據的類型。一個可以發送int類型數據的channel一般寫爲chan int。
|
|
|
|
|
|
|
|
|
|
使用內置的make函數,我們可以創建一個channel:
|
|
|
|
|
|
|
|
|
|
```Go
|
|
|
|
|
ch := make(chan int) // ch has type 'chan int'
|
|
|
|
|
```
|
|
|
|
|
|
2016-01-21 02:56:41 +00:00
|
|
|
|
和map類似,channel也一個對應make創建的底層數據結構的引用。當我們複製一個channel或用於函數參數傳遞時,我們隻是拷貝了一個channel引用,因此調用者何被調用者將引用同一個channel對象。和其它的引用類型一樣,channel的零值也是nil。
|
2016-01-03 04:07:46 +00:00
|
|
|
|
|
|
|
|
|
兩個相同類型的channel可以使用==運算符比較。如果兩個channel引用的是相通的對象,那麽比較的結果爲眞。一個channel也可以和nil進行比較。
|
|
|
|
|
|
|
|
|
|
一個channel有發送和接受兩個主要操作,都是通信行爲。一個發送語句將一個值從一個goroutine通過channel發送到另一個執行接收操作的goroutine。發送和接收兩個操作都是用`<-`運算符。在發送語句中,`<-`運算符分割channel和要發送的值。在接收語句中,`<-`運算符寫在channel對象之前。一個不使用接收結果的接收操作也是合法的。
|
|
|
|
|
|
|
|
|
|
```Go
|
|
|
|
|
ch <- x // a send statement
|
|
|
|
|
x = <-ch // a receive expression in an assignment statement
|
|
|
|
|
<-ch // a receive statement; result is discarded
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Channel還支持close操作,用於關閉channel,隨後對基於該channel的任何發送操作都將導致panic異常。對一個已經被close過的channel之行接收操作依然可以接受到之前已經成功發送的數據;如果channel中已經沒有數據的話講産生一個零值的數據。
|
|
|
|
|
|
|
|
|
|
使用內置的close函數就可以關閉一個channel:
|
|
|
|
|
|
|
|
|
|
```Go
|
|
|
|
|
close(ch)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
以最簡單方式調用make函數創建的時一個無緩存的channel,但是我們也可以指定第二個整形參數,對應channel的容量。如果channel的容量大於零,那麽該channel就是帶緩存的channel。
|
|
|
|
|
|
|
|
|
|
```Go
|
|
|
|
|
ch = make(chan int) // unbuffered channel
|
|
|
|
|
ch = make(chan int, 0) // unbuffered channel
|
|
|
|
|
ch = make(chan int, 3) // buffered channel with capacity 3
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
我們將先討論無緩存的channel,然後在8.4.4節討論帶緩存的channel。
|
|
|
|
|
|
2016-01-02 14:07:09 +00:00
|
|
|
|
|
|
|
|
|
{% include "./ch8-04-1.md" %}
|
|
|
|
|
|
|
|
|
|
{% include "./ch8-04-2.md" %}
|
|
|
|
|
|
|
|
|
|
{% include "./ch8-04-3.md" %}
|
|
|
|
|
|
|
|
|
|
{% include "./ch8-04-4.md" %}
|