background
In addition to the introduction of generics and fuzzing in Go 1.18, another major feature is the introduction of workspace mode.
The workspace mode is very useful for scenarios where multiple dependent Modules are developed locally at the same time .
For example, we currently have 2 Go module projects under development, one is example.com/main
and the other is example.com/util
. Among them example.com/main
this module needs to use example.com/util
the function in this module.
Let's see how this scenario was handled before and after Go 1.18.
How to do it before Go 1.18
Before Go 1.18, there were 2 solutions for the above scenario:
Option 1: Dependent modules submit code to the code repository in a timely manner
This program is well understood, since example.com/main
This module relied example.com/util
this module, that order example.com/main
can be used to example.com/util
the latest code , you need to do 2 things
- During the local development process, if
example.com/util
is modified, submit the code to the code repository immediately, and then tag - Immediately after
example.com/main
update the version number (tag) of the dependentexample.com/util
, you can use thego get -u
command.
This solution is rather cumbersome. Every time example.com/util
is modified, the code must be submitted, otherwise example.com/main
this module cannot use the latest example.com/util
.
Option 2: Use the replace command in go.mod
In order to solve the pain point of solution 1, there is solution 2: use the replace command in go.mod.
Through the replace command, we can directly use the latest local code of this module example.com/util
16448737af8abfc211c0b855a78c263a--- without submitting the code of example.com/util
to the code repository.
In order to facilitate everyone's understanding, we directly go to the code. The code directory structure is as follows:
module
|
|------main
| |---main.go
| |---go.mod
|------util
| |---util.go
| |---go.mod
The code in the main directory main.go
is as follows:
//main.go
package main
import (
"fmt"
"example.com/util"
)
func main() {
result := util.Add(1, 2)
fmt.Println(result)
}
The contents of the main directory go.mod
are as follows:
module example.com/main
go 1.16
require example.com/util v1.0.0
replace example.com/util => ../util
The code in the util directory util.go
is as follows:
// util.go
package util
func Add(a int, b int) int {
return a + b
}
The contents of go.mod
in the util directory are as follows:
module example.com/util
go 1.16
The core here is example.com/main
go.mod
this module, the last line uses the replace instruction.
module example.com/main
go 1.16
require example.com/util v1.0.0
replace example.com/util => ../util
Through the replace command, when you use the go command to compile the code, the local util directory will be found, so that example.com/main
can use the latest local example.com/util
code. Enter the main directory and run the code, the result is as follows:
$ cd main
$ go run main.go
3
But this solution also has a problem. When we submit example.com/main
the code of this module to the code repository, we need to delete the last replace instruction, otherwise other developers will compile and report an error after downloading, because they may not have util locally. directory, or the path to the util directory is not the same as yours.
Code open source address: Use replace instruction before Go 1.18
Go 1.18 workspace mode
To address the pain point of solution 2, a workspace mode was added in Go 1.18.
In this mode, it is no longer necessary to use the replace command in go.mod
, but a new go.work
file is added.
Not much to say, go directly to the code. The code directory structure is as follows:
workspace
|------go.work
|
|------main
| |---main.go
| |---go.mod
|------util
| |---util.go
| |---go.mod
The code in the main directory main.go
is as follows:
//main.go
package main
import (
"fmt"
"example.com/util"
)
func main() {
result := util.Add(1, 2)
fmt.Println(result)
}
The contents of the main directory go.mod
are as follows: there is no replace instruction in the last line of scheme 2
module example.com/main
go 1.16
require example.com/util v1.0.0
The code in the util directory util.go
is as follows:
// util.go
package util
func Add(a int, b int) int {
return a + b
}
The contents of go.mod
in the util directory are as follows:
module example.com/util
go 1.16
go.work
The content is as follows:
go 1.18
use (
./main
./util
)
Execute the following command in the workspace directory to automatically generate go.work
$ go1.18beta1 work init main util
go1.18beta1 work init
followed by main
and util
are the directories corresponding to Module.
If the current directory or parent directory executed by the go command has the go.work
file, or the path of go.work
specified by the GOWORK
environment variable, the go command will enter the work. zone mode. In workspace mode, go can find and use the local module code through the module path under go.work
.
In the main directory or the workspace directory, you can run main.go
, the result is as follows:
$ go1.18beta1 run main/main.go
3
$ cd main/
$ go1.18beta1 run main.go
3
In this mode, we do not have any local intrusive modifications to example.com/main
, and do not need to update the go.mod
file before submitting the code as in scheme 2. example.com/main
can be directly submitted to the code repository.
Code open source address: Go 1.18 workspace mode
Note : go.work
does not need to be submitted to the code repository, only for local development use.
Summarize
In order to solve the problem of local simultaneous development of multiple dependent Modules, Go 1.18 introduced the workspace mode.
The workspace mode is an optimization of the existing Go Module development mode. For more details about the workspace mode, please refer to the References at the end of this article.
open source address
Articles and sample code are open sourced on GitHub: Beginner, Intermediate, and Advanced Tutorials in Go .
Official account: coding advanced. Follow the official account to get the latest Go interview questions and technology stacks.
Personal website: Jincheng's Blog .
Zhihu: Wuji .
References
- Proposal: https://go.googlesource.com/proposal/+/master/design/45713-workspace.md
- Workspace official tutorial: https://go.dev/doc/tutorial/workspaces
- workspace syntax: https://go.dev/ref/mod#go-work-file-replace
- go work command manual: https://pkg.go.dev/cmd/go@master#hdr-Workspace_maintenance
- go 1.18 release notes: https://tip.golang.org/doc/go1.18
- How Go references the local Module: https://github.com/jincheng9/go-tutorial/tree/main/workspace/lesson27#%E5%BC%80%E5%90%AFgo111modules%E6%97%B6import%E6%9C %AC%E5%9C%B0%E7%9A%84module
- polarisxu: https://polarisxu.studygolang.com/posts/go/dynamic/go1.18-workspace/
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。