golang学习笔记11-模块化与包管理【重要】
注:本人已有C,C++,Python基础,只写本人认为的重点。
在第六节(golang学习笔记6)中,我讲了如何自定义包,包其实有两种引用方式,一种是不用模块,还有种是用模块,我用的就是后者。尚硅谷的视频(见本专栏简介)是不用模块的,但这其实是旧版本的做法,因为这个视频是18年的。在18年8月发布的1.11版本中,增加了模块管理的内容,到现在六年了,所以旧版本的方法肯定不是主流了,这里不做赘述,但是有必要强调下两者的主要区别:旧版本的自定义包必须放在gopath/src下,模块管理则没有这种限制,可以放在任意位置。但这不意味着gopath就没用了,它要用于存储下载的模块和依赖包,还有存放Go 工具,例如通过 go install 或 go get 安装的命令行工具。
综上,本节再深入讲下模块管理和讲一些包管理的细节。
一、模块管理
1.1 模块化与get命令
在你的项目根目录下打开命令行,执行如下命令:
go mod init your_module
其中your_module是自定义的模块名。执行该命令后,会出现一个模块管理文件go.mod,它的出现说明该项目已经模块化,即一个项目就是一个模块,该项目的管理都要通过这个mod文件来管理。注意,一个项目根目录只能有一个mod文件!
打开go.mod,你会看到如下内容:
module testmodgo 1.23.1
在第六节中,我讲了如何引用我在gitee上部署的模块(项目),如果成功下载,那么这里会出现require声明,说明当前模块已依赖一个外部包。go get命令具体的流程是这样的:
1.Go 先解析命令,然后尝试在指定的URL上查找对应的代码仓库,仓库不存在则报错。
2.一旦找到仓库,Go 会查找该仓库根目录下的 go.mod 文件,mod不存在则报错。
3.找到mod后,解析mod,读取模块的名称、Go 版本和依赖包。
4.下载整个模块的内容,包括项目下的所有包、文件和依赖包。
5.更新本地的go.mod,并建立本地项目和依赖包的关系,即声明依赖包。
6.生成go.sum,记录所下载模块的校验和。
到这里,相信大家对模块有了更深的认识。
1.2 规范的项目结构
规范项目有以下几个特点:
1.总项目下可以放多个子项目,子项目可以继续嵌套。
2.总项目根目录下要有一个mod文件,子项目也可以建立mod,但一个项目一般只需要一个mod。
3.总项目必须包含main文件,main可以放在根目录,也可以放在子项目下。
4.main依赖的所有外部函数都放在main之外,由专门的包实现。
5.正式项目一般都有工具包(文件夹)。
综上,一个规范的项目结构至少是这样的:
your_project/ # 项目根目录
├── go.mod # 项目模块
├── README.md # 项目说明文件
├── main.go/ # 程序入口
└── utils/ # 工具包的根目录└── utils_code.go # 工具包的实现文件
关于工具包,有几个点要注意:
1.工具包下的文件名未必要和工具包相同(go官方的某些包就是这样),但主程序入口文件名一般都用main。
2.工具包可以用别人的,也可以是自定义的,或者所有外部函数的实现都放在工具包下。
3.工具包实现时,函数名和全局变量名的首字母必须大写!否则只能在当前文件内使用,无法作为外部引用。
工具包实现后,main文件的补全示例如下:
package mainimport "testmod/utils" //模块名/包路径func main() {utils.Test()
}
注意:如果utils不在项目(mod)根目录,则要写全路径,这里因为是在根目录下,所以只需写一个包名。
二、包管理的细节
1.go没有像C++那样的重载机制,所以同一个包中不能有重复的函数名,具体来说,就是一个包下的某个文件中不能有重复的函数名,该包下的各文件之间的函数名也不能重复。有人可能说,把其中一个文件声明的package改了不行吗?当然不能!我在第二节(golang学习笔记2)中说过:同一目录下的所有go文件必须属于同一个包,即同一目录下的所有go文件必须都作一样的package声明,否则编译错误!
2.和上一点类似,一个包下的某个文件中不能有重复的全局变量名,该包下的各文件之间的全局变量名也不能重复。
3.不同包之间可以有重复的函数名和全局变量名,这可以解决不同的人想要实现的函数的名字一样,或全局变量一样的冲突,也是包的主要作用之一。
综上,如果一个项目还有子项目,子项目要建立main文件,而main文件又必须声明main,该怎么做?一定是新建目录将main文件和其他文件隔离!所以有子项目的项目结构如下:
your_project/ # 项目根目录
├── go.mod # 项目模块
├── README.md # 项目说明文件
├── subproject/ # 子项目根目录
│ └── main/ # main包根目录
│ └── main.go # 子项目程序入口
└── utils/ # 工具包的根目录└── utils_code.go # 工具包的实现文件
以上就是包管理的全部介绍了,这个很重要,希望大家牢记。