github.com/songzhibin97/gkit@v1.2.13/internal/sys/once/once.go (about) 1 package once 2 3 import ( 4 "sync" 5 "sync/atomic" 6 ) 7 8 // Once 更强大的Once实现 9 // 在调用 f 失败的时候不会设置 done 并且可以返回失败信息 10 // 在失败的情况下也可以继续调用 Once 重试 11 type Once struct { 12 m sync.Mutex 13 done uint32 14 } 15 16 // Do 传入的函数f有返回值error,如果初始化失败,需要返回失败的error 17 // Do方法会把这个error返回给调用者 18 func (o *Once) Do(f func() error) error { 19 if atomic.LoadUint32(&o.done) == 1 { // fast path 20 return nil 21 } 22 return o.slowDo(f) 23 } 24 25 // 如果还没有初始化 26 func (o *Once) slowDo(f func() error) error { 27 o.m.Lock() 28 defer o.m.Unlock() 29 var err error 30 if o.done == 0 { // 双检查,还没有初始化 31 err = f() 32 if err == nil { // 初始化成功才将标记置为已初始化 33 atomic.StoreUint32(&o.done, 1) 34 } 35 } 36 return err 37 }