在 Go
中我們所以 close()
來關閉一個 channel
- 官方的註釋如下
The close built-in function closes a channel, which must be either bidirectional or send-only.
It should be executed only by the sender,never the receiver, and has the effect of shutting down the channel after the last sent value is received.
After the last value has been received from a closed channel c, any receive from c will succeed without blocking, returning the zero value for the channel element.
The form x, ok := <-c will also set ok to false for a closed channel.
翻譯如下
close
內置函數關閉一個通道,該通道必須是雙向的或僅發送的。- 如下關閉
ch3
就會報錯invalid operation: close(ch3) (cannot close receive-only channel)
- 如下關閉
ch1 := make(chan int, 10)
ch2 := make(chan<- int, 10)
ch3 := make(<-chan int, 10)
close(ch1)
close(ch2)
close(ch3)
channel
應僅由發送方執行,而不應由接收方執行,並且在收到最後發送的值後具有關閉通道的效果。- 即
channel
應該由發送的一方執行,由接收channel
的一方關閉
- 即
func send(ch chan int) {
for i := 0; i < 10; i++ {
ch <- i
}
}
func receive(ch chan int) {
for {
fmt.Println(<-ch)
}
close(ch)
}
func main() {
ch := make(chan int, 10)
go send(ch)
go receive(ch)
time.Sleep(1 * time.Millisecond)
}
- 在從閉合通道
c
接收到最後一個值之後,來自c
的任何接收都將成功而不會阻塞,返回通道元素的零值。- 如下,因爲通道元素類型是int,零值是0,所以輸出全是
ch
的this is from ch 0
,而ch1
由於沒有賦值,所以沒有IO
操作不能被select
捕捉
- 如下,因爲通道元素類型是int,零值是0,所以輸出全是
func receive(ch chan int, ch1 chan int) {
for {
select {
case a := <-ch:
fmt.Println("this is from ch", a)
case b := <-ch1:
fmt.Println("this is from ch1", b)
}
}
}
func main() {
ch := make(chan int, 10)
ch1 := make(chan int, 10)
close(ch)
go receive(ch, ch1)
time.Sleep(1 * time.Millisecond)
}
- 對於封閉的通道,表單
x , ok := <- c
也會將ok
設置爲false
- 輸出
0
和false
,通過這一點我們可以判斷channel
是否被關閉
- 輸出
ch := make(chan int, 10)
close(ch)
if x, ok := <-ch; !ok {
fmt.Println(x, ok)
}