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

Go语言如何先打印HELLO再输出错误信息并避免通道panic?

解决方案:调整Go代码执行顺序并避免通道panic

原代码的问题在于,主goroutine会阻塞在for item := range errorsChan循环上,直到通道关闭才会继续执行fmt.Print("HELLO\n"),导致错误信息先于HELLO输出。同时错误的WaitGroup管理会引发通道提前关闭的panic。

以下是修改后的代码,实现先输出HELLO,再打印错误信息,同时避免通道相关panic:

package main

import (
    "errors"
    "fmt"
    "sync"
    "time"

    er "github.com/pkg/errors"
)

func main() {
    var wg sync.WaitGroup
    errorsChan := make(chan error)

    // 启动两个任务goroutine
    wg.Add(2)
    go func() {
        defer wg.Done()
        say(5)
        errorsChan <- er.Wrap(errors.New("first one"), "first test")
    }()

    go func() {
        defer wg.Done()
        say(1)
        errorsChan <- er.Wrap(errors.New("something"), "another test")
    }()

    // 单独goroutine:等待所有任务完成后关闭通道
    go func() {
        wg.Wait()
        close(errorsChan)
    }()

    // 主goroutine先输出HELLO,不等待错误处理
    fmt.Print("HELLO\n")

    // 单独goroutine处理错误输出,不阻塞主流程
    go func() {
        for item := range errorsChan {
            fmt.Println(item)
        }
    }()

    // 等待所有错误处理完成(可选,若需要主goroutine不立即退出)
    wg.Wait()
}

func say(i time.Duration) {
    time.Sleep(i * time.Second)
}

修改说明:

  • 优先输出HELLO:主goroutine不再阻塞在错误通道的读取循环,直接先打印HELLO
  • 独立错误处理goroutine:将错误信息的打印逻辑放到单独的goroutine中,不影响主流程的执行顺序
  • 正确管理WaitGroup:直接为两个任务goroutine计数,确保所有发送错误的操作完成后才关闭通道,从根源避免send on closed channel panic
  • 无缓冲通道安全:即使使用无缓冲通道,由于错误读取goroutine一直在等待接收,发送操作不会阻塞或引发panic

内容的提问来源于stack exchange,提问作者HexaCrop

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 09:25:12