在运行任何init函数之前,需要加载.env文件



我试图通过在main方法中调用godotenv.Load来加载环境变量,但问题是我在其他包中有init函数,它们在从.env文件加载环境变量之前运行,因此造成了麻烦。

对此有什么变通办法吗?

以下是Golang包初始化的规范:https://go.dev/ref/spec#Package_initialization

简而言之,对于给定的包,

  1. 当前包导入的所有包都按照源文件名的词法顺序初始化,然后按照在每个源文件中导入的顺序初始化。

  2. 当前包中的所有包级别变量都按依赖关系顺序进行初始化。

  3. 然后,当前包中定义的所有init()函数都按源文件名的词法顺序执行,然后在每个文件中按文档顺序执行。

  4. 一旦初始化了所有包,就会调用main()函数,开始执行程序。

根据规范,

包初始化——变量初始化和init函数的调用——在单个goroutine中按顺序发生,每次一个包。

您所需要做的就是确保环境变量的加载/设置发生在首先初始化的包中但是请注意go fmt将按字母顺序排列您的imports

因此,给定一个包含4个包的程序,mainalphabravocharlie

依赖关系为:

  • main导入alphabravo,并且
  • alpha导入charlie

并且每个包具有多个CCD_ 17函数(源代码如下(,执行go run main.go将以下内容写入控制台:

charlie/main.go: init: 1
charlie/main.go: init: 2
charlie/main.go: init: 3
alpha/main.go: init: 1
alpha/main.go: init: 2
alpha/main.go: init: 3
bravo/main.go: init: 1
bravo/main.go: init: 2
bravo/main-.go: init: 3
main.go: init: 1
main.go: init: 2
main.go: init: 3
main(): executing

./main.go

package main
import (
"fmt"
"some-host/init-example/alpha"
"some-host/init-example/bravo"
)
func init() {
fmt.Println("main.go: init: 1")
}
func init() {
fmt.Println("main.go: init: 2")
}
func main() {
fmt.Println("main(): executing")
alpha.DoSomething()
bravo.DoSomething()
}
func init() {
fmt.Println("main.go: init: 3")
}

./alpha/alpha.go

package alpha
import (
"fmt"
"some-host/init-example/charlie"
)
func init() {
fmt.Println("alpha/main.go: init: 1")
}
func init() {
fmt.Println("alpha/main.go: init: 2")
}
func DoSomething() {
charlie.DoSomething()
}
func init() {
fmt.Println("alpha/main.go: init: 3")
}

./bravo/bravo.go

package bravo
import "fmt"
func init() {
fmt.Println("bravo/main.go: init: 1")
}
func init() {
fmt.Println("bravo/main.go: init: 2")
}
func DoSomething() {
}
func init() {
fmt.Println("bravo/main-.go: init: 3")
}

./charlie/charlie.go

package charlie
import "fmt"
func init() {
fmt.Println("charlie/main.go: init: 1")
}
func init() {
fmt.Println("charlie/main.go: init: 2")
}
func DoSomething() {
}
func init() {
fmt.Println("charlie/main.go: init: 3")
}

最新更新