教程:Go 中的多模块工作区入门
本教程介绍了 Go 中多模块工作区的基础知识。使用多模块工作区,您可以告诉 Go 命令您同时在多个模块中编写代码,并轻松构建和运行这些模块中的代码。
在本教程中,您将在共享的多模块工作区中创建两个模块,对这些模块进行更改,并查看这些更改在构建中的结果。
注意:有关其他教程,请参阅 教程。
先决条件
- Go 1.18 或更高版本的安装。
- 用于编辑代码的工具。任何您拥有的文本编辑器都可以正常工作。
- 命令终端。Go 在 Linux 和 Mac 上的任何终端以及 Windows 上的 PowerShell 或 cmd 上都能很好地工作。
本教程需要 go1.18 或更高版本。请确保您已使用 go.dev/dl 上的链接安装了 Go 1.18 或更高版本。
为您的代码创建一个模块
首先,为要编写的代码创建一个模块。
-
打开命令提示符并更改到您的主目录。
在 Linux 或 Mac 上
$ cd
在 Windows 上
C:\> cd %HOMEPATH%
本教程的其余部分将显示 $ 作为提示符。您使用的命令在 Windows 上也能正常工作。
-
在命令提示符下,为您的代码创建一个名为 workspace 的目录。
$ mkdir workspace $ cd workspace
-
初始化模块
我们的示例将创建一个新的模块
hello
,它将依赖于 golang.org/x/example 模块。创建 hello 模块
$ mkdir hello $ cd hello $ go mod init example.com/hello go: creating new go.mod: module example.com/hello
通过使用
go get
添加对 golang.org/x/example/hello/reverse 包的依赖项。$ go get golang.org/x/example/hello/reverse
在 hello 目录中创建 hello.go,内容如下
package main import ( "fmt" "golang.org/x/example/hello/reverse" ) func main() { fmt.Println(reverse.String("Hello")) }
现在,运行 hello 程序
$ go run . olleH
创建工作区
在此步骤中,我们将创建一个 go.work
文件来指定包含该模块的工作区。
初始化工作区
在 workspace
目录中,运行
$ go work init ./hello
go work init
命令告诉 go
为包含 ./hello
目录中模块的工作区创建一个 go.work
文件。
go
命令将生成一个 go.work
文件,如下所示
go 1.18
use ./hello
go.work
文件具有与 go.mod
相似的语法。
go
指令告诉 Go 该文件应使用哪个版本的 Go 进行解释。它类似于 go.mod
文件中的 go
指令。
use
指令告诉 Go hello
目录中的模块在进行构建时应为主模块。
因此,在 workspace
的任何子目录中,该模块都将处于活动状态。
在工作区目录中运行程序
在 workspace
目录中,运行
$ go run ./hello
olleH
Go 命令将工作区中的所有模块都包含为主模块。这允许我们在模块中引用包,即使是在模块之外。在模块或工作区之外运行 go run
命令会导致错误,因为 go
命令不知道使用哪个模块。
接下来,我们将向工作区添加 golang.org/x/example/hello
模块的本地副本。该模块存储在 go.googlesource.com/example
Git 存储库的子目录中。然后,我们将向 reverse
包添加一个新函数,可以在其中使用该函数而不是 String
。
下载和修改 golang.org/x/example/hello
模块
在此步骤中,我们将下载包含 golang.org/x/example/hello
模块的 Git 存储库的副本,将其添加到工作区,然后向其中添加一个新函数,我们将在 hello 程序中使用该函数。
-
克隆存储库
从工作区目录,运行
git
命令克隆存储库$ git clone https://go.googlesource.com/example Cloning into 'example'... remote: Total 165 (delta 27), reused 165 (delta 27) Receiving objects: 100% (165/165), 434.18 KiB | 1022.00 KiB/s, done. Resolving deltas: 100% (27/27), done.
-
将模块添加到工作区
Git 存储库刚刚签出到
./example
中。golang.org/x/example/hello
模块的源代码位于./example/hello
中。将其添加到工作区$ go work use ./example/hello
go work use
命令将一个新的模块添加到 go.work 文件中。现在它将如下所示go 1.18 use ( ./hello ./example/hello )
该工作区现在同时包含
example.com/hello
模块和golang.org/x/example/hello
模块,该模块提供了golang.org/x/example/hello/reverse
包。这将允许我们使用将在
reverse
包的副本中编写的代码,而不是使用我们使用go get
命令下载的模块缓存中的包版本。 -
添加新函数。
我们将向
golang.org/x/example/hello/reverse
包添加一个新的函数来反转数字。在
workspace/example/hello/reverse
目录中创建一个名为int.go
的新文件,包含以下内容package reverse import "strconv" // Int returns the decimal reversal of the integer i. func Int(i int) int { i, _ = strconv.Atoi(String(strconv.Itoa(i))) return i }
-
修改 hello 程序以使用该函数。
修改
workspace/hello/hello.go
的内容,使其包含以下内容package main import ( "fmt" "golang.org/x/example/hello/reverse" ) func main() { fmt.Println(reverse.String("Hello"), reverse.Int(24601)) }
在工作区中运行代码
从工作区目录,运行
$ go run ./hello
olleH 10642
Go 命令在 go.work
文件指定的 hello
目录中找到命令行中指定的 example.com/hello
模块,并类似地使用 go.work
文件解析 golang.org/x/example/hello/reverse
导入。
go.work
可用于替代向 replace
指令添加以跨多个模块工作。
由于这两个模块位于同一个工作区中,因此很容易在一个模块中进行更改并在另一个模块中使用它。
未来步骤
现在,要正确发布这些模块,我们需要发布 golang.org/x/example/hello
模块,例如在 v0.1.0
处。这通常通过在模块的版本控制存储库上标记提交来完成。有关更多详细信息,请参阅 模块发布工作流程文档。发布完成后,我们可以增加 hello/go.mod
中对 golang.org/x/example/hello
模块的要求
cd hello
go get golang.org/x/example/[email protected]
这样,go
命令就可以在工作区之外正确解析模块。
了解有关工作区的更多信息
除了本教程前面介绍的 go work init
之外,go
命令还有一些用于处理工作区的子命令
go work use [-r] [dir]
为dir
(如果存在)的go.work
文件添加use
指令,如果参数目录不存在,则删除use
目录。-r
标志递归地检查dir
的子目录。go work edit
以类似于go mod edit
的方式编辑go.work
文件go work sync
将工作区构建列表中的依赖项同步到每个工作区模块中。
有关工作区和 go.work
文件的更多详细信息,请参阅 Go 模块参考中的 工作区。