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

Go goroutine处理URL返回结果数少于实际输入量该如何解决

问题根因

你的代码触发了Go语言经典的循环变量捕获陷阱:

  • for range遍历过程中,循环变量url是整个迭代周期内复用的临时变量,内存地址固定,每次遍历只会更新该地址存储的URL值
  • 你启动goroutine时,匿名函数没有将url作为入参传入,而是直接捕获了外部url变量的引用,等到goroutine实际执行时,循环大概率已经迭代到了后面的环节,拿到的url不是启动goroutine时对应的那条URL
  • 这会导致大量goroutine重复处理同一条URL、甚至拿到异常的url值导致encoding.HexEncodeURL执行失败提前退出,最终结果条数随机少于输入条数。
修复方案

只需要修改goroutine匿名函数的定义,将当前迭代的url作为参数传入即可,启动goroutine时会自动拷贝当前url的值到函数内部,每个goroutine都会拿到独立的URL值:

if len(URLLists) > 0 {
    var base = "https://example.com/query?="
    var wg sync.WaitGroup
    var mutex = sync.Mutex{}
    wg.Add(len(URLLists))
    for _, url := range URLLists {
        // 将url作为参数传入匿名函数
        go func(url string) {
            defer wg.Done()
            hmac := "HMAX_123"
            out := encoding.HexEncodeURL(hmac, url)
            final := base + out
            list := Lists{
                Old: url,
                New: final,
            }
            mutex.Lock()
            response.URL = append(response.URL, list)
            mutex.Unlock()
        }(url) // 这里传入当前迭代的url值
    }
    wg.Wait()
    jR, err := json.Marshal(response)
    if err != nil {
        w.Write([]byte(`{"success": false, "url" : ""}`))
    } else {
        w.Write(jR)
    }
    return
}
补充说明

你当前使用的wg.Add在循环外一次性添加全量计数、以及用mutex保护切片append的写法都是正确的,不需要调整,问题和WaitGroup的逻辑无关。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 00:24:01