文章目录
【Go语言成长之路】多模块工作区入门
多模块工作区(muti-module workspaces)可以使得开发者在多个模块中构建并且运行代码,相互独立,互不干扰。
本教程中,将会创建两个模块来共享一个多模块工作区,并且跨模块进行更改,在构建中查看这些更改的结果。
前提条件
-
Go1.18以及之后的版本
-
命令终端。 Go 可以在 Linux 和 Mac 上的任何终端以及 Windows 中的 PowerShell 或 cmd 上正常运行
-
一个编辑代码的工具(文本编辑器)
一、创建一个模块
-
创建工作目录
创建一个新的工作空间,名称为workspace
sh~$ mkdir workspace ~/workspace$ cd workspace
-
初始化模块
创建一个新的模块,名称为hello
sh~/workspace$ mkdir hello ~/workspace$ cd hello ~/workspace/hello$ go mod init example.com/hello go: creating new go.mod: module example.com/hello
在 hello 目录下创建 hello.go,内容如下:
gopackage main import ( "fmt" "golang.org/x/example/hello/reverse" ) func main() { fmt.Println(reverse.String("Hello")) }
可以看到,在代码中,我们有着一个依赖外部包,因此需要使用go get添加对
golang.org/x/example/hello/reverse
包的依赖:sh~/workspace/hello$ go get golang.org/x/example/hello/reverse go: downloading golang.org/x/example v0.0.0-20240716161537-39e772fc2670 go: downloading golang.org/x/example/hello v0.0.0-20240716161537-39e772fc2670 go: added golang.org/x/example/hello v0.0.0-20240716161537-39e772fc2670
最后,运行hello程序
sh~/workspace/hello$ go run hello.go olleH
二、创建工作空间
在此步骤中,我们将创建一个 go.work 文件来指定模块的工作区。
-
初始化工作空间
sh~/workspace$ go work init ./hello/ ~/workspace$ cat go.work go 1.23.0 # go 指令告诉 Go 应使用哪个版本的 Go 来解释该文件 use ./hello # use 指令告诉 Go 在构建时 hello 目录中的模块应该是主模块。因此,在工作区的任何子目录中,该模块都将处于活动状态。
go work init 命令告诉 go 为包含 ./hello 目录中的模块的工作空间创建一个 go.work 文件。
-
运行工作空间目录下的程序
sh$ go run ./hello olleH
在模块或工作区之外运行 go run 命令会导致错误, 但是在工作区内运行则可以通过。
三、创建第二个模块
-
创建模块
sh~/workspace$ mkdir second ~/workspace/second$ touch second.go package second import ( "fmt" ) func Hello() { fmt.Println("second") } ~/workspace/second$ go mod init example.com/second ~/workspace/second$ go mod tidy
-
将模块添加到工作区
second
模块位于./second
内,将其添加到工作区:sh~/workspace$ go work use second
通过使用
go work use
命令就成功地将一个新模块添加到工作区内了,添加后的go.work内容如下所示:sh~/workspace$ cat go.work go 1.23.0 use ( ./hello ./second )
-
修改 hello 程序以使用该函数
gopackage main import ( "fmt" "github.com/pzs/second" "golang.org/x/example/hello/reverse" ) func main() { fmt.Println(reverse.String("Hello")) second.Hello() }
-
添加replace以引用本地包
修改hello包下的go.mod文件:
shreplace github.com/pzs/second => ../second
之后运行go mod tidy命令:
sh~/workspace/hello$ go mod tidy go: found github.com/pzs/second in github.com/pzs/second v0.0.0-00010101000000-000000000000
注:若引用的不是本地包,而是外部下载到本地的包修改后引用的话,则可以不使用replace,直接引用即可。默认会直接应用本地的包,而不是外部包。关于具体的例子,可以参考官方的文档: https://go.dev/doc/tutorial/workspaces
-
在工作空间中运行代码
sh~/workspace$ go run ./hello/ olleH second
Go命令在
go.work
文件指定的hello目录中查找命令行指定的example.com/hello
模块。注:由于这两个模块位于同一工作区中,因此可以轻松地在一个模块中进行更改并在另一个模块中使用它。
四、更多关于workspace
go work的子命令:
go work use [-r] [dir]
: 将 use 指令添加到 dir 的 go.work 文件中(如果存在),如果参数目录不存在,则删除 use 目录。 -r 标志递归地检查 dir 的子目录。go work edit
: 编辑 go.work 文件,类似于 go mod editgo work sync
将工作区构建列表中的依赖项同步到每个工作区模块中。
有关工作区和 go.work 文件的更多详细信息,请参阅 Go 模块参考中的Workspaces 。