教程:开始使用多模块工作区
5 分钟阅读
Tutorial: Getting started with multi-module workspaces - 教程:开始使用多模块工作区
本教程介绍了Go中多模块工作区的基本知识。通过多模块工作区,您可以告诉Go命令您同时在多个模块中编写代码,并在这些模块中轻松构建和运行代码。
在本教程中,您将在一个共享的多模块工作区中创建两个模块,对这些模块进行修改,并在构建中看到这些修改的结果。
注意:关于其他教程,请看Tutorials。
前提条件
- 安装
Go 1.18
或更高版本。 - 编辑代码的工具。任何文本编辑器都可以使用。
- 命令终端。Go在Linux和Mac上使用任何终端,在Windows上使用
PowerShell
或cmd
,都能很好地工作。
本教程需要go1.18
或更高版本。请确保您已经使用 go.dev/dl 的链接安装了Go 1.18
或更高版本。
为您的代码创建一个模块
首先,为您将要写的代码创建一个模块。
a. 打开一个命令提示符,换到您的主目录。
在Linux或Mac上:
|
|
在Windows上:
|
|
本教程的其余部分将显示一个$
作为提示符。您使用的命令在Windows上也可以使用。
b. 在命令提示符下,为您的代码创建一个名为workspace
的目录。
|
|
c. 初始化模块。
我们的示例将创建一个新的模块 hello
,它将依赖于 golang.org/x/example
模块。
创建hello
模块:
|
|
通过使用go get
添加对golang.org/x/example
模块的依赖。
|
|
在hello
目录下创建hello.go
,内容如下:
|
|
现在,运行hello
程序:
|
|
创建工作区
在这一步骤中,我们将创建一个go.work
文件来指定模块的工作区。
初始化工作区
在workspace
目录下,运行:
|
|
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
目录下运行程序
在workspace
目录下,运行:
|
|
The Go command includes all the modules in the workspace as main modules. This allows us to refer to a package in the module, even outside the module. Running the go run
command outside the module or the workspace would result in an error because the go
command wouldn’t know which modules to use.
Go命令将workspace
中的所有模块都作为主模块
。这使得我们可以引用模块中的包,甚至在模块之外。在模块或workspace
之外运行go run
命令会导致错误,因为go
命令不知道要使用哪些模块。=> 仍有疑问??
接下来,我们将在workspace
中添加一份 golang.org/x/example
模块的本地副本。然后我们将在stringutil
包中添加一个新的函数,我们可以用它代替Reverse
。
下载并修改golang.org/x/example
模块
在这一步骤中,我们将下载一份包含 golang.org/x/example
模块的 Git repo 的副本,将其添加到workspace
,然后为其添加一个新函数,我们将在 hello
程序中使用它。
a. 克隆仓库。
在 workspace
目录下,运行git
命令来克隆版本库:
|
|
b. 将该模块添加到workspace
|
|
go work use
命令在go.work
文件中添加了一个新模块。现在它看起来像这样:
go 1.18
use (
./hello
./example
)
该模块现在同时包括example.com/hello
模块和golang.org/x/example
模块。
这将使我们能够使用我们将在stringutil
模块副本中编写的新代码,而不是我们用go get
命令下载的模块缓存中的模块版本。
c. 添加新函数。
我们将在 golang.org/x/example/stringutil
包中添加一个新函数来对字符串进行大写。
在workspace/example/stringutil
目录下创建一个名为toupper.go
的新文件,包含以下内容:
|
|
d. 修改hello
程序以使用该函数。
修改workspace/hello/hello.go
的内容,使其包含以下内容:
|
|
在workspace
运行代码
从 workspace
目录中,运行
|
|
Go命令在go.work
文件指定的hello
目录下找到了命令行中指定的example.com/hello
模块,并同样使用go.work
文件解析了golang.org/x/example
的导入。
go.work
可以用来代替跨多模块工作时使用的 replace 指令。
由于这两个模块在同一个workspace
中,所以很容易在一个模块中做出改变,并在另一个模块中使用它。
未来的步骤
现在,为了正确地发布这些模块,我们需要对 golang.org/x/example
模块进行发布,例如在 v0.1.0
。这通常是通过在模块的版本控制库中标记一个提交来完成的。更多细节请参见模块发布工作流程文档。发布完成后,我们可以在 hello/go.mod
中增加对 golang.org/x/example
模块的要求:
|
|
这样一来,go
命令就可以正确解决workspace
外的模块了。
了解更多关于工作区的信息
除了我们在教程前面看到的go work init
外,go
命令还有几个子命令用于处理工作区:
go work use [-r] [dir]
在go.work
文件中为dir
添加一个use
指令(如果该dir
存在的话),如果参数目录不存在,则删除使用目录。-r
标志会递归地检查dir
的子目录。go work edit
编辑go.work
文件,与go mod edit
类似。go work sync
将工作区构建列表中的依赖项同步到每个工作区模块中。
关于 workspaces 和go.work
文件的更多细节,请参见Go模块参考中的Workspaces。