go 工作区(workspace)模式

使用go写一个处理数学运算的小通用包

go.mod文件如下

module gitee.com/demo_go/utils_mathgo 1.25.3

utilsmath.go 文件内容如下

package utilsmathimport "fmt"func AddInt(a, b int) int {fmt.Printf("utilsmath 内部方法 AddInt %d + %d", a, b)return a + b
}

这里有几个地方,需要注意

  1. 使用mod声明的时候,不需要带上 .git 后缀(如果无脑从git上复制地址,会把.git 一起复制上)
  • 不规范声明: go mod init gitee.com:demo_go/utils_math.git
  • 正确 声明: go mod init gitee.com:demo_go/utils_math
  1. package名称应该和 mod名称一致,避免歧义,比如上面的
package utilsmath
改为 
package utils_math

如果不改,在其他工具引用时,就会导致如下样式

package mainimport ("fmt"// 这要起别名才行,看起来很麻烦utilsmath "gitee.com/demo_go/utils_math"
)func main() {b := utilsmath.AddInt(1, 2)fmt.Println("------------------------")fmt.Println(b)
}

go work 使用

上面的例子,最终目录结构如下

.
├── student
│   ├── go.mod
│   ├── go.sum
│   └── main.go
└── utils_math├── go.mod└── main.go

在使用utils_math工具包的时候,我们发现如下问题。
image
这时候,就有个问题,在 student 这个项目中,引用的 utils_math,如果改代码,改完以后,必须要

  1. 在 utils_math 改完
  2. 将 utils_math 最新的改动,推送到 git 上去
  3. 在 student 项目中,拉取最新代码

如果在调试过程中,这么搞,就很繁琐,而且,你改的也不一定对,这时候,就可以考虑使用 go work 了。

使用 go work 托管

返回到 utilsstudent 两个共用的父级目录,执行如下命令

go work init ./student ./utils_math

go work init 后面跟的是 go.mod 文件所在的路径,最终目录结构如下:

.
├── go.work
├── student
│   ├── go.mod
│   ├── go.sum
│   └── main.go
└── utils_math├── go.mod└── main.go

此时,再在 student 项目中运行 go run main.go,就是直接引用的 utils_math 项目中的代码了,此次 student 中的 go.mod等代码,都没有变化

原理

  1. 检测到当前目录或父目录中存在 go.work;

  2. 自动将 use 中列出的模块都纳入编译视图;

  3. 如果 A 的 import 引用了 example.com/B,Go 会优先在 workspace 中查找是否存在该模块;

  4. 发现 B 模块在 use ./B 中,于是直接使用本地路径;

  5. 不再去下载远程依赖,也不修改 go.mod。