• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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)
		}
	}
}

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
golangcache--go-cache发布时间:2022-07-10
下一篇:
Go语言学习笔记(一)发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap