使用Channel在Goroutine间传递数据问题:无法正确打印求和结果
问题分析与修复方案
你的代码存在两个核心问题:
add函数内部创建的通道ch和main中传给display的ch2是完全独立的两个通道,计算出的sum根本没传到display对应的通道里display函数直接打印了通道变量本身(通道在Go里是引用类型,打印会输出内存地址),而没有从通道中读取实际的数值
以下是修复后的完整代码:
package main import ( "fmt" "sync" ) // 修改add函数,接收外部传入的通道,不再自行创建 func add(n int, ch chan int) { sum := 0 for i := 0; i < n; i++ { sum += i } ch <- sum // 将sum传入共享通道 fmt.Println("Sum calculated:", sum) } // 修改display函数,从通道接收值后打印 func display(ch chan int, wg *sync.WaitGroup) { defer wg.Done() // 任务完成后通知WaitGroup sum := <-ch // 从通道读取sum值 fmt.Println("Sum is now:", sum) } func main() { ch := make(chan int) var wg sync.WaitGroup wg.Add(2) // 标记需要等待2个goroutine完成 go add(10, ch) go display(ch, &wg) fmt.Println("Hello World!") wg.Wait() // 等待所有goroutine完成,替代time.Sleep的粗暴等待方式 close(ch) // 通道使用完毕后关闭 }
关键修改说明:
- 让
add接收外部通道:这样计算出的sum能传入到共享的通道中,供display读取 display从通道接收值:用sum := <-ch获取通道内的实际数值,再打印就不会输出地址了- 使用
sync.WaitGroup替代time.Sleep:time.Sleep是不可靠的等待方式,WaitGroup能精确等待所有goroutine执行完毕,避免程序提前退出或无意义等待
如果想保留 time.Sleep 做简单演示(不推荐在生产代码中使用),也可以简化成:
package main import ( "fmt" "time" ) func add(n int, ch chan int) { sum := 0 for i := 0; i < n; i++ { sum += i } ch <- sum fmt.Println("Sum calculated:", sum) } func display(ch chan int) { sum := <-ch fmt.Println("Sum is now:", sum) } func main() { ch := make(chan int) go add(10, ch) go display(ch) fmt.Println("Hello World!") time.Sleep(time.Second) close(ch) }
内容的提问来源于stack exchange,提问作者Witty Apps
相关产品推荐
相关产品推荐

