深入理解Go语言init方法的执行顺序

 更新时间:2025年09月18日 09:45:00   作者:liushen0528  
本文主要介绍了深入理解Go语言init方法的执行顺序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、什么是init方法?

init 是 Go 语言中的特殊函数,无需手动调用,由运行时自动执行。每个 .go 文件可以包含多个 init 函数。init方法没有参数和返回值。

示例代码如下:

func init() {
    // 初始化逻辑
}

init 函数在 main() 函数之前执行。当包被导入时,系统会自动调用所有 init 函数,其调用顺序为:先执行依赖包(被导入的包)的 init 函数,再执行当前包的 init 函数,最后执行 main() 函数。

二、init方法特性

1)执行顺序规则‌‌

(1)同一个文件多个init方法执行顺序

同一文件内的 init 函数则按照代码编写顺序执行,代码示例如下:

var config string
func init() {
    config = "config1"
    fmt.Println("init 1:", config)
}
func init() {
    fmt.Println("init 2: additional setup")
}
func main() {
    fmt.Println("main:", config)
}

执行结果如下:

(2)同一个包内执行顺序

同一包内的文件会按照文件名进行字典序排序,并按此顺序执行各文件中的 init 函数。如包内包括a.go和b.go两个文件,优先执行a.go中的init方法,在执行b.go中的init方法。

代码示例如下:

// a.go
package main
import "fmt"
func init() {
    fmt.Println("a.go init")
}
// b.go
package main
import "fmt"
func init() {
    fmt.Println("b.go init")
}
// main.go
package main
import "fmt"
func init() {
    fmt.Println("main init")
}
func main() {
    fmt.Println("main")
}

运行结果如下:

(3)跨包执行顺序

对于跨包依赖的情况,遵循"深度优先"原则,即最后被依赖的包会最先完成初始化。例如在 main → A → B → C 的依赖链中,初始化顺序为 C → B → A → main。

代码包结构如下:

代码示例如下:

// a.go
package A
import (
    "fmt"
    "te/src/B"
)
func init() {
    fmt.Println("a.go init")
}
func PrintA() {
    fmt.Println("print a")
    B.PrintB()
}
// b.go
package B
import (
    "fmt"
    "te/src/C"
)
func init() {
    fmt.Println("b.go init")
}
func PrintB() {
    fmt.Println("print b")
    C.PrintC()
}
// c.go
package C
import "fmt"
func init() {
    fmt.Println("c.go init")
}
func PrintC() {
    fmt.Println("print c")
}
// main.go
package main
import (
    "fmt"
    "te/src/A"
)
func init() {
    fmt.Println("main init")
}
func main() {
    fmt.Println("main")
    A.PrintA()
}

执行结果如下:

2)与变量初始化的关系‌

包级变量初始化优先于 init 执行。示例代码如下:

// 先执行
var config = initConfig()

func initConfig() string {
    fmt.Println("initConfig")
    return "initConfig"
}

// 后执行
func init() {
    config = "init"
    fmt.Println("init()", config)
}

func main() {
    fmt.Println(config)
}

运行结果如下:

三、init应用场景

场景用途说明
全局变量初始化复杂配置加载,如数据库连接池设置
驱动/插件注册数据库驱动注册
副作用代码执行日志系统初始化,如设设置日志级别和输出格式
确保初始化顺序依赖资源预加载,如配置文件读取优先于服务启动

四、init使用注意事项

1)避免滥用:过度使用 init 函数会降低代码可读性,建议采用显式初始化方式。对于复杂逻辑,应封装为普通函数并在 main 中显式调用。

2)线程安全:所有 init 函数都在同一个 goroutine 中执行,因此无需加锁。

3)初始化方法应仅包含不会失败的操作 。

到此这篇关于深入理解Go语言init方法的执行顺序的文章就介绍到这了,更多相关Go语言init执行顺序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go for-range 的 value值地址每次都一样的原因解析

    Go for-range 的 value值地址每次都一样的原因解析

    循环语句是一种常用的控制结构,在 Go 语言中,除了 for 关键字以外,还有一个 range 关键字,可以使用 for-range 循环迭代数组、切片、字符串、map 和 channel 这些数据类型,这篇文章主要介绍了Go for-range 的 value值地址每次都一样的原因解析,需要的朋友可以参考下
    2023-05-05
  • golang提示dial tcp 172 .217.163.49:443: connectex: A connection attempt failed解决

    golang提示dial tcp 172 .217.163.49:443: connectex: A con

    这篇文章主要为大家介绍了golang提示dial tcp 172 .217.163.49:443: connectex: A connection attempt failed解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • Golang空结构体struct{}用途,你知道吗

    Golang空结构体struct{}用途,你知道吗

    这篇文章主要介绍了Golang空结构体struct{}用途,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • 基于go语言实现图片验证码的代码示例

    基于go语言实现图片验证码的代码示例

    这篇文章主要为大家详细介绍了基于go语言实现图片验证码的代码示例,文中的示例代码简洁易懂,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-10-10
  • golang的tunny的用法示例教程

    golang的tunny的用法示例教程

    这篇文章主要为大家介绍了golang的tunny的用法示例教程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • 基于gin的golang web开发之认证利器jwt

    基于gin的golang web开发之认证利器jwt

    这篇文章主要介绍了基于gin的golang web开发之认证利器jwt,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • 安装Sublime Text支持Go插件的方法步骤

    安装Sublime Text支持Go插件的方法步骤

    本文主要介绍了安装Sublime Text支持Go插件的方法步骤,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • Go实现MD5加密的三种方法小结

    Go实现MD5加密的三种方法小结

    本文主要介绍了Go实现MD5加密的三种方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • Goland调节字体大小的设置(编辑区,terminal区,页面字体)

    Goland调节字体大小的设置(编辑区,terminal区,页面字体)

    这篇文章主要介绍了Goland调节字体大小的设置(编辑区,terminal区,页面字体),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Golang精编49面试题汇总(选择题)

    Golang精编49面试题汇总(选择题)

    这篇文章主要介绍了Golang精编49面试题汇总(选择题),本文章内容详细,具有很好的参考价值,希望对大家有所帮助,需要的朋友可以参考下
    2023-01-01

最新评论