ZetCode

Go Module

最后修改时间 2024 年 4 月 11 日

本文将介绍如何在 Golang 中使用 Modules。

Module 是一个文件树中存储的 Go 包的集合。

Modules 包含两个特定的文件:go.modgo.sumgo.mod 定义了 module 路径和依赖需求。go.sum 是一个自动生成的依赖锁定文件。

Modules 使我们能够定义精确的依赖需求,并为多个环境设计可重现的构建。

第三方 Modules 从它们的仓库下载到 Module 缓存中。构建应用程序时,这些依赖项会从这些副本中加载。Module 缓存默认位于主目录的 go 子目录中。

go module 命令

go 工具提供了几个与 Modules 相关的命令。

还有其他与 Go Modules 相关的命令。

go list -m 列出可用的 Modules。go get 安装依赖项并更新 go.mod 文件。go buildgo test 命令根据需要向 go.mod 添加新的依赖项。

go mod init

go mod init 命令在当前目录中创建新的 Module。当前目录会创建一个新的 go.mod 文件;该文件必须不存在。

$ go mod init [module-path]

Module 路径是用于导入该 Module 所有包的前缀路径。开发者通常使用托管源代码的仓库 URL 作为 Module 路径。

$ go mod init com.zetcode/first
go: creating new go.mod: module com.zetcode/first

创建一个具有 com.zetcode/first Module 路径的新 Module。

$ cat go.mod
module com.zetcode/first

go 1.17

这是 go.mod 文件的内容。我们有 Module 路径和 Go 版本。

go get 命令

使用 go get 命令安装依赖项。该命令会自动更新 go.mod 文件并创建 go.sum 文件。

$ go mod init com.zetcode/myprog

首先,我们创建一个 Module。

$ go get gonum.org/v1/gonum/stat
go: downloading gonum.org/v1/gonum v0.9.3
go get: added gonum.org/v1/gonum v0.9.3

我们安装 Gonum 库。它是 Go 语言的一套数值库。

$ ls
go.mod  go.sum

我们在当前工作目录中有 go.modgo.sum

~/go/pkg/mod/gonum.org/v1/gonum@v0.9.3$ ls -1
appveyor.yml
AUTHORS
blas
cmplxs
CONDUCT.md
CONTRIBUTING.md
CONTRIBUTORS
diff
doc.go
dsp
floats
go.mod
GOPHER
gopher.png
gopher.svg
go.sum
graph
integrate
internal
interp
lapack
LICENSE
mat
mathext
num
optimize
README.md
spatial
stat
THIRD_PARTY_LICENSES
unit
version.go

Gonum 库作为 Module 分发;默认情况下,它安装在用户主目录的 go 子目录中。

first.go
package main

import (
    "fmt"
    "math"

    "gonum.org/v1/gonum/stat"
)

func main() {
    xs := []float64{
        12.44, 11.2, 34.5, 1.4, 6.7, 23.4,
    }

    fmt.Printf("data: %v\n", xs)

    mean := stat.Mean(xs, nil)
    variance := stat.Variance(xs, nil)
    stddev := math.Sqrt(variance)

    fmt.Printf("mean: %v\n", mean)
    fmt.Printf("variance: %v\n", variance)
    fmt.Printf("std-dev: %v\n", stddev)
}

我们有一个简单的示例,用于计算一些基本统计数据。

import (
    "fmt"
    "math"

    "gonum.org/v1/gonum/stat"
)

我们获取 Module 的 stat 包。

$ go run first.go 
data: [12.44 11.2 34.5 1.4 6.7 23.4]
mean: 14.94
variance: 145.12640000000002
std-dev: 12.046841909811883
$ go list -m all
com.zetcode/myprog
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9
gioui.org v0.0.0-20210308172011-57750fc8a0a6
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af
github.com/boombuler/barcode v1.0.0
github.com/davecgh/go-spew v1.1.0
...

使用 go list -m all,我们列出项目的所有依赖项。

依赖项管理 (Vendoring)

依赖项管理是一种满足项目依赖项的特定方式。与使用默认的 Module 缓存不同,依赖项会被下载,然后从 vendor 子目录加载。该目录是项目目录的一个子目录。

$ go mod vendor

go mod vendor 命令在主 Module 的根目录中创建一个名为 vendor 的目录。该命令还会创建 vendor/modules.txt 文件,其中包含供应商包列表以及它们被复制的 Module 版本。

$ go mod init com.zetcode/second 
$ go get github.com/bykof/gostradamus

我们创建一个项目并下载一个依赖项。gostradamus 是一个用于处理日期和时间的库。

second.go
package main

import (
     "fmt"

     "github.com/bykof/gostradamus"
)

func main() {

     now := gostradamus.Now()

     fmt.Println(now)
}

该示例打印当前日期时间。

$ go mod vendor

我们初始化依赖项管理。

$ ls
go.mod  go.sum  second.go  vendor

我们创建了 vendor 目录。

$ ls vendor/github.com/
bykof

它包含我们的依赖项。

来源

使用 Go Modules

在本文中,我们讨论了 Go 中的 Modules。

作者

我叫 Jan Bodnar,是一名充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。至今,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有超过十年的经验。

列出所有 Go 教程