<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ## Channel 那么如果啟動了多個 goroutine,它們之間該如何通信呢?這就是 Go 語言提供的 channel(通道)要解決的問題。 **創建一個 channel** ``` ch := make(chan 數據類型) ch1 := make(chan int) // 創建一個整型類型的通道 ch2 := make(chan interface{}) // 創建一個空接口類型的通道, 可以存放任意格式 type Equip struct{ /* 一些字段 */ } ch2 := make(chan *Equip) // 創建Equip指針類型的通道, 可以存放*Equip ``` **發送數據** 通道的發送使用特殊的操作符 `<-`,將數據通過通道發送的格式為: 通道變量 <- 值 使用 `make` 創建一個通道后,就可以使用`<-`向通道發送數據,代碼如下: ``` // 創建一個空接口通道 ch := make(chan interface{}) // 將0放入通道中 ch <- 0 // 將hello字符串放入通道中 ch <- "hello" ``` 把數據往通道中發送時,如果接收方一直都沒有接收,那么發送操作將持續阻塞。 **接收數據** 通道接收同樣使用`<-`操作符 通道的數據接收一共有以下寫法。 1. 阻塞接收數據 阻塞模式接收數據時,將接收變量作為`<-`操作符的左值,格式如下: ``` data := <-ch ``` 執行該語句時將會阻塞,直到接收到數據并賦值給 data 變量。 2. 忽略接收的數據 阻塞接收數據后,忽略從通道返回的數據,格式如下: ``` <-ch ``` 執行該語句時將會發生阻塞,直到接收到數據,但接收到的數據會被忽略。這個方式實際上只是通過通道在 goroutine 間阻塞收發實現并發同步。 3. 循環接收 通道的數據接收可以借用 for range 語句進行多個元素的接收操作,格式如下: ``` for data := range ch { } ``` 通道 ch 是可以進行遍歷的,遍歷的結果就是接收到的數據。數據類型就是通道的數據類型。通過 for 遍歷獲得的變量只有一個,即上面例子中的 data。 ``` package main import ( "fmt" "time" ) func main() { // 構建一個通道 ch := make(chan int) // 開啟一個并發匿名函數 go func() { // 從3循環到0 for i := 3; i >= 0; i-- { // 發送3到0之間的數值 ch <- i // 每次發送完時等待 time.Sleep(time.Second) } }() // 遍歷接收通道數據 for data := range ch { // 打印通道數據 fmt.Println(data) // 當遇到數據0時, 退出接收循環 if data == 0 { break } } } ``` ### 無緩沖 channel 上面的示例中,使用 make 創建的 chan 就是一個無緩沖 channel,它的容量是 0,不能存儲任何數據。所以無緩沖 channel 只起到傳輸數據的作用,數據并不會在 channel 中做任何停留。這也意味著,無緩沖 channel 的發送和接收操作是同時進行的,它也可以稱為同步 channel。 ### 有緩沖 channel 有緩沖 channel 類似一個可阻塞的隊列,內部的元素先進先出。通過 make 函數的第二個參數可以指定 channel 容量的大小,進而創建一個有緩沖 channel,如下面的代碼所示: ``` cacheCh:=make(chan int,5) ``` 一個有緩沖 channel 具備以下特點: 1. 有緩沖 channel 的內部有一個緩沖隊列; 2. 發送操作是向隊列的尾部插入元素,如果隊列已滿,則阻塞等待,直到另一個 goroutine 執行,接收操作釋放隊列的空間; 3. 接收操作是從隊列的頭部獲取元素并把它從隊列中刪除,如果隊列為空,則阻塞等待,直到另一個 goroutine 執行,發送操作插入新的元素。 因為有緩沖 channel 類似一個隊列,可以獲取它的容量和里面元素的個數。如下面的代碼所示: ``` cacheCh:=make(chan int,5) cacheCh <- 2 cacheCh <- 3 fmt.Println("cacheCh容量為:",cap(cacheCh),",元素個數為:",len(cacheCh)) ``` 通過內置函數 cap 可以獲取 channel 的容量,也就是最大能存放多少個元素,通過內置函數 len 可以獲取 channel 中元素的個數。 ### 單向 channel 有時候,我們有一些特殊的業務需求,比如限制一個 channel 只可以接收但是不能發送,或者限制一個 channel 只能發送但不能接收,這種 channel 稱為單向 channel。 單向 channel 的聲明也很簡單,只需要在聲明的時候帶上 <- 操作符即可,如下面的代碼所示: ``` // 接收通道 ch := make(chan<- int) // 發送通道 ch := make(<-chan int) ``` ### 關閉 channel channel 還可以使用內置函數 `close`關閉。關閉channel之后就無法再發送任何數據了,在消費方可以通過語法`v, ok := <-ch`獲取channel是否被關閉。如果ok返回false,那么說明channel已經沒有任何數據并且已經被關閉。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看