Golang中Go.work的使用:如何管理模块与文件夹的对应关系

Golang中Go.work的使用:如何管理模块与文件夹的对应关系 在替换方式中,存在一对一的映射关系,例如,模块 example.com/hello 被映射到文件夹 ../hello

$ go mod edit -replace example.com/hello=../hello

go.mod:
replace example.com/hello => ../hello

但在新的多模块工作区方式中,没有这样的映射关系。如何确定哪个模块在使用文件夹 ./hello 呢?

go.work:
use ./hello

是否也像下面这样明确写出映射关系会更好呢:

example.com/hello => ./hello

谢谢


更多关于Golang中Go.work的使用:如何管理模块与文件夹的对应关系的实战教程也可以访问 https://www.itying.com/category-94-b0.html

7 回复

是的,这很好地概括了这一点。

更多关于Golang中Go.work的使用:如何管理模块与文件夹的对应关系的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这同样有效。每个本地模块都通过其模块路径 go.mod 被唯一标识。

// 代码示例应放置在此处

谢谢 Christoph,

如果我有多个仓库/模块怎么办

example.com/hello1
example.com/hello2
example.com/hello3
example1.com/hello
example2.com/hello
example3.com/hello

以及多个文件夹

./hello1
./hello2
./hello3

谢谢。

我想我大概明白了。

如果存在 go.work 文件,import example.com/module 会首先尝试 go.work 中列出的本地目录。如果找不到,才会尝试在线仓库。并且像 example.com/modulegithub.com/golang/glog 这样的模块名是唯一的,所以不会有歧义。我的理解对吗?

感谢 Christoph,

但是 go.mod 文件中没有 replace 行:

replace example.com/hello => ../hello

使用 go.work 方式,它只有 require 行。

module main

go 1.18

require example1.com/hello v1.0.0
require example2.com/hello v1.0.0
require example3.com/hello v1.0.0

我如何知道上面哪个仓库/模块,链接到了下面的 ./hello?

go.work:
use ./hello

你好 @ljh

位于 ./hello 的模块有一个包含模块路径的 mod 文件。

每当主模块(即你执行 Go 命令的模块)存在一个 go.work 文件时,任何与 ./hello/go.mod 中模块路径匹配的导入路径都将被重定向到本地模块。

示例:

主模块中的 go.work

use ./hello

./hello/go.mod

module git.hoster/my/repository

main.go

import "git.hoster/my/repository"

在这里,导入路径与 ./hello 中本地模块的模块路径匹配,Go 命令将使用这个本地模块,而不是远程模块。

(免责声明:晚上10:30在手机上写的——所有错误都归我。)

在 Go 1.18+ 的多模块工作区中,go.work 文件确实不直接声明模块路径与目录的映射关系。工作区机制通过扫描指定目录下的 go.mod 文件自动建立关联。要确定哪个模块在使用 ./hello 目录,需要检查该目录下的 go.mod 文件。

示例:

# 查看 ./hello 目录下的 go.mod 文件
$ cat ./hello/go.mod

# 输出示例:
module example.com/hello

go 1.20

go.work 文件示例:

go 1.20

use (
    ./hello
    ./world
)

当执行 go work use ./hello 时,Go 工具会:

  1. 读取 ./hello/go.mod 获取模块路径 example.com/hello
  2. 将工作区内的导入路径 example.com/hello 解析到 ./hello 目录

验证方法:

// 在工作区根目录创建测试文件
package main

import (
    "fmt"
    "example.com/hello" // 自动指向 ./hello 目录
)

func main() {
    fmt.Println(hello.Message)
}

如果需要显式查看映射关系,可以使用:

$ go work edit -json
{
    "go": "1.20",
    "use": [
        {"path": "./hello", "module": "example.com/hello"},
        {"path": "./world", "module": "example.com/world"}
    ]
}

这种设计避免了手动维护映射,通过 go.mod 文件自动建立关联,确保模块声明的路径与实际使用路径一致。

回到顶部