教程:开始使用多模块工作区
本教程介绍 Go 中多模块工作区的基础知识。使用多模块工作区,您可以告诉 Go 命令您正在同时在多个模块中编写代码,并轻松地在这些模块中构建和运行代码.
在本教程中,您将在共享的多模块工作区中创建两个模块,对这些模块进行更改,并在构建中查看这些更改的结果.
注意: 有关其他教程,请参阅 教程.
先决条件
- Go 1.18 或更高版本的安装.
- 用于编辑代码的工具. 您拥有的任何文本编辑器都可以正常工作.
- 一个命令终端. Go 在 Linux 和 Mac 上的任何终端以及 Windows 中的 PowerShell 或 cmd 上都能很好地工作.
本教程需要 go1.18 或更高版本. Make sure you’ve installed Go at Go 1.18 or later using the links at go.dev/dl.
为您的代码创建一个模块
首先,为您要编写的代码创建一个模块.
-
打开命令提示符并切换到您的主目录.
在 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 模块的依赖项.$ go get golang.org/x/example
在 hello 目录下创建 hello.go,内容如下:
package main import ( "fmt" "golang.org/x/example/stringutil" ) func main() { fmt.Println(stringutil.Reverse("Hello")) }
现在,运行 hello 程序:
$ go run example.com/hello olleH
创建工作区
在这一步中,我们将创建一个 go.work
文件来指定模块的工作区.
初始化工作区
在 workspace
目录中,运行:
$ go work init ./hello
The go work init
command tells go
to create a go.work
file
for a workspace containing the modules in the ./hello
directory. (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 example.com/hello
olleH
Go 命令包含工作区中的所有模块作为主模块。这允许我们在模块中引用一个包,甚至在模块之外。在模块或工作区之外运行go run
命令会导致错误,因为 go
命令不知道要使用哪些模块。
接下来,我们将 golang.org/x/example
模块的本地副本添加到工作区。然后,我们将向stringutil
包中添加一个新函数,我们可以使用它来代替 Reverse
.
下载和修改 golang.org/x/example
模块
在此步骤中,我们将下载包含 golang.org/x/example
模块的 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.
-
将模块添加到工作区
$ go work use ./example
go work use
命令将一个新模块添加到 go.work 文件中。它现在看起来像这样:go 1.18 use ( ./hello ./example )
模块现在包括
example.com/hello
模块和golang.org/x/example
模块.这将允许我们使用将在
stringutil
模块副本中编写的新代码,而不是使用go get
命令下载的模块缓存中的模块版本. -
添加新函数.
我们将向
golang.org/x/example/stringutil
包中添加一个新函数以将字符串变大写。在
workspace/example/stringutil
目录中创建一个名为toupper.go
的新文件,其中包含以下内容:package stringutil import "unicode" // ToUpper uppercases all the runes in its argument string. func ToUpper(s string) string { r := []rune(s) for i := range r { r[i] = unicode.ToUpper(r[i]) } return string(r) }
-
修改hello程序以使用该函数.
修改
workspace/hello/hello.go
的内容以包含以下内容:package main import ( "fmt" "golang.org/x/example/stringutil" ) func main() { fmt.Println(stringutil.ToUpper("Hello")) }
在工作区运行代码
从工作区目录,运行
$ go run example.com/hello
HELLO
Go 命令在 go.work
文件指定的 hello
目录中查找命令行中指定的example.com/hello
模块,并同样使用 go.work
文件解析 golang.org/x/example
导入。
可以使用 go.work
,而不是添加replace
指令来跨多个模块工作。
由于这两个模块在同一个工作区中,因此很容易在一个模块中进行更改并在另一个模块中使用它.
未来步骤
现在,要正确发布这些模块,我们需要发布golang.org/x/example
模块,例如在v0.1.0
。这通常是通过在模块的版本控制存储库上标记一个提交来完成的。有关更多详细信息,请参阅模块模块发布工作流文档。发布完成后,我们可以在 hello/go.mod
中增加对 golang.org/x/example
模块的要求( increase the requirement):
cd hello
go get golang.org/x/example@v0.1.0
这样, go
命令可以正确解析工作区之外的模块.
了解有关工作区的更多信息
go
命令有几个子命令,用于处理工作区,除了 go work init
之外,我们在本教程前面看到过:
go work use [-r] [dir]
将use
指令添加到dir
的go.work
文件中(如果存在),如果参数目录不存在,则删除use
目录。-r
标志以递归方式检查dir
的子目录。go work edit
编辑go.work
文件,类似于go mod edit
go work sync
将工作区构建列表中的依赖项同步到每个工作区模块中。
有关工作区和 go.work
文件的更多详细信息,请参阅 Go 模块参考中的 Workspaces 。