news 2026/8/3 7:41:26

Go 语言包初始化顺序详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Go 语言包初始化顺序详解

在Go中,当程序启动时,包初始化过程遵循特定顺序:

1、当存在 import 包,会递归先初始化依赖包,依此再初始化第二个 import 包

package main import ( "fmt" _ "inittest/dao" // 导入 dao 包, 会先初始化该包的内容,再执行主函数单元的 init() ) // 主函数单元 init func init() { fmt.Println("主函数单元 init") } func main() { fmt.Println("主函数单元执行 main 函数") } /* 执行结果: dao 包下的 order 文件单元全局变量创建: OrderInfo dao 包下的 order 文件单元 init 主函数单元 init 主函数单元执行 main 函数 */

2、单个包内的初始化顺序为先初始化变量,再执行 init 函数。

package main import ( "fmt" ) type Conf struct { } // 新建全局变量,会优先于 init() 函数初始化 var conf = NewConfig() func NewConfig() *Conf { fmt.Println("") fmt.Println("主函数单元全局变量创建: conf") return &Conf{} } // 主函数单元 init func init() { fmt.Println("主函数单元 init") } func main() { fmt.Println("主函数单元执行 main 函数") if conf == nil { fmt.Println("配置项为空") return } } /* 执行结果: 主函数单元全局变量创建: conf 主函数单元 init 主函数单元执行 main 函数 */

特别注意:

当一个包存在多个文件时,go 的初始化规则是:

①先处理所有文件的包级别变量(按文件中的出现顺序,但文件间的顺序不确定)

②再执行所有文件的 init 函数(按文件名字母顺序)

以下为完整示例,其中一个包中含有多个文件,项目结构如下:

inittest/

├── main.go # 项目入口文件

├── go.mod # Go 模块依赖配置

├── dao/ # 数据访问层 (Data Access Object)

│ └── order.go # 订单相关数据操作

└── root/ # 根包/初始化包

├── db.go # 数据库初始化配置

└── log.go # 日志初始化配置

执行结果:

包初始化顺序:

完整代码示例:

// 文件位置 inittest\main.go package main import ( "fmt" "inittest/dao" // 导入 dao 包 _ "inittest/root" // 导入 root 包, root 包下有多个文件单元, 会将所有文件单元的 import 包递归初始化,然后再将所有文件的变量初始化,最后将所有文件的 init 函数执行 ) type Conf struct { } // 新建全局变量 var conf = NewConfig() func NewConfig() *Conf { fmt.Println("") fmt.Println("主函数单元全局变量创建: conf") return &Conf{} } // 主函数单元 init func init() { fmt.Println("主函数单元 init") } func main() { fmt.Println("主函数单元执行 main 函数") if conf == nil { fmt.Println("配置项为空") return } if dao.OrderInfo != nil { fmt.Println("主函数单元获取 dao 包下的全局变量 OrderInfo 成功") return } }
// 文件位置 inittest\root\log.go package root import "fmt" type Logger struct { } // 新建全局变量 var Log = NewLogger() func NewLogger() *Logger { fmt.Println("root 包下的 log 文件单元全局变量创建: Log") return &Logger{} } func init() { fmt.Println("root 包下的 log 文件单元 init") }
// 文件位置 inittest\root\db.go package root import "fmt" type DB struct { } // 新建全局变量 var Db = NewDB() func NewDB() *DB { fmt.Println("root 包下的 db 文件单元全局变量创建: db") return &DB{} } func init() { fmt.Println("root 包下的 db 文件单元 init") }
// 文件位置 inittest\dao\order.go package dao import "fmt" type Order struct { } // 新建全局变量 var OrderInfo = NewOrder() func NewOrder() *Order { fmt.Println("dao 包下的 order 文件单元全局变量创建: OrderInfo") return &Order{} } func init() { fmt.Println("dao 包下的 order 文件单元 init") fmt.Println("") }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/3 0:15:30

文理分科选对学习机:主流机型的适配指南

一、文理分科下,学习机选择的核心逻辑高中文科重知识体系构建、材料分析与表达输出,理科强逻辑拆解、错题闭环与实验理解,二者对学习机的需求存在本质差异:文科刚需:教材同步讲解的细致度、海量题库的分类检索&#xf…

作者头像 李华
网站建设 2026/8/2 15:47:20

深入探索 Spring Boot3 中 Profiles 多环境配置

前言在当今复杂的软件开发领域,一个应用往往需要在开发、测试、生产等多个环境中运行,每个环境的配置需求大相径庭。想象一下,在开发环境中,你可能需要频繁调试,所以希望日志更加详细,数据库连接到本地易于…

作者头像 李华
网站建设 2026/8/3 11:22:32

Wan2.2-T2V-A14B能否理解隐喻性语言?‘心如刀割’如何呈现?

Wan2.2-T2V-A14B能否理解“心如刀割”?当AI开始读懂你心里的痛 💔 你有没有试过把一句诗、一段情绪,丢进AI视频生成器里,然后期待它“懂你”? 比如输入“心如刀割”——不是字面意思的心脏被刀切开,而是一种…

作者头像 李华
网站建设 2026/8/2 16:34:12

spRAG开源项目:5分钟快速安装与使用终极指南

spRAG开源项目:5分钟快速安装与使用终极指南 【免费下载链接】spRAG RAG framework for challenging queries over dense unstructured data 项目地址: https://gitcode.com/gh_mirrors/sp/spRAG spRAG开源项目是一个专为处理复杂非结构化数据设计的检索增强…

作者头像 李华
网站建设 2026/8/2 17:27:52

【运维】StarRocks 跨集群数据迁移工具 - 基于快照进行的快速迁移

文章目录一、整体迁移逻辑1.1 架构概览1.2 核心工作流程阶段 1:初始化阶段 2:启动工作线程阶段 3:周期性执行1.3 任务生成逻辑1.3.1 元数据同步1.3.2 DDL 任务生成1.3.3 数据复制任务生成1.4 任务执行流程1.4.1 DDL 任务执行1.4.2 数据复制任…

作者头像 李华