笔记 - 在合适之处关闭channel

/*
摘自: 
https://code.google.com/p/go/source/browse/2013/advconc/buffer/buffer.go?repo=talks
*/
package main

import (
	"fmt"
)

func main() {
	in,out := make(chan int),make(chan int)
	go buffer(in,out)

	for i := 0; i < 10; i++ {
		in <- i
	}
	close(in) // in == nil => false

	for i := range out { // 注:out如果不close()会持续循环下去,系统报错
		fmt.Println(i)
	}

}

func buffer(in <-chan int,out chan<- int) {
	var buf []int // 无限制的缓存

	for in != nil || len(buf) > 0 {
		var i int = 0
		var c chan<- int

		if len(buf) > 0 { // 如果缓存中还有数据,则取出发送。
			i = buf[0]
			c = out
		}

		// 此处会阻塞
		select {
		case c <- i: // 送出左端数据
			buf = buf[1:]
		case n,ok := <-in: // 取出in管道数据,放入缓存中。
			if ok {
				buf = append(buf,n)
			} else {
				in = nil // 消灭一个LOOP条件
			}

		}
	}
	close(out) // 在合适之处关闭channel
}

相关文章

程序目录结构 简单实现,用户登录后返回一个jwt的token,下次请求带上token请求用户信息接口并返回信息...
本篇博客的主要内容是用go写一个简单的Proof-of-Work共识机制,不涉及到网络通信环节,只是一个本地的简...
简介 默克尔树(MerkleTree)是一种典型的二叉树结构,其主要特点为: 最下面的叶节点包含存储数据或其...
接下来学习并发编程, 并发编程是go语言最有特色的地方, go对并发编程是原生支持. goroutine是go中最近本...
先普及一下, 什么是广度优先搜索 广度优先搜索类似于树的层次遍历。从图中的某一顶点出发,遍历每一个顶...
第一天: 接口的定义和实现 第二天: 一. go语言是面向接口编程. 在学习继承的时候说过, go语言只有封装,...