使用模块时,Go get找不到本地包

Tob*_*ore 24 module go go-modules

我遇到了go新模块系统的问题,因为我想定义一个本地模块并将其导入主程序中.本地程序包驻留在主程序包/根文件夹的文件夹中.想象一下以下的项目结构$GOPATH.

项目结构

./main.go

package main

import "fmt"
import "example.com/localModule/model"

func main() {
    var p = model.Person{name: "Dieter", age:25}
    fmt.Printf("Hello %s\n", p.name)
}
Run Code Online (Sandbox Code Playgroud)

./model/person.go

package model

type Person struct {
    name string
    age int
}
Run Code Online (Sandbox Code Playgroud)

在根文件夹中,我通过调用初始化了一个模块

go mod init example.com/localModule
Run Code Online (Sandbox Code Playgroud)

model/文件夹中,然后通过调用初始化子模块

go mod init example.com/localModule/model
Run Code Online (Sandbox Code Playgroud)

错误

在根文件夹中调用以下命令失败.

$ go get
go build example.com/localModule/model: no Go files in

$ go build
main.go:4:8: unknown import path "example.com/localModule/model": cannot find module providing package example.com/localModule/model
Run Code Online (Sandbox Code Playgroud)

go get的错误消息被切断了,我不会错误地解析它.

我不打算推动模块到服务器,并与只需要引用本地包的方式model,所以我选择了example.com/localModule/example.com/localModule/model分别.

我在go1.11 darwin/amd64运行MacOS 10.13.6的Macbook上使用.

小智 36

您可以通过在go.mod中添加require语句和匹配的replace语句以及相对文件路径来获得您所要求的本地"子"模块.

在"root"./go.mod中:

module example.com/localModule

require example.com/localModule/model v0.0.0

replace example.com/localModule/model v0.0.0 => ./model
Run Code Online (Sandbox Code Playgroud)


typ*_*182 6

根本问题

您收到此错误的原因是您定义了两个不知道如何在本地磁盘上找到彼此的模块。

$ go build
main.go:4:8: unknown import path "example.com/localModule/model": 
 cannot find module providing package example.com/localModule/model
Run Code Online (Sandbox Code Playgroud)

解决方案1: replace

您可以replace在顶层模块的go.mod文件中添加一条指令,例如:

replace example.com/localModule/model v0.0.0 => ./model

这让顶层模块在磁盘上找到另一个模块。模块 wiki 上的替换常见问题解答“多模块存储库”部分对此进行了更详细的介绍。

然而,这是一个更复杂的解决方案,可能很难做到正确,通常是更多的持续工作,并且有一些限制,比如replace对除当前模块之外的所有模块都被忽略。对于大多数人来说,多模块存储库可能不是他们想要的。在这一点上,真正需要在单个存储库中有多个模块的情况相对较少。

解决方案 2:一个 repo == 一个模块

虽然可以使用replace指令,但更常见和直接的解决方案是:

  • go.mod在您的存储库中有一个文件,并且
  • 将该单个go.mod文件放在存储库的根目录中。

这是一个非常简单的解决方案,这意味着您在存储库中的两个包将能够在不需要任何 的情况下自动找到彼此replace,并且避免了您报告的错误消息。

replace 使用多模块回购与单模块回购?

Russ Cox 在#26664 中评论道:

对于除高级用户之外的所有用户,您可能希望采用通常的约定,即一个 repo = 一个模块。一个 repo可以包含多个模块,这对于代码存储选项的长期发展很重要,但几乎可以肯定,默认情况下你不想这样做。

如果您希望在单个存储库中定义多个模块,那么如何正确执行此操作存在相当多的细微差别,并且应该阅读 Modules wiki的整个部分,了解如何管理相关的复杂性单个存储库中的多个模块,包括以下建议:

在单个存储库中添加模块、删除模块和对具有多个模块的模块进行版本控制需要相当谨慎和深思熟虑,因此管理单模块存储库几乎总是比现有存储库中的多个模块更容易和更简单