【问题标题】:Import provided by both the main module and the vendor directory is flagged as an error主模块和供应商目录提供的导入被标记为错误
【发布时间】:2021-02-21 18:17:48
【问题描述】:

我想了解我在复习 go 模块和供应商目录时遇到的错误的原因。显然,在主模块和供应商文件夹中具有相同的包会导致错误,我想了解原因。据我了解,如果有 go.mod go 甚至不应该检查 vendor 文件夹的依赖关系。一旦我运行 go run ./main.go 我得到以下错误:

main.go:3:8: ambiguous import: found package test/testpkg in multiple directories:
        /Users/mic4ael/dev/mine/something-in-go/testpkg
        /Users/mic4ael/dev/mine/something-in-go/vendor/test/testpkg

但是,当go build -mod=mod 用于构建二进制文件时,不会发生这种情况。我会很感激解释为什么会这样。

GO111MODULE=""
$ tree
.
├── go.mod
├── main.go
├── test
├── testpkg
│   └── lib.go
└── vendor
    └── test
        └── testpkg
            └── lib.go

去.mod

module test

go 1.15

main.go

package main

import "test/testpkg"

func main() {
    testpkg.Echo("Test")
}

供应商/test/testpkg/lib.go

package testpkg

import "fmt"

func Echo(str string) {
    fmt.Printf("From vendored package %s\n", str)
}

testpkg/lib.go

package testpkg

import "fmt"

func Echo(str string) {
    fmt.Printf("From internal pkg: %s\n", str)
}

【问题讨论】:

  • 我可以看到 here 为什么会发生这种情况,但我仍然不明白为什么。

标签: go go-modules govendor


【解决方案1】:

有两个同名的包,这就是歧义。当您导入test/testpkg 时,它可以从项目本身或供应商目录中导入。

使用 go 模块不会改变 vendoring 行为。实际上,您可以使用go mod vendor 来本地供应模块。如果一个包出现在vendor/ 下,它将从供应商的副本中使用,否则将从模块缓存中下载和使用。但是,如果您的项目中有一个包与 vendor 下的包之一同名,则存在歧义。

【讨论】:

  • 我知道歧义来自哪里,但是在模块感知上下文中,go 不应该跳过供应商文件夹吗?
  • 它没有。您仍然可以供应外部依赖项。
  • 我还是不明白为什么运行go build -mod=mod 没有同样的问题。 -mod=mod 有什么变化?
  • 好的,nvm,我在go help modules找到了答案
猜你喜欢
  • 2014-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-09
  • 1970-01-01
相关资源
最近更新 更多