共计 13636 个字符,预计需要花费 35 分钟才能阅读完成。
原文地址
https://github.com/anqiansong/golang-notes/blob/main/go-module.md
github
https://github.com/anqiansong
go module
在 go1.16 版本公布后,go module 由原来的默认值 auto
变为 on
了,这意味着后续开发中,go 更举荐用 go module 模式开发,而不是 gopath 模式开发了。
在之前,我也是大多数以 go module 模式进行 golang 开发,但至今对其不相熟,仅仅停留在:他人是这样做的,我跟着做就是了
,这都算不上会应用 go module,更不用说相熟或者精通了;在此之前,我会存在这些疑难:
- go mod 文件中定义的各项内容代表什么;
- 除了常见的
require
、偶然见replace
关键字外,exclude
、retract
(1.16)这些关键字是什么,怎么用; - go mod 文件语法格局是什么,目前除了跟着他人写,如同也不明确其中的语法
github.com/tal-tech/go-zero v1.1.5
、github.com/antlr/antlr4 v0.0.0-20210105212045-464bcbc32de2
、google.golang.org/protobuf v1.25.0 // indirect
等格局别离代表什么,为什么有的还有// indirect
润饰;- go.mod 上面为什么有一个 go.sum,其有什么作用;
- …
不晓得有多少人和我一样,对 go module 的理解微不足道。
最近,带着这些纳闷,去学习了官网的参考手册,这些纳闷就引刃而解了。
project
在正式进入 module 介绍前,有必要首先理解一下 project 和 module 的关系,置信开发过 Android 或者 Java 的同学对 module 有十分好的了解,艰深的讲,一个 project 能够有多个 module 组成,module 能够作为独立
的 project 被别的 project 作为依赖援用,如下 golang 工程 demo
中就蕴含了 foo
和 bar
两个 module
demo
├── bar
│ └── go.mod
└── foo
└── go.mod
module 介绍
go module(以下称:module、模块、工程模块)
是 golang 中已公布版本的 package 的汇合,是 Go 治理依赖的一种形式,相似 Android 中的 Gradle,Java 中的 Maven,当然,他们的治理模式必定是天壤之别,然而目标都是统一的,对依赖进行治理。
在 go.mod 中,其蕴含了 main module 的 module 门路、module 依赖及其关联信息(版本等),如果一个工程模块须要以go module mode
(module 模式)开发,在工程模块的根目录下必须蕴含 go.mod
文件。
module path(module 门路)
module 门路是一个工程模块中的名称,在 go.mod 中以 module
命令申明,其也是工程模块中 package import 的前缀,咱们来看一下 demo/foo
下的 module 门路:
$ cat demo/foo/go.mod
module github.com/foo
go 1.16
require github.com/tal-tech/go-zero
github.com/foo
为 main module foo
模块的模块门路,github.com/tal-tech/go-zero
也是 module path, 他们也是 foo 中 package
import 的前缀,我在 foo 下的 base 包下增加了一个 Echo
函数,而后在 main.go
中调用,咱们察看一下其 package import 的前缀
目录树
foo
├── base
│ └── base.go
├── go.mod
└── main.go
main.go
package main
import "github.com/foo/base" // github.com/foo 为 module path
import "fmt"
func main() {msg := base.Echo("go-zero")
fmt.Println(msg)
}
module 门路次要作用是形容一个工程模块的作用是什么,在哪里能够找到,因而,module path 的组成元素就蕴含了
- repo 门路
- repo 文件夹
- 版本
其表现形式如: {{.repo_url}}/{{.nameOfDir}}/{{.version}}
,示例:github.com/tal-tech/go-zero/v2
,github.com/tal-tech
明确告知了 repo
的门路,go-zero
即为 repo 的文件夹,v2
即为版本号 版本个别 v1
个别都默认不写了,只有大于 v1
时则须要用来辨别。
版本号
这里的版本号是指 go.mod 文件中依赖 module 的版本,这和上文的 {{.version}}
会有关联,如下示例中的 v1.1.5
即为本次所说的 module 依赖版本号。
module github.com/foo
go 1.16
require github.com/tal-tech/go-zero v1.1.5
版本号组成及规定
版本号由 major version
(次要版本)、minor version
(主要版本)、patch version
(订正版本)组成;
- major version:指 module 中内容作了向后不兼容的更改后,则版本会 upgrade,在此版本号 upgrade 时,
minor version
和patch version
要归零; - minor version:指在新的性能公布 (features) 或者作了向后兼容的内容变更后,此版本号会 upgrade,在此版本号 upgrade 时,
patch version
要归零; - patch version:指有 bug 修复或者性能优化时,此版本号能够进行 upgrade,在有 pre-release 公布需要时也能够变更此版本号
示例:v0.0.0
、v1.2.3
、v1.2.10-pre
如果一个版本的
major version
为0
或者patch-version
有版本后缀(如:pre),则认为这个版本是不稳固的,如v0.2.0
、v1.5.0-pre
、v1.1.3-beta
更多对于 version 语义定义能够参考《Semantic Versioning 2.0.0》
Golang 除此之外,还能够用一些标记、分支来代表某一个版本,如:github.com/tal-tech/go-zero 39540e21d249e91f89d96d015a6e3795cfb2be44
、github.com/tal-tech/go-zero v1.1.6-0.20210303091609-39540e21d249
、github.com/tal-tech/go-zero@master
其中github.com/tal-tech/go-zero v1.1.6-0.20210303091609-39540e21d249
这种版本在 golang 外面称为 Pseudo-versions
(伪版本),其没有齐全遵循上文中的版本规定,伪版本由三个局部组成:
- 版本根本前缀(
vX.Y.Z-0
或vX.0.0
),如v1.1.6-0
- 工夫戳:即 revision 的创立工夫戳,如
20210303091609
- revision 标识符,如
39540e21d249
依据根本前缀的不同,伪版本会有三种模式:
vX.0.0-yyyymmddhhmmss-abcdefabcdef
:在没有release
版本时应用vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef
:当根本版本是预公布版本时应用vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdef
:当release
版本相似vX.Y.Z
时应用,如github.com/tal-tech/go-zero v1.1.6-0.20210303091609-39540e21d249
的release
版本为v1.1.5
伪版本不须要手动输出,其会在执行局部 go 命令获取某一次提交记录版本 (revision) 的代码作为依赖时,会主动将其转换为伪版本
上文中的
github.com/tal-tech/go-zero v1.1.6-0.20210303091609-39540e21d249
则是在执行go get github.com/tal-tech/go-zero 39540e21d249e91f89d96d015a6e3795cfb2be44
后主动转换的后果
版本后缀
为了向前兼容,如果 major version
降级到 2 时,模块门路必须要指定一个版本后缀 v2
(其数值放弃和版本中的 major version
的值统一),在 major version
小于 2 时,不容许应用版本后缀。
咱们来看一个例子,我在 demo/foo
模块工程中用到了 miniRedis
这个库,该库的 major version
曾经降级到 2 了,假如我在 go.mod 中援用如下版本会怎么样?
module github.com/foo
go 1.16
// 正确引入
// require github.com/alicebob/miniredis/v2 v2.14.1
// 谬误引入
require github.com/alicebob/miniredis v2.14.1
invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2
下面是 go mod 应用时的场景,咱们来看一下当 main module 的 release 版本升级到 v2.x.x
时 (前提先发一个 v1.0.0 的版本),module path 没有增加版本后缀,在另一个 module 去应用它会有什么成果:
示例 module foofoo
工程目前有 release 版本
v1.0.0
v2.0.1
- …
应用 module 的工程 bar
- 未增加版本后缀前
foo
工程目录树
foo
├── echo
│ └── echo.go
└── go.mod
module path 为 github.com/anqiansong/foo
module github.com/anqiansong/foo
go 1.16
在工程 bar
的 go.mod 应用 v2.0.0
版本
require github.com/anqiansong/foo v2.0.0
你会发现报错内容为
require github.com/anqiansong/foo: reading https://goproxy.cn/github.com/anqiansong/foo/@v/v2.0.0.info: 404 Not Found
server response: not found: github.com/anqiansong/foo@v2.0.0: invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2
如果 require github.com/anqiansong/foo v1.0.0
是能够的。
- 增加版本后缀后
foo
工程目录树
foo
├── echo
│ └── echo.go
└── go.mod
module path 为 github.com/anqiansong/foo/v2
module github.com/anqiansong/foo/v2
go 1.16
在工程 bar
的 go.mod 应用 v2.0.1
版本
require github.com/anqiansong/foo/v2 v2.0.1
bar
运行失常
如果
major version
降级至v2
时,如果该版本没有打算向前兼容,且不想把 module path 增加版本后缀,则能够在 build tag 时以+incompatible
结尾即可,
则别的工程援用示例为require github.com/anqiansong/foo v2.0.0+incompatible
如何解析 package 中的 module
Go 命令首先在构建列表中搜寻具备包门路前缀的模块。例如,如果导入了包 example.com/a/b
,而模块 example.com/a
位于构建列表中,则 go 命令将查看 example.com/a
是否蕴含目录 b
中的包。且该目录中至多蕴含一个 go 文件,这样能力被视为 package
。生成束缚不利用于此目标。如果生成列表中只有一个模块提供包,则应用该模块。如果没有模块提供包,或者有两个或多个模块提供包,则 go
命令报告谬误。mod=mod
标记批示 go
命令尝试查找提供失落包的新模块,并更新 go.mod
和 go.sum
。go get
和 go mod tidy
命令会主动执行此操作。
当 go 命令更新或者获取 module 依赖时,其会查看 GOPROXY
环境变量,GOPROXY
的值是一个逗号宰割的 url 列表,或者是关键字 direct
、off
,
- 逗号宰割的具体 url 为代理地址,其会告知
go
命令以此值去发动连贯 direct
:指定 module 依赖通过版本控制系统去获取off
:示意不尝试连贯获取 module
如果 GOPROXY
设置了具体的 url,假如 go
命令要寻找一个 github.com/tal-tech/go-zero/zrpc
的 package
,go
命令会并行的去查找一下 module
github.com/tal-tech/go-zero/zrpc
github.com/tal-tech/go-zero
github.com/tal-tech
github.com
如果其中有一个或者多个匹配到蕴含满足 github.com/tal-tech/go-zero/zrpc
的内容,则取最长的 module
作为依赖,在找到适合的 module 和版本后,go
命令会向 go.mod
和 go.sum
文件中填写 require
,,如果解析到的 module
不是 main module 被动引入的,则会在 require
的值前面增加 // direct
正文,如果一个都没有匹配到,则报错;如果 GOPROXY
有多个 url 代理,在后面失败的状况下,会顺次 向前面代理执行下面的步骤。
go.mod 文件
一个 module
(模块工程)的标识是在其根目录下蕴含一个编码为 UTF-8
、名称为 go.mod
的文本文件,go.mod
文件中的内容是面向 行
的,每一行蕴含一个指令,且每行均由一个 关键字
和 参数
组成,就像:
module github.com/anqiansong/foo
go 1.16
require github.com/tal-tech/go-zero
require github.com/tal-tech/go-queue
replace go.etcd.io/etcd => go.etcd.io/etcd v0.0.0-20200402134248-51bdeb39e698
retract [v1.0.0, v1.0.1]
当然,领有雷同关键字的内容能够分离出来,用 关键字
+ block
组成,就像:
module github.com/anqiansong/foo
go 1.16
require (
github.com/tal-tech/go-zero
github.com/tal-tech/go-queue
)
replace go.etcd.io/etcd => go.etcd.io/etcd v0.0.0-20200402134248-51bdeb39e698
retract [v1.0.0, v1.0.1]
go.mod
是机器可写的,像执行一些命令(如:go get
、go mod edit
)可能会自动更新 go.mod
文件。
module 组成元素
在解析 go.mod
文件中的内容时,其会被解析为
空白符
:蕴含空格(U+0020)、制表符(U+0009)、回车(U+000D) 和换行符(U+000A)正文
:正文仅反对单行正文//
标点
:标点符号有(
、)
、,
、=>
关键字
:go
、require
、replace
、exclude
、retract
标识符
:由非空白符
组成的字符序列,如 module path、语义版本字符串
:由英文双引号"
(U+0022)包裹的解释字符串或者有<
(U+0060)包裹的原始字符串。如"github/com/tal-tech/go-zero"
、“
标识符
和字符串
在go.mod
语法中能够替换
module 语法词法
go.mod
语法是通过Extended Backus-Naur Form
(EBNF 范式) 定义的,就像
GoMod = {Directive} .
Directive = ModuleDirective |
GoDirective |
RequireDirective |
ExcludeDirective |
ReplaceDirective |
RetractDirective .
module
指令
module
关键字定义了 main module 的 module path,在 go.mod
文件中有且只有一个 module
指定。
语法规定:
ModuleDirective = "module" (ModulePath | "(" newline ModulePath newline ")" newline .
示例:
module github.com/tal-tech/go-zero
go
指令
go
关键字定义了 module
设置预期应用的 go 语言版本,版本必须是一个无效的 go 版本(能够了解为合乎 version
规定,也能够了解为为 Go 曾经 release 的版本)
通过 go
关键字定义版本后,编译器在编译包时就晓得应该应用哪个 go 版本去编译,除此外,go
关键字定义版本还能够用于 是否启用 go
命令的一些个性,如是否主动开始 vendoring 在版本 1.14
及当前。
语法规定:
GoDirective = "go" GoVersion newline .
GoVersion = string | ident . /* valid release version; see above */
示例:
go 1.16
require
指令
require
申明了 module 依赖的最小版本,在 require
指定版本后,go
相干命令会依据 MVS
规定依据此值来加载依赖。
go
寻找依赖时,如果该依赖不是 main module 间接依赖的,则会在该 module path 前面增加 // direct
正文内容。
语法规定:
RequireDirective = "require" (RequireSpec | "(" newline { RequireSpec} ")" newline ) .
RequireSpec = ModulePath Version newline .
示例:
module github.com/tal-tech/go-zero
go 1.16
require (
golang.org/x/crypto v1.4.5 // indirect
golang.org/x/text v1.6.7
)
excule
指令
excule
会疏忽内容中的指定版本,从 go 1.16
后,exclude
指定的 module 会被疏忽,在 go 1.16
前,如果 require
的 module 被 exclude
指定后,会列出并获取更改的为被 exclude
的版本。
语法规定:
ExcludeDirective = "exclude" (ExcludeSpec | "(" newline { ExcludeSpec} ")" ) .
ExcludeSpec = ModulePath Version newline .
示例:
module github.com/tal-tech/go-zero
go 1.16
exclude golang.org/x/net v1.2.3
excule (
golang.org/x/crypto v1.4.5
golang.org/x/text v1.6.7
)
replace
指令
replace
指令用于将 module 的指定版本或者 module 应用其余的 module 或者版本来替换,如果 =>
右边质指定了版本,则替换 这个版本至指标内容,否则替换替换 module 的所有版本至指标内容
语法规定:
ReplaceDirective = "replace" (ReplaceSpec | "(" newline { ReplaceSpec} ")" newline ")" ) .
ReplaceSpec = ModulePath [Version] "=>" FilePath newline
| ModulePath [Version] "=>" ModulePath Version newline .
FilePath = /* platform-specific relative or absolute file path */
示例:
replace golang.org/x/net v1.2.3 => example.com/fork/net v1.4.5
=>
左边的内容能够是无效的 module path,也能够是绝对或者绝对路径,如果是绝对或者绝对路径,这该门路的根目录必须蕴含 go.mod
文件。
示例:
require github.com/foo v1.0.0
replace github.com/foo v1.0.0 => ../bar
retract
指令(1.16 新增)
retract
申明的内容,用于标记某些版本或者某个版本范畴(闭区间)标记为撤回,个别 retract
申明前须要写一条正文用于阐明,当执行 go get
命令时,如果援用了被标记为 retract
的版本,或者
在 retract
标记的版本范畴内,则会提醒一条正告(其内容为 retract
的正文内容),通过go list -m -versions
获取版本时也会暗藏该版本。
语法规定:
RetractDirective = "retract" (RetractSpec | "(" newline { RetractSpec} ")" ) .
RetractSpec = (Version | "[" Version "," Version "]" ) newline .
示例:
// someting wrong
retract v1.0.0
// someting wrong in range of versions => v1.0.0~v1.2.0
retrace [v1.0.0,v1.2.0]
咱们来看一个例子,目前 github.com/anqiansong/retract
曾经有 v1.0.0
等版本了,咱们 增加一行 retract
指令标记v1.0.0
撤回:
// someting wrong
retract v1.0.0
而后 release 一个版本为 v1.0.1
,接下来在 github.com/anqiansong/bar
中援用 v1.0.0
版本
require github.com/anqiansong/retract v1.0.0
而后执行 go get github.com/anqiansong/retract@v1.0.0
,不出意外,会失去一个提醒蕴含 something wrong
和 提醒更新到 v1.0.1
的信息
$ go get github.com/anqiansong/retract@v1.0.0
go: warning: github.com/anqiansong/retract@v1.0.0: retracted by module author: someting wrong
go: to switch to the latest unretracted version, run:
go get github.com/anqiansong/retract@latestgo get: downgraded github.com/anqiansong/retract v1.0.1 => v1.0.0
获取 github.com/anqiansong/retract
所有 module release 版本
$ go list -m -versions github.com/anqiansong/retract
github.com/anqiansong/retract v1.0.1
局部命令查看 github.com/anqiansong/retract@v1.0.0
的后果:
-
go get
$ go get github.com/anqiansong/retract@v1.0.0
go: warning: github.com/anqiansong/retract@v1.0.0: retracted by module author: someting wrong go: to switch to the latest unretracted version, run: go get github.com/anqiansong/retract@latest
-
go list -m -u
$ go get github.com/anqiansong/retract@v1.0.0
github.com/anqiansong/retract v1.0.0 (retracted) [v1.0.1]
-
go list -m -versions
$ go list -m -versions github.com/anqiansong/retract
github.com/anqiansong/retract v1.0.1
阐明:
retract
管制的是 main module 的版本,而非依赖的 module 版本。被
retract
标记的版本其余 module 还是能够援用的,只是局部go
命令执行时会有retract
的不同后果,如上。
自动更新
如果 go.mod 短少信息或者不能精确反映理论状况,大多数 go
命令都会报告谬误。go get
、go mod tidy
命令能够用来修复大多数这类问题。此外,-mod=mod
标记能够用于大多数模块感知命令(go build
、go test
等),以批示 go
命令主动修复 go.mod
和 go.sum
中的问题。
module 感知
大多数 go 命令能够在 Module-ware
模式或 GOPATH
模式下运行。在 Module-ware
模式下,go 命令应用 go.mod 文件来查找版本相关性,
它通常从模块缓存中加载包,如果短少模块,则下载模块。在 GOPATH
模式下,go 命令疏忽 module;它在 vendor
或 GOPATH
目录中查找依赖项。
在 Go 1.16 中,无论是否存在 go.mod
文件,Module-ware
模式默认是启用的。在低版本中,当工作目录文件或任何父目录中存在 go.mod
文件时,启用 Module-ware
模式。
Module-ware
模式能够通过 GO111MODULE 环境变量管制,能够设置为 on
、off
或 auto
off
:go
相干命令会疏忽go.mod
文件,而后以GOPATH
模式运行on
:on
或者空字符串,相干命令会Module-ware
模式运行auto
:如果以后文件夹存在go.mod
文件,则会以Module-ware
模式运行,在 Go 1.15 及更低版本,此值为默认值,
局部 go module 相干命令
这里命令必须要在 Module-ware
模式才无效
命令 | 用法 | 备注 | 示例 |
---|---|---|---|
go list -m | go list -m [-u] [-retracted] [-versions] [list flags] [modules] | 查看 module 信息 | go list -m all |
go mod init | go mod init [module-path] | 在工作目录初始化并创立一个 go.mod 文件 | go mod init demo |
go mod tidy | go mod tidy [-e] [-v] | 整顿 go.mod 文件 | go mode tidy |
go clean -modcache | go clean [-modcache] | 革除 module 缓存 | go clean -modcache |
Proxy
模块代理是一个反对 GET
申请响应 的 HTTP
服务器,该申请没有 query
参数,甚至不须要特定的 header
信息,即便 该值是一个固定的文件系统站点 (如:file:// URL
) 也是能够的。
模块代理的 HTTP
响应状态码必须蕴含 200
(OK),3xx
,4xx
、5xx
,4xx
、5xx
被认为是响应谬误,404
和 410
示意所有的 module 申请是不可用的,留神,谬误的响应的 contentType 应该设置为 text/plain
,字符集为 utf-8
或者 us-ascii
。
URLs
go
命令能够通过读取 GOPROXY
环境变量配置来连贯连贯代理服务器或者版本控制系统,GOPROXY
承受一个逗号 (,) 或者竖线 (|) 宰割的多个 url 值,当以英文逗号 (,)
宰割时,只有响应状态码为 404 或者 410 时就会尝试前面的代理地址,如果是以竖线 (|) 宰割,则在 http 呈现任何谬误(蕴含超时)都会跳过去尝试前面的代理地址。也能够是 direct
或者 off
关键字。
上面的表格为一个代理地址必须要实现且有申请响应的 path(即一个代理服务器必须要要反对一下路由的实现)
$base
为代理服务器地址,如:https://goproxy.cn$module
为 module path,如:github.com/tal-tech/go-zero$version
为 module 版本
path | 形容 | 示例 | 示例后果 |
$base/$module/@v/list | 以纯文本模式返回给定模块的已知版本的列表,每行一个。此列表不应包含伪版本 | curl -X GET https://goproxy.cn/github.com… |
v1.0.0 v1.0.1 v1.0.2 v1.0.3 v1.0.4 … |
$base/$module/c/$version.info | 返回对于某个模块的特定版本的 json 格局的元数据。响应必须是一个 JSON 对象,对应于上面的 Go 数据结构:` type Info struct { Version string // version string Time time.Time // commit time } `
|
curl -X GET https://goproxy.cn/github.com… |
` {“Version”: “v1.1.5”, “Time”: “2021-03-02T03:02:57Z” } `
|
$base/$module/@v/$version.mod | 返回指定版本的 go.mod 中的信息 /td> | curl -X GET https://goproxy.cn/github.com… |
` module github.com/tal-tech/go-zero go 1.14 require ( github.com/ClickHouse/clickhouse-go v1.4.3 github.com/DATA-DOG/go-sqlmock v1.4.1 github.com/alicebob/miniredis/v2 v2.14.1 github.com/antlr/antlr4 v0.0.0-20210105212045-464bcbc32de2 …. ) `
|
$base/$module/@v/$version.zip | 返回指定版本的 go module 的 zip 文件 | wget https://goproxy.cn/github.com… | v1.1.5.zip |
$base/$module/@latest | 返回无关模块的最新已知版本的 json 格局的元数据 | curl -X GET https://goproxy.cn/github.com… | { “Version”: “v1.1.5”, “Time”: “2021-03-02T03:02:57Z” } |
在获取 module 最新版本时,go
相干命令会优先申请 $base/$module/@v/list
地址,如果没有找到适宜的版本,
则申请 $base/$module/@latest
获取并匹配是否满足,go
相干命令会依照 release
版本、pre-release
版本、pseudo
版本排序。
而 $base/$module/$version.mod
和 $base/$module/$version.zip
地址必须要提供,因为这些信息能够用于和 go.sum
进行数据校验。
go module 下载后的内容个别会存储在 $GOPATH/pkg/mod/cache/download
门路下,包含版本控制系统下载的也是如此。
direct
如果 GOPROXY
设置了 direct
值,则在执行相干 go
命令时会从版本控制系统 (git
、svn
等)下载 module 资源,当然还须要另外两个环境
变量 GOPRIVATE
、GONOPROXY
配合,更多环境变量信息请参考这里
module 文件大小束缚
对模块 zip
文件的内容有许多限度。这些束缚确保能够在宽泛的平台上平安和统一地提取压缩文件。
一个模块最多能够达到 500MiB(不论是压缩模式还是未压缩模式文件)
go.mod
文件要求显示在 16MiB 以内
go.sum
在 module 的根目录下可能有一个名为 go.sum
的文件,其是间接附丽在 go.mod 上面的,当执行 go
相干命令获取 module 时,
其会查看 zip
文件和 go.sum
中的值是否统一。
go.sum
中的值由一个 module path
、version
和一个 hash
值组成,如:
github.com/anqiansong/retract v1.0.1 h1:jxcsUM/6tvxM7p14/XMeZPFbql5KAAZJfFqiHG+YKxA=
总结
花了 3 天工夫,第一天看英文原文档,第二、三天翻译成中文来验证本人的了解,并写下这篇日志,通过学习,对于 go module 手册的学习解开了不少纳闷,
至多开篇的几个问题算是解开了,本文也是将手册中的局部内容作了 搬运
联合了本人的一些了解,
以及用实在例子去验证,其中还有很多内容我并未齐全照搬,如果有趣味的同学,能够参考官网手册,本文局部内容蕴含集体了解,也是联合 google 翻译加上
对一些翻译不合理的中央进行人工翻译,必定存在不合理的中央,如果有了解不统一的,欢送提出和探讨。
最初
有播种能够到 github 点个小❤️❤️ 哈。
参考文档
- 《Semantic Versioning 2.0.0》
- 《Go Module 官网文档》