Go基础系列:nil channel用法示例

f-ck-need-u · · 2585 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Go channel系列

当未为channel分配内存时,channel就是nil channel,例如var ch1 chan int。nil channel会永远阻塞对该channel的读、写操作。

nil channel会阻塞对该channel的所有读、写。所以,可以将某个channel设置为nil,进行强制阻塞,对于select分支来说,就是强制禁用此分支。

以下是一个nil channel的示例:

package main

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

// 不断向channel c中发送[0,10)的随机数
func send(c chan int) {
    for {
        c <- rand.Intn(10)
    }
}

func add(c chan int) {
    sum := 0

    // 1秒后,将向t.C通道发送时间点,使其可读
    t := time.NewTimer(1 * time.Second)

    for {
        // 一秒内,将一直选择第一个case
        // 一秒后,t.C可读,将选择第二个case
        // c变成nil channel后,两个case分支都将一直阻塞
        select {
        case input := <-c:
            // 不断读取c中的随机数据进行加总
            sum = sum + input
        case <-t.C:
            c = nil
            fmt.Println(sum)
        }
    }
}

func main() {
    c := make(chan int)
    go add(c)
    go send(c)
    // 给3秒时间让前两个goroutine有足够时间运行
    time.Sleep(3 * time.Second)
}

上面的示例中,send()向通道c不断发送10以内的随机整数,add()则在一秒内不断读取通道c中的数据并进行加总。一秒时间到后,t.C通道就会有数据,第二个case分支就会被选中,第二个case会让第一个case评估的channel变为nil channel,使得第一个case从此永久禁用,因为第二个case没有多余的数据可读,它也被永久禁用。总共3秒之后,main goroutine结束,程序结束。

如果不理解NewTimer(d),换成After(d)是一样的,After(d)和NewTime(d).C是等价的。

func add(c chan int) {
    sum := 0
    t := time.After(1 * time.Second)
    for {
        select {
        case val := <-c:
            sum = sum + val
        case <-t:
            c = nil
            fmt.Println(sum)
        }
    }
}

有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:f-ck-need-u

查看原文:Go基础系列:nil channel用法示例

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2585 次点击  ∙  1 赞  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传