《Go 语言第一课》课程学习笔记(五)

入口函数与包初始化:搞清 Go 程序的执行次序

main.main 函数:Go 应用的入口函数

  • Go 语言中有一个特殊的函数:main 包中的 main 函数,也就是 main.main,它是所有 Go 可执行程序的用户层执行逻辑的入口函数。
    • Go 程序在用户层面的执行逻辑,会在这个函数内按照它的调用顺序展开。
    • main 函数的函数原型非常简单,没有参数也没有返回值。
    • Go 语言要求:可执行程序的 main 包必须定义 main 函数,否则 Go 编译器会报错。在启动了多个 Goroutine 的 Go 应用中,main.main 函数将在 Go 应用的主 Goroutine 中执行。
    • 不过对于 main 包的 main 函数来说,还需要明确一点,就是它虽然是用户层逻辑的入口函数,但它却不一定是用户层第一个被执行的函数。

init 函数:Go 包的初始化函数

  • Go 语言还有一个特殊函数,它就是用于进行包初始化的 init 函数了。和 main.main 函数一样,init 函数也是一个无参数无返回值的函数。
  • 如果 main 包依赖的包中定义了 init 函数,或者是 main 包自身定义了 init 函数,那么 Go 程序在这个包初始化的时候,就会自动调用它的 init 函数,因此这些 init 函数的执行就都会发生在 main 函数之前。
    • 在初始化 Go 包时,Go 会按照一定的次序,逐一、顺序地调用这个包的 init 函数。
    • 一般来说,先传递给 Go 编译器的源文件中的 init 函数,会先被执行;而同一个源文件中的多个 init 函数,会按声明顺序依次执行。
    • 当我们要在 main.main 函数执行之前,执行一些函数或语句的时候,我们只需要将它放入 init 函数中就可以了。

Go 包的初始化次序

  • Go 包是程序逻辑封装的基本单元,每个包都可以理解为是一个"自治"的、封装良好的、对外部暴露有限接口的基本单元。
    • 一个 Go 程序就是由一组包组成的,程序的初始化就是这些包的初始化。
    • 每个 Go 包还会有自己的依赖包、常量、变量、init 函数(其中 main 包有 main 函数)等。
    • 我们在阅读和理解代码的时候,需要知道这些元素在在程序初始化过程中的初始化顺序,这样便于我们确定在某一行代码处这些元素的当前状态。
  • Go 在进行包初始化的过程中,会采用"深度优先"的原则,递归初始化各个包的依赖包。
  • Go 会按照"常量 -> 变量 -> init 函数"的顺序进行初始化,执行完这些初始化工作后才正式进入程序的函数。包内的多个 init 函数按出现次序进行自动调用。

init 函数的用途

  • init 函数的第一个常用用途:重置包级变量值。init 函数就好比 Go 包真正投入使用之前唯一的"质检员",负责对包内部以及暴露到外部的包级数据(主要是包级变量)的初始状态进行检查。
  • init 函数的第二个常用用途,是实现对包级变量的复杂初始化。
  • init 函数的第三个常用用途:在 init 函数中实现"注册模式"。通过在 init 函数中注册自己的实现的模式,就有效降低了 Go 包对外的直接暴露。
相关推荐
周周记笔记16 分钟前
学习笔记:第一个Python程序
笔记·学习
丑小鸭是白天鹅18 分钟前
Kotlin协程详细笔记之切线程和挂起函数
开发语言·笔记·kotlin
潘达斯奈基~19 分钟前
《大数据之路1》笔记2:数据模型
大数据·笔记
优雅鹅28 分钟前
ARM、AArch64、amd64、x86_64、x86有什么区别?
arm开发·学习
..过云雨32 分钟前
05.【Linux系统编程】进程(冯诺依曼体系结构、进程概念、进程状态(注意僵尸和孤儿)、进程优先级、进程切换和调度)
linux·笔记·学习
咸甜适中1 小时前
rust语言 (1.88) egui (0.32.2) 学习笔记(逐行注释)(二十八)使用图片控件显示图片
笔记·学习·rust·egui
一又四分之一.1 小时前
高数基础知识(下)②
笔记
ZHANG8023ZHEN2 小时前
fMoE论文阅读笔记
论文阅读·笔记
o0o_-_2 小时前
【go/gopls/mcp】官方gopls内置mcp server使用
开发语言·后端·golang
Ro Jace2 小时前
文献阅读笔记:R&S电子战测试与测量技术文档
笔记