Go 包管理相关
虽然在公司实习的时候绝大多都是在写 Go,但是没有深入了解过 Go 项目管理的相关知识,所以总结梳理下。
我的新书《LangChain编程从入门到实践》 已经开售!推荐正在学习AI应用开发的朋友购买阅读!
Go 程序初始化顺序
- Go 程序中通常包含包、常量、变量、init()、main()等元,同时存在多个包时,包之间存在依赖关系,他们之间的执行顺序如下。
包的执行顺序
- main 包中的 go 文件默认总是会被先执行,同包下其他 go 文件,按照文件名“从小到大”排序顺序执行。
- 其他的包只有被 main 包 import 才会执行,按照 import 的先后顺序执行。
- 被递归 import 的包的初始化顺序与 import 顺序相反,因此 main 包总是被最后一个初始化,因为它总是依赖别的包。
- 一个包被其它多个包 import,但只能被初始化一次。
init 和 main 函数
- init()、main() 是 go 语言中的保留函数,两个函数在 go 语言中相同点:两个函数在定义时不能有任何的参数和返回值,只能由 go 程序自动调用,不可以被引用。不同点在于 init 可以应用于任意包中,且可以重复定义多个,main 函数只能用于 main 包中,且只能定义一个。
- 对同一个 go 文件的 init() 调用顺序是从上到下的,对同一个 package 中的不同文件,将文件名按字符串进行“从小到大”排序,之后顺序调用各文件中的init()函数。
使用 Modules
- Modules官方定义为:模块是相关Go包的集合。modules是源代码交换和版本控制的单元。 go命令直接支持使用modules,包括记录和解析对其他模块的依赖性。modules替换旧的基于GOPATH的方法来指定在给定构建中使用哪些源文件。
设置 GO111MODULE
- GO111MODULE 有三个值:off, on和auto(默认值)。
- GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
- GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录下查找。
- GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:当前目录在GOPATH/src之外且该目录包含go.mod文件,当前文件在包含go.mod文件的目录下面。
- 当modules 功能启用时,依赖包的存放位置变更为$GOPATH/pkg,允许同一个package多个版本并存,且多个项目可以共享缓存的 module
项目中使用
- 使用
go mod init
初始化生成go.mod
文件,go.mod文件一旦创建后,它的内容将会被 go toolchain 全面掌控。go toolchain 会在各类命令执行时,比如go get、go build、go mod 等修改和维护go.mod文件。 - 执行 go run 运行代码会发现 go mod 会自动查找依赖自动下载。
- go mod 安装 package 的原则是先拉最新的 release tag,若无 tag则拉最新的 commit,go 会自动生成一个 go.sum 文件来记录 dependency tree。
- go.mod 提供了module, require、replace和exclude 四个命令:
- module 语句指定包的名字(路径)
- require 语句指定的依赖项模块
- replace 语句可以替换依赖项模块
- exclude 语句可以忽略依赖项模块
- go get 升级
- 一个完善的 Go 项目经常会执行可以用来执行:测试、编译、运行、语法检查等命令。
- 对应到 Makefile 也应该支持这些命令。
- Makefile 构建工具,大大的简化了构建项目的难度。真实的生产环境下,需要使用到CI/CD(持续集成和持续部署), 所以 Makefile 通常用来和 CI 工具配合使用。
- 新合并的代码,先触发单元测试,静态检查等,在执行 CI 脚本成功之后,再构建镜像,推送镜像到服务器上,完成持续集成和持续部署一整套流程。
参考链接
- go mod 使用
- 适用于 Go 项目的 Makefile 指南