Go语言中多个init函数的调用顺序

发表时间: 2024-05-10 15:59

golang 多个 init 方法的执行顺序

目录结构:

> # cd /data/init

> # tree

.

├── a

│ └── a.go

├── b

│ └── b.go

├── go.mod

└── main.go

2 directories, 4 files

a/a.go

package aimport (    "fmt"    "path/filepath")func init() {    fmt.Println("a init")    dir, _ := filepath.Abs("./") // 这里的路径是以 import 导入时执行为准    fmt.Println(dir)}func Add() {    fmt.Println("a Add")}

b/b.go

package bimport (    "fmt"    "path/filepath")func init() {    fmt.Println("b init")    dir, _ := filepath.Abs("./") // 这里的路径是以 import 导入时执行为准    fmt.Println(dir)}func Add() {    fmt.Println("b Add")}

main.go

package mainimport (    "fmt"    "init/a" // 导入包的顺序 决定了 init() 函数谁先执行    "init/b")func init() {    fmt.Println("main init 1")}func init() {    fmt.Println("main init 2")}func main() {    fmt.Println("main")    a.Add()    b.Add()}

> # go run main.go

a init

/data/init

b init

/data/init

main init 1

main init 2

main

a Add

b Add

现在调整导入包的顺序

main.go

package mainimport (    "fmt"    "init/b" // 导入包的顺序 决定了 init() 函数谁先执行    "init/a")func init() {    fmt.Println("main init 1")}func init() {    fmt.Println("main init 2")}func main() {    fmt.Println("main")    a.Add()    b.Add()}

> # go run main.go

b init

/data/init

a init

/data/init

main init 1

main init 2

main

a Add

b Add

结论:

可以看出init()函数执行顺序是按照导入包的顺序执行, 而不是按照调用先后顺序执行。

init 函数的主要作用:初始化。


init 函数的主要特点:

init 函数先于 main 函数自动执行, 不能被其他函数调用;

init 函数没有输入参数、返回值;

每个包可以有多个 init 函数;

包的每个源文件也可以有多个 init 函数, 这点比较特殊;

同一个包的 init 执行顺序, golang 没有明确定义, 编程时要注意程序不要依赖这个执行顺序。

不同包的 init 函数按照包导入的依赖关系决定执行顺序。

注意: golang 使用路径时尽量使用绝对路径, 避免不必要的错误