/* 摘自: 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 }