Go 語言延遲初始化 -Lazy Initialization- 最佳實踐

  1. 簡介

在有些資源初始化成本很高,甚至在某些代碼路徑未觸發根本沒有必要初始化,可以將對象的創建、配置等耗時操作推遲到真正需要使用時才執行。

  1. 延遲初始化實現

2.1 sync.Once

sync.Once 是 Go 標準庫提供的線程安全初始化工具,確保初始化代碼只執行一次:

var (
    resource *MyResource  // 需要延遲初始化的資源
    once     sync.Once    // 控制初始化的同步原語
)

func getResource() *MyResource {
    once.Do(func() {
        resource = &MyResource{
            // 初始化代碼
        }
    })
    return resource
}

特點:

2.2 sync.OnceValue (Go 1.21+)

Go 1.21 引入了更簡潔的 sync.OnceValue,適合返回單個值的場景:

var getResource = sync.OnceValue(func() *MyResource {
    return &MyResource{
        // 初始化代碼
    }
})

// 使用示例
func main() {
    res := getResource()  // 第一次調用時初始化
    _ = getResource()     // 後續調用直接返回緩存值

2.3 錯誤處理方案:sync.OnceValues

當初始化可能返回錯誤時,使用 sync.OnceValues:

var getConfig = sync.OnceValues(func() (*Config, error) {
    return loadConfig("config.yml")
})

func main() {
    config, err := getConfig()
    if err != nil {
        log.Fatal("加載配置失敗:", err)
    }
    // 使用配置...
}
  1. 總結

在以下場景中適合使用延遲初始化:

引用鏈接

[1] www.zhengwenfeng.com: http://www.zhengwenfeng.com

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/7pyEVLYQZFI-j5glm6CRNg