值为nil的通道

这节,您将了解到 值为 nil 的通道。这些是通道的特殊类型,因为它们总是阻塞的。空通道的使用说明在 nilChannel.go 中, 分为四个代码片段来介绍。

nilChannel.go 的第一部分如下:

  1. package main
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "time"
  6. )

nilChannel.go 的第二段代码显示如下:

  1. func add(c chan int) {
  2. sum := 0
  3. t := time.NewTimer(time.Second)
  4. for {
  5. select {
  6. case input := <-c:
  7. sum = sum + input
  8. case <-t.C:
  9. c = nil
  10. fmt.Println(sum)
  11. }
  12. }
  13. }

add() 函数展示了如何使用空通道。<-t.c 表达式按在 time.NewTimer() 调用中指定的时间阻塞 t 计时器的 c 通道。不要混淆函数的参数 c 通道和 t 计时器的 t.c 通道。它会触发 select 表达式的相关分支的执行,给 c 通道分配 nil 值并打印 sum 变量。

nilChannel.go 的第三段代码如下:

  1. func send(c chan int) {
  2. for {
  3. c <- rand.Intn(10)
  4. }
  5. }

send() 函数的目的是产生随机数并持续发送它们到一个通道里,只要这个通道是打开的。

nilChannel.go 的其余代码如下:

  1. func main() {
  2. c := make(chan int)
  3. go add(c)
  4. go send(c)
  5. time.Sleep(3 * time.Second)
  6. }

使用 time.Sleep() 函数是为了给这俩个 goroutines 足够的操作时间。

执行 nilChannel.go 将产生如下输出:

  1. $go run nilChannel.go
  2. 13167523
  3. $go run nilChannel.go
  4. 12988362

由于执行 add() 函数中的 select 表达式的第一个分支的次数不固定,所以您执行 nilChannel.go 会得到不同的结果。