结论:sync.Once 保证其 Do(f) 中的 f 在进程内恰好执行一次——无论多少 goroutine 并发调用,f 只跑一遍,其余调用者阻塞等待首次执行完成后直接返回。它通过"原子标志位 + 互斥锁"的快慢两条路径实现。

展开:实现要点(标准库源码约 20 行):done 是 atomic.Uint32,慢路径先加 Mutex,加锁后 double-check 标志,未执行则 defer 里置 1 再调 f——defer 保证即使 f panic 标志也会置位(Once 语义是"调用过一次"而非"成功一次");快路径是 Do 开头的一次原子 Load,已置位直接返回,无锁。1.21 后的优化是把原子读放最前,热路径零锁开销。典型用途:单例初始化、惰性加载全局资源(DB 连接池、配置解析)、注册表只注册一次。易错点:1)f 里再调用同一个 Once 的 Do 会死锁(锁不可重入);2)f panic 后 Once 视为已消费,重试语义要自己包一层;3)Once 不能复制使用(go vet 会报 copylocks)。

var (
    once     sync.Once
    instance *DB
)
func GetDB() *DB {
    once.Do(func() { instance = connect() })
    return instance
}

追问方向:与包级 init() 的分工(错误处理能力)、单测中如何重置 Once(只能重建实例,这是它不适合可重试初始化的原因)。