You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Channel在Goroutine间传递数据问题:无法正确打印求和结果

问题分析与修复方案

你的代码存在两个核心问题:

  1. add 函数内部创建的通道 ch 和 main 中传给 display 的 ch2 是完全独立的两个通道,计算出的 sum 根本没传到 display 对应的通道里
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 11:25:01