Go語言單向通道——通道中的單行道

   Go語言的類型系統提供了單方向的channel類型,顧名思義,單向channel只用於發送或者接受數據。channel本身必然是同時支持讀寫否則根本沒法用。假如一個 channel 真的只能讀,那麼肯定只會是空的,因爲你沒機會往裏面寫數據。同理,如果一個 channel 只允許寫,即使寫進去了,也沒有絲毫意義,因爲沒有機會讀取裏面的數據。所謂的單向 channel 概念,其實只是對 channel 的一種使用限制。

  • 單向通道的聲明格式

     將一個channel變量傳遞到一個函數時,可以通過將其指定爲單向channel變量,從而限制該函數中可以對此channel的操作,比如只能往這個channel寫,或者只能從這個channel讀。

  單向channel變量的聲明非常簡單,只能發送的通道類型爲chan<-,只能接收的通道類型爲<-chan,格式如下:   

    var 通道實例 chan<- 元素類型    // 只能發送通道

    var 通道實例 <-chan 元素類型    // 只能接收通道

單向通道的使用例子

例子代碼如下:

  1. ch := make(chan int)
  2. // 聲明一個只能發送的通道類型, 並賦值爲ch
  3. var chSendOnly chan<- int = ch
  4. //聲明一個只能接收的通道類型, 並賦值爲ch
  5. var chRecvOnly <-chan int = ch

   上面的例子中,chSendOnly 只能發送數據,如果嘗試接收數據,將會出現如下報錯:

invalid operation: <-chSendOnly (receive from send-only type chan<- int)

同理,chRecvOnly也不能發送的

當然,使用make創建通道時,也可以創建一個只發送或讀取的通道:

 ch :=make(<-chan int)

 var chReadOnly <-chan int = ch

<-chReadOnly

上面代碼編譯正常,運行也是正常。但是,一個不能填充數據(發送)只能讀取的通道是毫無意義的。

  • time包中的單向通道

time包中的計時器會返回一個timer實例,代碼如下:

timer:=time.NewTimer(time.Second)

timer的Timer類型定義如下:

  type Timer Struct{

   c<-chan Time

  r runtimeTimer

}

第 2 行中 C 通道的類型就是一種只能接收的單向通道。如果此處不進行通道方向約束,一旦外部向通道發送數據,將會造成其他使用到計時器的地方邏輯產生混亂。因此,單向通道有利於代碼接口的嚴謹性。

  • 關閉 channel

關閉channel非常簡單,直接使用Go語言內置的close()函數即可:

close(ch)

在介紹瞭如何關閉channel之後,我們就多了一個問題,如何判斷一個channel是否已經被關閉?我們可以在讀取的時候使用多重返回值的方式:

X.ok:=<-ch

這個用法與 map 中的按鍵獲取 value 的過程比較類似,只需要看第二個 bool 返回值即可,如果返回值是 false 則表示 ch 已經被關閉。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章