[备忘] Go init 行为

💡 原文中文,约1000字,阅读约需3分钟。
📝

内容提要

本文讨论了Go语言中init函数的执行顺序规则。所有init函数在同一个Goroutine中执行,包的init函数在main函数之前运行。从Go1.21开始,引用关系无关的包按字母序执行,可能因阻塞导致并发执行,从而影响顺序。

🎯

关键要点

  • 所有的 init 函数都在一个 Goroutine 中执行。
  • 包的 init 函数在 main 函数之前运行。
  • 同一 package 中的多个文件中的 init 执行顺序未定义,同一文件中的 init 自上而下运行。
  • 在 Go1.21 及之后,引用关系无关的包按字母序执行。
  • 如果 init 存在阻塞,可能导致某些 init 代码并发运行,无法保证无引用关系的 package 的 init 完成先后顺序。
  • 如果 package a 依赖了 package b,那么 a 的 init 一定在 b 的 init 运行完成后开始运行。

延伸问答

Go语言中的init函数执行顺序是怎样的?

所有的init函数在同一个Goroutine中执行,包的init函数在main函数之前运行。

在Go1.21之前,引用关系无关的包的init函数执行顺序是怎样的?

在Go1.20及之前,如果package a同时引用了package b和c,b和c的执行顺序是不定的。

Go1.21及之后,如何确定无引用关系的包的init执行顺序?

在Go1.21及之后,引用关系无关的包按字母序执行。

如果一个init函数存在阻塞,会有什么影响?

如果init存在阻塞,可能导致某些init代码并发运行,无法保证无引用关系的package的init完成先后顺序。

在Go语言中,如何保证依赖关系的包的init函数执行顺序?

如果package a依赖了package b,那么a的init一定在b的init运行完成后开始运行。

同一package中多个文件的init函数执行顺序是怎样的?

同一package中的多个文件的init执行顺序未定义,但同一文件中的init自上而下运行。

➡️

继续阅读