go channel理解不徹底遇到的問題-nil channel
阿新 • • 發佈:2021-12-27
程式碼A
package main import ( "fmt" "time" ) func generator() chan int { out := make(chan int) go func() { i := 0 for { //time.Sleep(time.Duration(rand.Intn(8500)) * time.Millisecond) time.Sleep(1 * time.Second) out <- i i++ } }() return out } func worker(id int, c chan int) { for n := range c { time.Sleep(time.Second) fmt.Printf("Worker %d received %d\n", id, n) } } func createWorker(id int) chan<- int { c := make(chan int) go worker(id, c) return c } func main() { var c1, c2 = generator(), generator() var workChannel = createWorker(0) var values []int tm := time.After(10 * time.Second) tick := time.Tick(time.Second) for { var activeWorker chan<- int var activeValue int if len(values) > 0 { activeWorker = workChannel activeValue = values[0] } select { case n := <-c1: println("c1") values = append(values, n) case n := <-c2: println("c2") values = append(values, n) case activeWorker <- activeValue: println(activeValue) fmt.Println("values :", values, " activeValue:", activeValue) println(len(values)) values = values[1:] case <-time.After(800 * time.Millisecond): fmt.Println("timeout") case <-tick: fmt.Println( "queue len =", len(values)) case <-tm: fmt.Println("bye") return } } }
程式碼B
package main import ( "fmt" "math/rand" "time" ) func generator() chan int { out := make(chan int) go func() { i := 0 for { time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond) //time.Sleep(1 * time.Second) out <- i i++ } }() return out } func worker(id int, c chan int) { for n := range c { time.Sleep(time.Second) fmt.Printf("Worker %d received %d\n", id, n) } } func createWorker(id int) chan<- int { c := make(chan int) go worker(id, c) return c } func main() { var c1, c2 = generator(), generator() var workChannel = createWorker(0) var values []int //tm := time.After(10 * time.Second) tick := time.Tick(time.Second) for { // var activeWorker chan<- int var activeValue int if len(values) > 0 { // activeWorker = workChannel activeValue = values[0] } select { case n := <-c1: values = append(values, n) case n := <-c2: values = append(values, n) case workChannel <- activeValue: fmt.Println("values :", values, " activeValue:", activeValue) values = values[1:] case <-tick: fmt.Println( "queue len =", len(values)) //case <-tm: // fmt.Println("bye") // return } } }
程式碼A、B 晃眼一看基本沒有什麼問題,都是兩個生產者一個消費者,A只是多了activeWorker 的臨時變數,中間做了轉換,但是問題就出在這裡,由於對於nil channel的理解不夠,所以一直認為 nil channel是可以傳值的,但是百思不得其解,為什麼一直報錯。
網上找了教程,看了總結,才發現,原理竟然如此簡單,論基礎的重要性。。。。。。