惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hugging Face - Blog
Hugging Face - Blog
Recent Announcements
Recent Announcements
V
Visual Studio Blog
博客园 - 叶小钗
H
Help Net Security
aimingoo的专栏
aimingoo的专栏
宝玉的分享
宝玉的分享
U
Unit 42
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
F
Fortinet All Blogs
V
V2EX
Stack Overflow Blog
Stack Overflow Blog
WordPress大学
WordPress大学
D
DataBreaches.Net
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
A
About on SuperTechFans
酷 壳 – CoolShell
酷 壳 – CoolShell
量子位
C
Check Point Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
小众软件
小众软件
Microsoft Azure Blog
Microsoft Azure Blog
M
MIT News - Artificial intelligence

郑文峰的博客

使用dify对接飞书多维表格 使用n8n对接飞书多维表格 服务启动时出现 OOM 一次服务升级时pg表DDL执行超时失败 Go语言高效IO缓冲技术详解 Go语言字符串拼接性能对比与优化指南 Go语言结构体内存对齐完全指南 Go语言空结构体:零内存消耗的高效编程 Go语言堆栈分配与逃逸分析深度解析 Go语言原子操作完全指南 Go语言内存预分配完全指南 Go语言不可变数据共享:无锁并发编程实践 Go语言零拷贝技术完全指南 Go语言遍历性能深度解析:从原理到优化实践 Go语言Interface Boxing原理与性能优化指南 Go协程池深度解析:原理、实现与最佳实践 使用etcd分布式锁导致的协程泄露与死锁问题 基于pre-commit的Python代码规范落地实践 初识 MCP Server pulsar阻塞导致logstash无法接入日志 django-prometheus使用及源码分析 kube-proxy源码分析 kubernetes service如何通过iptables转发 tcp缓存引起的日志丢失 django-apschedule定时任务异常停止 理解calico容器网络通信方案原理 理解flannel的三种容器网络方案原理 理解Linux IPIP隧道 理解VXLAN网络 理解Linux TunTap设备
Go语言延迟初始化(Lazy Initialization)最佳实践
zhengwenfeng · 2025-06-15 · via 郑文峰的博客

# 1. 简介

在有些资源初始化成本很高,甚至在某些代码路径未触发根本没有必要初始化,可以将对象的创建、配置等耗时操作推迟到真正需要使用时才执行。

# 2. 延迟初始化实现

# 2.1 sync.Once

sync.Once 是Go标准库提供的线程安全初始化工具,确保初始化代码只执行一次:

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13

特点:

  • 线程安全,适合并发场景
  • 初始化逻辑与业务代码耦合
  • 需要额外定义全局变量

# 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()     // 后续调用直接返回缓存值

1
2
3
4
5
6
7
8
9
10

# 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
2
3
4
5
6
7
8
9
10
11

# 3. 总结

在以下场景中适合使用延迟初始化:

  • 资源初始化成本非常高。
  • 为了提高启动性能和内存效率。
  • 当并非所有的资源都需要在运行时立即使用,甚至根本不需要使用。