Go 關閉chanel & chanel的range迴圈

LiberHome發表於2022-05-31

關閉chanel

傳送者這邊可以傳送一個close(ch),接收方收到之後就知道傳送方之後都不會再傳送資訊了。
接收者這邊可以通過一個額外的變數,檢測通道是否已經關閉。類似這樣:v, ok := <- ch這裡的ok為false就代表我們從一個已經關閉的chanel獲取資料,這個資料是chanel型別對應的零值。

例如:

package main

import (
    "fmt"
    "time"
)

func main() {
    //    子協程:寫10個資料,每寫一次,就阻塞一次,主協程讀取一次,阻塞解除一次
    //    主協程:讀取一次資料,阻塞一次,子協程寫一次,阻塞解除一次
    ch1 := make(chan int)
    go sendData(ch1)
    //讀取chanel中的資料,不過由於我們可能不知道傳送方傳送了多少資料, 這裡用死迴圈
    for {
        time.Sleep(1 * time.Second)
        v, ok := <-ch1
        if !ok {
            fmt.Println("all the data has bean read ", ok)
            break
        }
        fmt.Println("the data read is: ", v, ok)
    }
}

func sendData(ch1 chan int) {
    // 傳送方: 傳送10條資料
    for i := 0; i < 10; i++ {
        //把i寫入chanel
        ch1 <- i
    }
    //關閉ch1通道
    close(ch1)
}

執行結果是:

the data read is:  0 true
the data read is:  1 true
the data read is:  2 true
the data read is:  3 true
the data read is:  4 true
the data read is:  5 true
the data read is:  6 true
the data read is:  7 true
the data read is:  8 true
the data read is:  9 true
all the data has bean read  false

chanel的range迴圈

相對於上面的for 用range能夠省去對ok值的判斷,更加簡潔方便地操作chanel。

下面這個例子中,range的含義就是從通道ch1中讀取資料並且賦值給v:

package main

import (
    "fmt"
    "time"
)

func main() {
    //    子協程:寫10個資料,每寫一次,就阻塞一次,主協程讀取一次,阻塞解除一次
    //    主協程:讀取一次資料,阻塞一次,子協程寫一次,阻塞解除一次
    ch1 := make(chan int)
    go sendData(ch1)
    //讀取chanel中的資料,不過由於我們可能不知道傳送方傳送了多少資料, 這裡用死迴圈
    for v := range ch1 { //這裡range的含義就是從通道ch1中讀取資料並且賦值給v [v<- ch1]
        fmt.Println("reading data: ", v)
    }
    fmt.Println("main-goroutine completed")
}

func sendData(ch1 chan int) {
    // 傳送方: 傳送10條資料
    for i := 0; i < 10; i++ {
        time.Sleep(1 * time.Second)
        //把i寫入chanel
        ch1 <- i
    }
    //關閉ch1通道
    close(ch1)
}

執行結果是:

reading data:  0
reading data:  1
reading data:  2
reading data:  3
reading data:  4
reading data:  5
reading data:  6
reading data:  7
reading data:  8
reading data:  9
main-goroutine completed

相關文章