V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
赤友DiskGeeker — 一键搞定磁盘清理
赤友 DiskGeeker 支持一键清理系统垃圾,结合 AI 深度清理与智能分析技术,精准识别“其它文件”等磁盘占用,清理过程安全、可控、无风险。
Promoted by editorsiboysoft
SGL
V2EX  ›  Go 编程语言

go 源码困惑, 在 once.Do 中放标志变量,还是放操作本身。

  •  
  •   SGL · 11 天前 · 1598 次点击
    func AfterFunc(ctx Context, f func()) (stop func() bool) {
    a := &afterFuncCtx{
    f: f,
    }
    a.cancelCtx.propagateCancel(ctx, a)
    return func() bool {
    stopped := false
    a.once.Do(func() {
    stopped = true
    })
    if stopped { // TODO: 这个代码我很费解, 为什么不把 a.cancel(true, Canceled, nil)操作直接放到 once.Do 中呢。
    a.cancel(true, Canceled, nil)
    }
    return stopped
    }
    }

    这个是 go 源码中 context 包的部分代码。我很奇怪,为什么不在匿名函数中直接调用 a.once.Do(func(){ a.cancel(true, Canceled,nil)}), 这样也能确保这个取消操作只执行一次啊, 为什么要维护一个局部的标志变量呢。
    5 条回复    2025-07-15 09:57:57 +08:00
    cloudzhou
        1
    cloudzhou  
       11 天前
    是可以的,这个和个人代码风格有关,go 源代码的写法,stopped 变量作为一个独立的逻辑,后面以此作为判断,比较清晰
    ihciah
        2
    ihciah  
       11 天前 via iPhone
    这很 golang🌚外面一个 once ,cancel 里面还一个 atomic ,可能放这儿是避免给人一种复制的时候狂点 ctrl c 增大复制成功概率的感觉。
    lovelylain
        3
    lovelylain  
       10 天前 via Android
    要看全啊,仅看这里我的感觉是用 atomic.Bool 也能保证 stop 仅 1 次,为什么要用 sync.Once 。找来源码一看,这里是通过 sync.Once 仅执行 1 次实现要么调用 f 要么取消,调用 f 在 cancel 函数里,stop 后也会调用 cancel ,如果把 cancel 也放在 once 里调用,就可能死锁了。
    liaohongxing
        4
    liaohongxing  
       10 天前
    看函数签名 ,主要为了返回一个 bool 值吧 !把 stopped 这个变量 return 了 ,直接 cancel 没法返回这个布尔值。
    jigujigushanshan
        5
    jigujigushanshan  
       10 天前
    就是代码风格而已,比较明了,逻辑是逻辑,变量是变量 就算你写 once 里面了如果后面改 stop 还能因为其他原因变为 true 你不是还得把执行 cancel 移到外面来吗
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   958 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 22:53 · PVG 06:53 · LAX 15:53 · JFK 18:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.