Go 語言延遲初始化 -Lazy Initialization- 最佳實踐
- 簡介
在有些資源初始化成本很高,甚至在某些代碼路徑未觸發根本沒有必要初始化,可以將對象的創建、配置等耗時操作推遲到真正需要使用時才執行。
- 延遲初始化實現
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] www.zhengwenfeng.com: http://www.zhengwenfeng.com
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/7pyEVLYQZFI-j5glm6CRNg