admin 管理员组

文章数量: 887007

Go工作空间

摘要:工作空间是Go 1.18新添加的特性,英文名叫workspace,同时还有和工作空间相关的命令go work。工作空间与Go模块是完全不同的概念。模块是代码组织的一种方式,工作空间本质上是一个目录,它影响的是编译器的工作,只在开发人员的本地发挥作用。工作空间的出现是为了方便多模块开发模式,本文将会介绍任何使用工作空间进行开发。


Go Module的开发模式

从Go1.11开始,Go Module横空出世,让我们摆脱了Go Path,从此代码可以放在任意地方。虽然饱受争议,但也在磕磕盼盼中逐渐被人们接受。由于Go工作空间并不是Go Module的替代之物,所以还是让我们从Go Module开始吧。

首先找一个地方,打开PowerShell,然后依次执行以下命令。

mkdir work
cd work
mkdir hello
mkdir world
cd hello
go mod init github/caiwangg/hello
new-item hello.go
cd ../world
go mod init github/caiwangg/world
new-item world.go

其实,上面的命令做了这样一件事:创建一个work文件夹,进入work文件夹创建helloworld两个目录。然后分别在两个目录中初始化Go模块,并分别在两个目录中创建hello.goworld.go文件。

这就是一个简单的多模块开发场景,在工作中也很常见,比如我们可能需要同时开发主项目和公共的工具库。作为例子,我们只是模仿这一形式。

接下来用你喜欢的代码编辑器打开hello.go,输入以下代码。

package hellofunc SayHello(name string) string {return "Hello, " + name + " !"
}

同样,在world.go中输入以下代码。

package mainimport ("fmt""github/caiwangg/hello"
)func main() {name := "Caiwangg"fmt.Println(hello.SayHello(name))
}

为了在world中能够调用hello模块的函数,我们还需要修改一下world模块中的go.mod文件,在文件最后添加以下两行内容。

require github/caiwangg/hello v0.1.0replace github/caiwangg/hello v0.1.0 => ../hello

现在切换到world目录下,执行以下命令运行项目。

PS XXX\work\world> go run .
Hello, Caiwangg !

看到Hello, Caiwangg !的输出说明我们的项目是正常的。但是这其中有一个小小的问题,我们的代码不可能永远放在本地,不管是hello模块还是world模块,它们都有对应的代码仓库,尽管我们的例子中没有显示出这一点。

为了使用本地正在开发的hello模块,我们不得不在world模块的go.mod文件中使用replace指令。当我们要将world模块推送到代码仓库时,又必须把replace去掉。频繁的修改go.mod文件对我们来说将是一个麻烦。

Go工作空间

我们在上一节中创建的work目录就是为工作空间做准备的。首先我们在powershell中切换到work目录,然后执行以下命令:

go work init world hello

以上命令用来初始化工作空间,它会在work目录下创建一个go.work文件,命令中的worldhello都会出现在go.work文件的use模块中。以下就是我们的go.work文件的内容。

go 1.18use (./hello./world
)

该命令的基本语法是go work init [moddirs],如果不提供moddirs,将会创建一个空的工作空间。工作空间声明了一组模块,同一个工作空间中的模块互相可见,可以直接使用。

工作空间创建以后,还可以通过go work use [-r] moddirs添加模块,-r表示递归子目录。当然你也可以直接在代码编辑器中编辑go.work文件。

现在,我们把之前在worldgo.mod文件中添加的那两行去掉,也就是将它恢复成如下样子。

module github/caiwangg/worldgo 1.18// require github/caiwangg/hello v0.1.0// replace github/caiwangg/hello v0.1.0 => ../hello

理论上来说,这时在work目录下运行go run .\world是编译不过的,因为找不到hello模块。但是由于go.work的存在,神奇的事情发生了,代码成功编译并运行,输出了Hello, Caiwangg !

这就是工作空间的魅力,我们不需要replace指令,也不需要在提交代码时修改go.mod文件。编译器会自动使用工作空间下的模块,对于多模块同时开发的场景,这简直就是福音。也许在一开始你认为不会多线作战,但是公共模块这个东西往往都是在项目开发过程中被拆分出去的,因为项目架构也是随着开发在变化的。当你在项目开发的中途想拆分模块时,工作空间会让拆分过程更加丝滑无痛。

总结

总结个屁,冲就完了。


附录

Tutorial: Getting started with multi-module workspaces

本文标签: Go工作空间