Импорт, предоставляемый как основным модулем, так и каталогом поставщиков, помечается как ошибка

#go #go-modules #govendor

#Вперед #go-модули #govendor

Вопрос:

Я хотел бы понять причину ошибки, с которой я столкнулся при обновлении модулей 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
  

go.mod

 module test

go 1.15
  

main.go

 package main

import "test/testpkg"

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

vendor/test/testpkg/lib.go

 package testpkg

import "fmt"

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

testpkg/lib.go

 package testpkg

import "fmt"

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

Комментарии:

1. Здесь я вижу, почему это происходит, но я все еще не понимаю, почему.

Ответ №1:

Есть два пакета с одинаковым именем, и в этом заключается двусмысленность. При импорте test/testpkg он может быть импортирован из самого проекта или из каталога поставщиков.

Использование модулей go не изменяет поведение поставщика. Фактически, вы можете использовать go mod vendor модули поставщика локально. Если пакет появляется под vendor/ ним, он будет использоваться из копии поставщика, в противном случае он будет загружен и использован из кэша модуля. Однако, если в вашем проекте есть пакет с именем, идентичным одному из пакетов в разделе «Поставщик», возникает двусмысленность.

Комментарии:

1. Я понимаю, откуда возникает двусмысленность, однако в контексте, зависящем от модуля, не следует go просто пропускать папку поставщика?

2. Это не так. Вы все еще можете использовать внешние зависимости поставщика.

3. Я все еще не понимаю, почему при запуске go build -mod=mod нет такой же проблемы. Что -mod=mod меняется?

4. Хорошо, nvm, я нашел свой ответ в go help modules