10.4.3 值为nil的通道

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

nilChannel.go 的第一部分如下:

package main

import (
    "fmt"
    "math/rand"
    "time"
)

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

func add(c chan int) {
    sum := 0
    t := time.NewTimer(time.Second)
    for {
        select {
            case input := <-c:
                sum = sum + input
            case <-t.C:
                c = nil
                fmt.Println(sum)
        }
    }
}

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

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

func send(c chan int) {
    for {
        c <- rand.Intn(10)
    }
}

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

nilChannel.go 的其余代码如下:

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

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

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

$go run nilChannel.go
13167523
$go run nilChannel.go
12988362

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

Last updated