This article was last updated on <span id="expire-date"></span> days ago, the information described in the article may be outdated.
Go 项目结构和 Go mod 最佳实践
项目目录
|-- go-test
|--bin 存放编译后的可执行文件
|--pkg 存放编译后的包文件
|--src 存放项目源文件
一般地 bin 和 pkg 目录可以不创建,go 命令会自动创建(爽否?),只需要创建 src 目录放代码即可。
环境变量
- GOROOT:安装的
go
路径 - GOPATA:项目的根目录
go-test
细心的人注意到,这里有一个Project GOPATH
,还有一个Global GOPATH
,把你的项目配置在Project GOPATH
里,每个项目都不一样,创建另一个项目时这个路径要配置成新项目的。
Global GOPATH
可以弄一个公共项目,以后就把第三方的包直接装到这里,就可以自动在你的项目里引用了。
引用包
|____src
| |____main
| | |____calc
| | | |____add.go
| | |____main.go
注意点
add.go
中的 Add 函数名首字母必须大写,只有大写的才是 Public 权限,外面的包才能访问,否则只能自己文件夹下代码才能访问。add.go
的改名为 addyyy.go 也可以,查找 add 包的时候,并不会根据 add.go 这个文件名来查找。而是根据文件夹名来查找,一个文件夹下的所有文件都属于同一个包。所以函数变量自然不能重复。main
中调用add.Add(1,2)
时,add 是包, 必须跟add.go
中的package
处的包名一致,否则报错。- import 后, 根据
GOROOT
和GOPATH
查找对应的包,src 这个目录名可不是能随便取的。
引用第三方项目
Go mod 包管理工具
Why?
- 使用 go mod 仓库中可以不用再上传依赖代码包,防止代码仓库过大浪费以及多个项目同时用包时的浪费。
- 可以管理引用包的版本,这一点是 gopath(src 模式)和
vendor
做不到的 - 如果依赖
GOPATH
不同项目如果引用了同一个软件包的不同版本,就会造成编译麻烦
gopath 是 go 之前的默认策略,每个项目在运行时都要严格放在**src
目录下,而 go mod 不用。**
Go mod
的优点:
- 自动下载依赖包。
- 项目不必放在
$GOPATH/src
内了。 - 项目内会生成一个
go.mod
文件,列出包依赖。 - 第三方包会准确的指定版本号。
- 对于已经转移的包,可以用
replace
申明替换,不需要改代码。 - 在使用模块的时候,GOPATH 是无意义的,不过它还是会把下载的依赖储存在
$GOPATH/pkg/mod
中,也会把 go install 的结果放在$GOPATH/bin
中。
配置
# 设置 gopath
go env -w GOPATH=/usr/gopath
# 设置环境变量
go env -w GO111MODULE="on"
# china proxy
go env -w GOPROXY=https://goproxy.io
# 初始化 mod 项目
# 自动生成了 `go.mod` 和 `go.sum` 文件。
go mod init [packetName]
# add missing and remove unused modules
# 自动增加包和删除无用包到 GOPATH 目录下
go mod tidy
注意:只要在本地 设置一个公用 gopath 目录 就可以了,全部的包都会下载到那里,其他本地项目用到时就可以共享了,并且会自动根据 go.mod
选择对应版本的第三方库。
go.mod
// 模块的引用路径
module github.com/BingmingWong/module-test
// 项目使用的 go 版本
go 1.14
// 项目所需的直接依赖包及其版本
require (
example.com/apple v0.1.2
)
// 忽略指定版本的依赖包
exclude example.com/banana v1.2.4
// 由于在国内访问golang.org/x的各个包都需要翻墙,你可以在go.mod中使用replace替换成github上对应的库。
replace(
golang.org/x/text v0.3.0 = > github.com/golang/text v0.3.0
)
go.sum
每一行都是由 模块路径,模块版本,哈希检验值 组成,其中哈希检验值是用来保证当前缓存的模块不会被篡改。
<module> <version>/go.mod <hash>
Go mod 命令使用
go mod init
:初始化 go mod, 生成 go.mod 文件,后可接参数指定 module 名,上面已经演示过。go mod download
:手动触发下载依赖包到本地 cache(默认为 $GOPATH/pkg/mod 目录)go mod graph
:打印项目的模块依赖结构go mod tidy
:添加缺少的包,且删除无用的包go mod verify
:校验模块是否被篡改过go mod why
:查看为什么需要依赖go mod vendor
:导出项目所有依赖到 vendor 下
写入 go.mod 有两种方法:
- 你只要在项目中有 import 并使用或者使用下划线强制占用,然后 go build 时 go module 就会自动下载并添加。
go mod tidy
参考:Go mod用法
Author: WhaleFall
Permalink: https://www.whaleluo.top/golang/golang-project-and-gomod-note/
文章默认使用 CC BY-NC-SA 4.0 协议进行许可,使用时请注意遵守协议。
Comments