Go语言中的init函数的执行时机

init函数的执行时机

  • 这个涉及到
    • init 函数的作用和执行顺序
    • 相同个文件和不同文件中以及在不同的包中init的执行顺序
    • go文件初始化的顺序

一、init 函数的作用和执行顺序

作用

  • init 函数是用于程序执行前做包的初始化的函数,比如初始化包里面的一些变量等等
  • 通常在项目工程中,用来做 Http Server的初始化,DB的初始化, redis 初始化等等中间件的初始化

执行顺序

  • 在同一个 Go 文件可以重复定义多个 init 方法, 它的执行顺序是按照代码编写的顺序依次执行
  • 在同一个 package 里面,不同文件中的 init 方法的执行是按照文件名的顺序先后执行各个文件当中的init方法的
  • 对于不同的package
    • 如果不相互依赖的话,就会按照main包里面 import 的顺序,调用各个包中的init函数
    • 存在依赖,调用顺序就变成最后被依赖的会最先被初始化
      • 比如我们的导入顺序是在main函数中依赖a模块
      • a模块又依赖b模块,b模块又依赖c模块
      • 初始化的顺序就会先初始化c这个包再初始化b这个包再初始化a这个包
      • 最后执行main方法

测试 同一个 Go 文件可以重复定义多个 init 方法

main.go

package mainimport (. "fmt"
)// 同一个go文件中的多个init方法,按照定义的顺序执行
func init() {Println(1)
}func init() {Println(2)
}func main() {}
  • 运行 $ go run main.go
  • 输出
    1
    2
    
  • 可见,按照 定义顺序保持一致

二、相同个文件和不同文件中以及在不同的包中init的执行顺序


2.1 测试同一个包中,不同的文件中的init执行顺序

  • init-demo/
    • go.mod
    • main.go
    • pkg/
      • a.go
      • b.go
      • pkg.go

pkg/a.go

package pkg
import . "fmt"func init() {Println("pkg-a")
}

pkg/b.go

package pkg
import . "fmt"func init() {Println("pkg-b")
}

pkg/pkg.go

package pkg
import . "fmt"var Pkg = "pkg"func init() {Println("pkg-pkg")
}

main.go

package mainimport (. "fmt""init-demo/pkg"
)// 同一个go文件中的多个init方法,按照定义的顺序执行
func init() {Println(1)
}func init() {Println(2)
}func main() {println(pkg.Pkg)
}
  • 执行 $ go run main.go
  • 输出
    pkg-a
    pkg-b
    pkg-pkg
    1
    2
    pkg
    
  • main包依赖pkg包,先按照pkg中包名的 ascII 码的顺序依次执行init, 再执行 main包中的任务
  • 我们知道,先执行 pkg/a.go 中的init, 再执行 pkg/b.go中的init, 再执行 pkg/pkg.go 中的init,最终执行main方法中的任务

测试 导入不同的包有和没有依赖其他包的情况

  • init-demo/
    • go.mod
    • main.go
    • pkg1/
      • pkg1.go
    • pkg2/
      • pkg2.go

pkg1/pkg.go

package pkg1
import "fmt"var Pkg1 = "pkg1"func init() {fmt.Println("pkg1-pkg1")
}

pkg2/pkg.go

package pkg2
import "fmt"
import "init-demo/pkg3"var Pkg2 = "pkg2"func init() {fmt.Println("pkg2-pkg2")
}

pkg3/pkg.go

package pkg3
import ("fmt"
)func init() {fmt.Println("pkg3-pkg3")
}

main.go

package mainimport (. "fmt""init-demo/pkg1""init-demo/pkg2"
)// 同一个go文件中的多个init方法,按照定义的顺序执行
func init() {Println(1)
}func init() {Println(2)
}func main() {println(pkg1.Pkg1)println(pkg2.Pkg2)
}
  • 执行 $ go run main.go

  • 输出

    pkg1-pkg1
    pkg3-pkg3
    pkg2-pkg2
    1
    2
    pkg1
    pkg2
    
  • 先执行pkg1的init,因为在main中被最先引入,优先按照import的顺序执行,接着是pkg3的init, 接着是pkg2的init

  • 因为 pkg3被pkg2引用,这样pkg3的init优先于pkg2的init执行

  • 最后是main包中的init和main函数的方法

三、go文件初始化的顺序

  • 会先初始化引入的包
  • 再初始化当前包中的常量变量
  • 接着初始化当前包中的init函数
  • 最后执行main函数
  • 注意
    • 一个包被引用多次,这个包的init函数只会执行一次 (按照之前的规则的执行顺序下的第一次)
    • 所有的 init 函数都会在同一个 goroutine 内执行
    • 注意包的循环导入问题,会出现异常: import cycle not allowed
  • 这里不再举例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/601685.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML5大作业-精致版个人博客空间模板源码

文章目录 1.设计来源1.1 博客主页界面1.2 博主信息界面1.3 我的文章界面1.4 我的相册界面1.5 我的工具界面1.6 我的源码界面1.7 我的日记界面1.8 我的留言板界面1.9 联系博主界面 2.演示效果和结构及源码2.1 效果演示2.2 目录结构2.3 源代码 源码下载 作者:xcLeigh …

从零学Java 包装类

Java 包装类 文章目录 Java 包装类1 什么是包装类?2 为什么需要包装类?3 包装类对应4 包装类的基本操作4.1 装箱4.2 拆箱4.3 自动装箱/拆箱面试题整数缓冲区 5 包装类的类型转换5.1 字符串转基本数据类型5.2 基本数据类型转字符串5.2.1 方法一: 号字符串拼接5.2.2 方法二: 使…

在MS中基于perl脚本实现氢键统计

氢原子与电负性大的原子X以共价键结合,若与电负性大、半径小的原子Y(O F N等)接近,在X与Y之间以氢为媒介,生成X-H…Y形式的一种特殊的分子间或分子内相互作用,称为氢键。 氢键通常是物质在液态时形成的&…

【华为OD真题 Python】解密犯罪时间

文章目录 题目描述输入描述输出描述示例1输入输出说明示例1输入输出说明示例2输入输出说明备注代码实现题目描述 警察在侦破一个案件时,得到了线人给出的可能

第1章 线性回归

一、基本概念 1、线性模型 2、线性模型可以看成:单层的神经网络 输入维度:d 输出维度:1 每个箭头代表权重 一个输入层,一个输出层 单层神经网络:带权重的层为1(将权重和输入层放在一起) 3、…

数据库设计——DML

D M L \huge{DML} DML DML:数据库操作语言,用来对数据库中的数据进行增删改查。 增(INSERT) 使用insert来向数据库中增加数据。 示例: -- DML : 数据操作语言 -- DML : 插入数据 - insert -- 1. 为 tb_emp 表的 us…

Kubernetes二进制部署 单节点

一、环境准备 k8s集群master1:192.168.229.90 kube-apiserver kube-controller-manager kube-scheduler etcd k8s集群node1: 192.168.229.80 kubelet kube-proxy docker flannel k8s集群node2: 192.168.229.70 kubelet kube-proxy docker flannel 至少2C2G 常见的k…

Flutter3.X基础入门教程(2024完整版)

Flutter介绍: Flutter是谷歌公司开发的一款开源、免费的UI框架,可以让我们快速的在Android和iOS上构建高质量App。它最大的特点就是跨平台、以及高性能。 目前Flutter已经支持 iOS、Android、Web、Windows、macOS、Linux的跨平台开发。 教程所讲内容支持…

独立式键盘控制步进电机实验

#include<reg51.h> //包含51单片机寄存器定义的头文件 sbit S1P1^4; //将S1位定义为P1.4引脚 sbit S2P1^5; //将S2位定义为P1.5引脚 sbit S3P1^6; //将S3位定义为P1.6引脚 unsigned char keyval; //储存按键值 unsigned char ID; …

bat批处理文件_命令汇总(2)

文章目录 1、换行2、返回上一级目录cd..3、隐藏指令回显echo off4、开启指令回显echo on5、用关闭echo off指令本身的回显6、echo提示信息 1、换行 cd.. echo. echo. echo. pause2、返回上一级目录cd… 3、隐藏指令回显echo off echo off echo hello1 echo hello2 pause4、开…

tomcat session cookie值设置逻辑

tomcat session cookie 值设置&#xff0c;tomcat jsessionid设置 ##调用request.getSession() Controller RequestMapping("/cookie") public class CookieController {RequestMapping("/tomcatRequest")ResponseBodypublic String tomcatRequest(HttpS…

软件测试|什么是Python构造方法,构造方法如何使用?

构造方法&#xff08;Constructor&#xff09;是面向对象编程中的重要概念&#xff0c;它在创建对象时用于初始化对象的实例变量。在Python中&#xff0c;构造方法是通过特殊的名称__init__()来定义的。本文将介绍Python构造方法的基本概念、语法和用法。 什么是构造方法&…

轻松获取CHATGPT API:免费、无验证、带实例

免费获取和使用ChatGPT API的方法 快速开始&#xff1a;视频教程 章节一&#xff1a;GPT-API-Free开源项目介绍 GPT-API-Free 是一个开源项目&#xff0c;它提供了一个中转API KEY&#xff0c;使用户能够调用多个GPT模型&#xff0c;包括gpt-3.5-turbo、embedding和gpt-4。这…

记一次服务器被入侵的排查过程

起因 阿里云安全中心报告了告警信息&#xff0c;同时手机短信、邮件、电话也接收到了来自阿里云的风险通知&#xff0c;感觉这方面阿里云还是不错。 排查及解决过程 这条wget指令究竟是怎么被运行的 我无法定位到攻击人员是通过什么样的方式让我的java程序执行了wget这条指…

JavaScript中绑定事件的方法

在JavaScript中&#xff0c;绑定事件的方法主要有三种&#xff1a; 直接在HTML元素中通过onclick&#xff0c;onload等属性直接绑定事件处理函数。使用DOM0级事件绑定&#xff0c;即直接在JavaScript代码中通过element.onclick function()或者element.addEventListener(click…

地平面--高速布线

https://baijiahao.baidu.com/s?id1764139038516816855&wfrspider&forpc 概念 回顾传输线&#xff0c;由任意两条有一定长度的导线组成&#xff0c;一条为信号路径&#xff0c;一条为返回路径。基本电路理论告诉我们&#xff0c;信号是由电流传播的&#xff0c;明确的…

ECMAScript简介及特性

ECMAScript&#xff0c;通常简称为ES&#xff0c;是一种由ECMA&#xff08;欧洲计算机协会&#xff09;国际组织标准化和推动的脚本语言规范。它被广泛用于Web浏览器和服务器端编程&#xff0c;是JavaScript的基础。 ECMAScript的起源可以追溯到1996年&#xff0c;当时Netscape…

vue2 消息弹框

父页面 <template><div style"margin-top: 20px"><div class"nav-style msg-style"><el-badge :value"value" :max"99" class"num" v-if"value > 0"><i class"el-icon-bell&…

树莓派 GPIO 教程

1.树莓派引脚分类 电源引脚:5v&#xff0c;3.3v&#xff0c;GND(Ground)。常规GPIO控制引脚:可以通过编写程序控制这些引脚的高低电平。特殊GPIO通讯引脚: SPI通讯&#xff0c;12C通讯&#xff0c;TxD/RxD串口通讯。 2.树莓派引脚编码 功能物理引脚&#xff1a;这种编码方式…

深度生成模型之图像翻译GAN ->(个人学习记录笔记)

文章目录 深度生成模型之图像翻译GAN图像翻译的应用1. 风格迁移2. 数据增强3. 经典图像任务4. 内容创作5. 人脸图像编辑6. 人体图像编辑 图像翻译模型1. 有监督图像翻译模型2. 无监督图像翻译模型3. 多域图像翻译模型 深度生成模型之图像翻译GAN 图像翻译的应用 1. 风格迁移 …