1.go mod需要go.1.13以上版本,使用前先更新go的版本
(1) 下载Go发行版
从Go语言中文网:https://studygolang.com/dl 上下载合适的 二进制发行版 (例如: https://studygolang.com/dl/golang/go1.16.6.linux-amd64.tar.gz):
wget https://studygolang.com/dl/golang/go1.16.6.linux-amd64.tar.gz
(2) 提取压缩包
提取压缩包到合适的目录(例如: /usr/local ):
sudo tar -xzf go1.16.linux-amd64.tar.gz -C /usr/local
(3) .建立软链接
sudo ln -s /usr/local/go/bin/* /usr/bin/
可以运行如下命令,验证是否安装成功:
go version
2.配置go的环境变量
vi /etc/profile export GOROOT=/usr/local/go #设置为go安装的路径,有些安装包会自动设置默认的goroot export GOPATH=$HOME/go-work #默认的Golang项目的工作空间 export GOBIN=$GOPATH/bin # go install命令生成的可执行文件的路径 export PATH=$PATH:$GOROOT/bin:$GOBIN 查看go环境变量 go env
3.开启go modules配置
go env -w GOBIN=/Users/youdi/go/bin go env -w GO111MODULE=on go env -w GOPROXY=https://goproxy.cn,direct // 使用七牛云的
4.go mod相关命令集
| 命令 | 说明 |
| download | download modules to local cache(下载依赖包) |
| edit | edit go.mod from tools or scripts(编辑go.mod) |
| graph | print module requirement graph (打印模块依赖图) |
| verify | initialize new module in current directory(在当前目录初始化mod) |
| tidy | add missing and remove unused modules(拉取缺少的模块,移除不用的模块) |
| vendor | make vendored copy of dependencies(将依赖复制到vendor下) |
| verify | verify dependencies have expected content (验证依赖是否正确) |
| why | explain why packages or modules are needed(解释为什么需要依赖) |
1. 初始化项目
可以随便找一个目录创建项目
mkdir Gone cd Gone go mod init Gone
查看一下 go.mod文件
module Gone go 1.14
go.mod文件一旦创建后,它的内容将会被go toolchain全面掌控。go toolchain会在各类命令执行时,比如go get、go build、go mod等修改和维护go.mod文件。
go.mod 提供了module, require、replace和exclude 四个命令
- module 语句指定包的名字(路径)
- require 语句指定的依赖项模块
- replace 语句可以替换依赖项模块
- exclude 语句可以忽略依赖项模块
2. 添加依赖
创建 main.go文件
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
执行 go run main.go 运行代码会发现 go mod 会自动查找依赖自动下载
再查看 go.mod
module Gone go 1.14 require github.com/gin-gonic/gin v1.6.3
go module 安装 package 的原則是先拉最新的 release tag,若无tag则拉最新的commit
再次执行脚本 go run main.go发现跳过了检查并安装依赖的步骤。
可以使用命令 go list -m -u all 来检查可以升级的package,使用go get -u need-upgrade-package 升级后会将新的依赖版本更新到go.mod * 也可以使用 go get -u 升级所有依赖
去mod包缓存下看看
/Users/youdi/go/pkg/mod/github.com/gin-gonic/gin@v1.6.3go get升级
- 运行 go get -u 将会升级到最新的次要版本或者修订版本(x.y.z, z是修订版本号, y是次要版本号)
- 运行 go get -u=patch 将会升级到最新的修订版本
- 运行 go get package@version 将会升级到指定的版本号version
- 运行go get如果有版本的更改,那么go.mod文件也会更改
由于某些已知的原因,并不是所有的package都能成功下载,比如:golang.org下的包。
modules 可以通过在 go.mod 文件中使用 replace 指令替换成github上对应的库,比如:
replace (
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a => github.com/golang/crypto v0.0.0-20190313024323-a1f597ede03a
)
go mod发布和使用
参考Roberto Selbach写的go mod入门文章,文末,我给出链接
Creating a Module如果你设置好go mod了,那你就可以在任何目录下随便创建
$mkdir gomodone $cd gomodone
在这个目录下创建一个文件say.go
package gomodone
import "fmt"
// say Hi to someone
func SayHi(name string) string {
return fmt.Sprintf("Hi, %s", name)
}
初始化一个 go.mod文件
$ go mod init github.com/jacksonyoudi/gomodone go: creating new go.mod: module github.com/jacksonyoudi/gomodone
查看 go.mod内容如下:
github.com/jacksonyoudi/gomodone go 1.14
下面我们要将这个module发布到github上,然后在另外一个程序使用
$git init $vim .gitiiignore $git commit -am "init" // github创建对应的repo $git remote add origin git@github.com:jacksonyoudi/gomodone.git $git push -u origin master
执行完,上面我们就相当于发布完了。
如果有人需要使用,就可以使用
go get github.com/jacksonyoudi/gomodone
这个时候没有加tag,所以,没有版本的控制。默认是v0.0.0后面接上时间和commitid。如下:
gomodone@v0.0.0-20200517004046-ee882713fd1e
官方不建议这样做,没有进行版本控制管理。
module versioning使用tag,进行版本控制
making a release
git tag v1.0.0 git push --tags
操作完,我们的module就发布了一个v1.0.0的版本了。
推荐在这个状态下,再切出一个分支,用于后续v1.0.0的修复推送,不要直接在master分支修复
$git checkout -b v1 $git push -u origin v1use our module
上面已经发布了一个v1.0.0的版本,我们可以在另一个项目中使用,创建一个go的项目
$mkdir Gone $cd Gone $vim main.go
package main
import (
"fmt"
"github.com/jacksonyoudi/gomodone"
)
func main() {
fmt.Println(gomodone.SayHi("Roberto"))
}
代码写好了,我们生成 go mod文件
go mod init Gone
上面命令执行完,会生成 go mod文件
看下mod文件:
module Gone
go 1.14
require (
github.com/jacksonyoudi/gomodone v1.0.0
)
$go mod tidy go: finding module for package github.com/jacksonyoudi/gomodone go: found github.com/jacksonyoudi/gomodone in github.com/jacksonyoudi/gomodone v1.0.0
同时还生成了go.sum, 其中包含软件包的哈希值,以确保我们具有正确的版本和文件。
github.com/jacksonyoudi/gomodone v1.0.1 h1:jFd+qZlAB0R3zqrC9kwO8IgPrAdayMUS0rSHMDc/uG8= github.com/jacksonyoudi/gomodone v1.0.1/go.mod h1:XWi+BLbuiuC2YM8Qz4yQzTSPtHt3T3hrlNN2pNlyA94= github.com/jacksonyoudi/gomodone/v2 v2.0.0 h1:GpzGeXCx/Xv2ueiZJ8hEhFwLu7xjxLBjkOYSmg8Ya/w= github.com/jacksonyoudi/gomodone/v2 v2.0.0/go.mod h1:L8uFPSZNHoAhpaePWUfKmGinjufYdw9c2i70xtBorSw=
这个内容是下面的,需要操作执行的结果
go run main.go就可以运行了
Making a bugfix release假如fix一个bug,我们在v1版本上进行修复
修改代码如下:
// say Hi to someone
func SayHi(name string) string {
- return fmt.Sprintf("Hi, %s", name)
+ return fmt.Sprintf("Hi, %s!", name)
}
修复好,我们开始push
$ git commit -m "Emphasize our friendliness" say.go $ git tag v1.0.1 $ git push --tags origin v1
Updating modules
刚才fix bug,所以要在我们使用项目中更新
这个需要我们手动执行更新module操作
我们通过使用我们的好朋友来做到这一点go get:
- 运行 go get -u 以使用最新的 minor 版本或修补程序版本(即它将从1.0.0更新到例如1.0.1,或者,如果可用,则更新为1.1.0)
- 运行 go get -u=patch 以使用最新的 修补程序 版本(即,将更新为1.0.1但不更新 为1.1.0)
- 运行go get package@version 以更新到特定版本(例如github.com/jacksonyoudi/gomodone@v1.0.1)
目前module最新的也是v1.0.1
// 更新最新 $go get -u $go get -u=patch //指定包,指定版本 $go get github.com/jacksonyoudi/gomodone@v1.0.1
操作完,go.mod文件会修改如下:
module Gone
go 1.14
require (
github.com/jacksonyoudi/gomodone v1.0.1
)
Major versions
根据语义版本语义,主要版本与次要版本 不同。主要版本可能会破坏向后兼容性。从Go模块的角度来看,主要版本是 完全不同的软件包。乍一看这听起来很奇怪,但这是有道理的:两个不兼容的库版本是两个不同的库。
比如下面修改,完全破坏了兼容性。
package gomodone
import (
"errors"
"fmt"
)
// Hi returns a friendly greeting
// Hi returns a friendly greeting in language lang
func SayHi(name, lang string) (string, error) {
switch lang {
case "en":
return fmt.Sprintf("Hi, %s!", name), nil
case "pt":
return fmt.Sprintf("Oi, %s!", name), nil
case "es":
return fmt.Sprintf("¡Hola, %s!", name), nil
case "fr":
return fmt.Sprintf("Bonjour, %s!", name), nil
default:
return "", errors.New("unknown language")
}
}
如上,我们需要不同的大版本,这种情况下
修改 go.mod如下
module github.com/jacksonyoudi/gomodone/v2 go 1.14
然后,重新tag,push
$ git commit say.go -m "Change Hi to allow multilang" $ git checkout -b v2 # 用于v2版本,后续修复v2 $ git commit go.mod -m "Bump version to v2" $ git tag v2.0.0 $ git push --tags origin v2Updating to a major version
即使发布了库的新不兼容版本,现有软件 也不会中断,因为它将继续使用现有版本1.0.1。go get -u 将不会获得版本2.0.0。
如果想使用v2.0.0,代码改成如下:
package main
import (
"fmt"
"github.com/jacksonyoudi/gomodone/v2"
)
func main() {
g, err := gomodone.SayHi("Roberto", "pt")
if err != nil {
panic(err)
}
fmt.Println(g)
}
执行 go mod tidy
go: finding module for package github.com/jacksonyoudi/gomodone/v2 go: downloading github.com/jacksonyoudi/gomodone/v2 v2.0.0 go: found github.com/jacksonyoudi/gomodone/v2 in github.com/jacksonyoudi/gomodone/v2 v2.0.0
当然,两个版本都可以同时使用, 使用别名
如下:
package main
import (
"fmt"
"github.com/jacksonyoudi/gomodone"
mv2 "github.com/jacksonyoudi/gomodone/v2"
)
func main() {
g, err := mv2.SayHi("Roberto", "pt")
if err != nil {
panic(err)
}
fmt.Println(g)
fmt.Println(gomodone.SayHi("Roberto"))
}
执行一下 go mod tidy
Vendoring默认是忽略vendor的,如果想在项目目录下有vendor可以执行下面命令
$go vendor
当然,如果构建程序的时候,希望使用vendor中的依赖,
$ go build -mod vendor



