zhngs

zhngs

go注解(9)——工程管理

一.包管理
1.包声明
2.包导入
3.包初始化
4.包可见性
二.依赖管理
1.go环境变量
2.go module
3.go.mod语法
4.版本号管理
三.go工具
1.go mod
2. go test
四.创建一个go项目

一.包管理

把相同的功能放到一个目录,就是一个包

go语言工程管理的基本单位是包,一个包给它的声明提供一个独立的命名空间

1.包声明

  • 每一个go源文件开头都需要进行包声明,表示该源文件属于这个包
  • 一个文件夹下可以有多个源文件,但是只能有一个包

2.包导入

  • 使用import语句进行导入,有两种特殊情况需要注意:重命名导入和空导入。重命名导入的目的是为了解决包重名的问题;空导入是因为go语言如果导入的包的名字没有被引用,会产生编译错误,而有时候我们确实不会引用某个包,但是需要对包级别的变量执行初始化表达式求值,并执行init函数,这种情况就用到空导入

    import ( "crypto/rand" mrand "math/rand" //重命名导入 _ "image/png" //空导入 )
  • note:当导入一个包时,编译器去哪获得这个包?首先会去$GOROOT下查找标准库,如果找不到,会向上寻找go.mod文件,根据其中的依赖进行导入包

3.包初始化

  • 包初始化,首先初始化包级变量,然后如果包内有特殊函数init,再调用init函数,这时候一个包初始化完毕

  • go语言的包依赖是一个有向无环图,加入包p导入了包q,那么可以保证包q会在包p之前初始化完成。并且因为是有无环图,包可以独立编译甚至并行编译,go工程的编译速度非常快

4.包可见性

  • 包通过一个简单的规则来控制包内变量和声明的可见性:导出的标识符以大写字母开头

二.依赖管理

1.go环境变量

  • 命令行执行go env可以查看go的环境变量,下面是几个比较重要的环境变量

    $ go env GO111MODULE="on" //开启go module模式 GOPATH="/root/go" //用来存储下载的源码和命令 GOROOT="/usr/lib/golang" //go发行版的根目录,其中提供了所有标准库的包 GOPROXY="https://goproxy.cn,direct" //国内使用go需要设置代理,不然有些包无法下载

2.go module

  • 自go1.13版本开始,go module成为默认依赖管理工具,取代了旧的GOPATH模式。当环境变量GO111MODULE="on"时go module被开启

  • go module意味着项目本身是一个模块,一个模块下可以包含多个包

  • 在go moudule模式下,项目根目录下有go.mod文件,内容形式大致如下

    module example.com/mymodule go 1.14 require ( example.com/othermodule v1.2.3 example.com/thismodule v1.2.3 example.com/thatmodule v1.2.3 ) replace example.com/thatmodule => ../thatmodule exclude example.com/thismodule v1.3.0
  • 和go.mod文件有一个相匹配的文件go.sum,同样是在项目根目录下,记录了项目依赖包的哈希值,如果依赖包的哈希值和go.sum里面的哈希值不匹配,go会拒绝构建,防止了依赖包被篡改的可能

3.go.mod语法

  • go.mod里一共6个关键字:module, go, require, replace, exclude, retract,重点掌握module, go, require即可

  • module:该关键字的语法是module module-path,意思就是表明该模块的路径

  • go:关键字语法是go minimum-go-version,记录编译运行某项目的最小go版本

  • require:关键字语法是require module-path module-version,用来记录项目依赖

  • replace:关键字语法是replace module-path [module-version] => replacement-path [replacement-version],用另一个模块版本或本地目录替换特定版本(或所有版本)的模块内容

  • exclude:关键字语法是exclude module-path module-version,指定要从当前模块的依赖关系图中排除的模块或模块版本

  • retract:一般用不到,主要用来撤回版本

4.版本号管理

  • 版本号形式为v1.4.0-beta.2,1为主要版本号,4为次要版本号,0为补丁版本号,beta.2为预发布标识

| 版本阶段 | 例子 | 信息 | | ----- | ----------------- | -------------------------------------------------------------------- | | 开发中 | 伪版本号或者v0.x.x | 表示模块正在开发中且不稳定,不提供向后兼容。伪版本号的写法类似于v0.0.0-20170915032832-14c0d48ead0c | | 主要版本 | v1.x.x | 表示向后不兼容的版本,每一个大版本的发布都不保证向后兼容之前的主要版本 | | 次要版本 | vx.4.x | 会更改模块的公共api,但不破坏调用代码,保证向后兼容性和稳定性 | | 补丁版本 | vx.x.1 | 补丁版本不影响模块的公共api或者依赖,保证向后兼容 | | 预发布版本 | vx.x.x-beta.2 | 表示一个预发布里程碑,不提供稳定性保证 |

  • note:当主要版本>=2的时候,go.mod的module关键字的内容需要附加主要版本号。例如会从module example.com/mymodule修改为module example.com/mymodule/v2。这样做的原因是主要版本的发布不会向后兼容,提醒代码开发者显式修改go.mod文件中的依赖,对于依赖管理更加友好

三.go工具

1.go mod

  • go mod命令提供了对模块的操作能力

    go mod download # 下载依赖的module到本地cache(默认为$GOPATH/pkg/mod目录) go mod init # 初始化当前文件夹, 创建go.mod文件

2. go test

  • go test是对包的测试命令,在一个包中,以_test.go结尾的文件不是go build命令的编译目标,而是go test的编译目标
  • go test工具会扫描*test.go文件来寻找特殊函数,并生成一个临时的main包来调用它们,然后编译和运行,并汇报结果,最后清空临时文件

四.创建一个go项目

  • 首先创建一个目录,然后进入目录执行go mod init命令,一个go项目就创建完成

    $ mkdir greetings $ cd greetings $ go mod init greetings # 这句命令创建了go.mod文件,并将模块命名为greetings go: creating new go.mod: module example.com/greetings
  • 如果想要添加依赖包,可以在go.mod文件中添加依赖,然后执行go mod download;也可以使用go get packagename@v1.0命令,可以自动更新go.mod文件