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

推荐订阅源

罗磊的独立博客
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
Hugging Face - Blog
Hugging Face - Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
WordPress大学
WordPress大学
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园_首页
博客园 - Franky
博客园 - 司徒正美
酷 壳 – CoolShell
酷 壳 – CoolShell
爱范儿
爱范儿
Jina AI
Jina AI
Last Week in AI
Last Week in AI
雷峰网
雷峰网
IT之家
IT之家
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
小众软件
小众软件
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
V2EX

Origin

Agent 安全:环境变量泄露 人生第一次离职,感觉应该写点什么 在 Python 中复现 Race Condition 再看看 SQL 中的 null 迁移 Zeabur 集群 2025Q3 订阅 Recap 再见 xlog Python 的 pth 文件:在程序启动前自动执行命令 浏览器从 A 到 Z 2024Q3 订阅 Recap 使用 TypeScript 撰写 OmniFocus 脚本 [随笔] 一开始就公布定价 [随笔] Server Action [随笔] Swift 异步:Task vs DispatchQueue [随笔] RSS 与稍后阅读 在 Shell 脚本中嵌入二进制文件 谈谈时区 利用 Fly.io 部署 Windmill 强制关闭 xLog 的 Dark Mode 解决 CentOS8 中 yum 源失效 [随笔] 避免完美主义导致的看似时间不够
[备忘] Go init 行为
Singee · 2023-12-12 · via Origin

总结

基础规则:

  1. 所有的 init 函数都在一个 Goroutine 中执行(但请参见下面的特殊注意)
  2. 如果 package a 引用了 package b,那么 a 的 init 一定在 b 的 init 运行完成后运行
  3. main package 的 main 函数一定在其他 init 函数均运行完成后再运行(即运行顺序为 package 的 init -> main 的 init -> main 的 main)
  4. 同一 package 中的多个文件中的 init 执行顺序未定义,同一文件中的 init 自上而下运行
  5. 如果 package a 同时引用了 package b 和 c,那么 b 与 c 的 init 顺序在 Go1.21 及之后定义

在 Go1.20 及之前:

  1. 如果 package a 引用了 package b,那么 b 的 init 一定在 a 之前运行
  2. 但是,如果 package a 同时引用了 package b 和 c,只要 b c 之间没有引用关系,b c 的执行顺序是不定的

在 Go1.21 及之后:

  1. 对于无引用关系的包(即 Go1.20 及之前的中的第 2 点),按照其包名字母序决定引用顺序(例如 a 一定在 b 之前执行,github.com/xxx/xxx 一定在 gitlab.com/xxx/xxx 之前执行)

特殊注意:

  1. 如果 init 存在阻塞,那么用于运行 init 的 goroutine 可能创建新的 goroutine,这会导致某些 init 代码并发运行
  2. 存在阻塞的情况下,不会保证无引用关系的 package 的 init 完成先后顺序(参考示例 c)
  3. 存在阻塞的情况下,如果 package a 依赖了 package b,那么 a 的 init 一定在 b 的 init 运行完成后开始运行(参考示例 d)

示例项目

https://github.com/singee-study/go-init

参考

The Go Memory Model
Go 1.21 Release Notes