3
头图

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 dependent example.com/util , you can use the go 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


coding进阶
116 声望18 粉丝