Go get не может найти локальные пакеты при использовании модулей
У меня проблемы с новой модульной системой, так как я хочу определить локальный модуль и импортировать его в основную программу. Локальный пакет находится в папке основной папки пакета/корня. Представьте себе следующую структуру проекта за пределами $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)
}
./model/person.go
package model
type Person struct {
name string
age int
}
В корневой папке я инициализировал модуль, вызывая
go mod init example.com/localModule
В model/
папке я затем инициализировал подмодуль, вызывая
go mod init example.com/localModule/model
Ошибка
В корневой папке вызывается вызов следующих команд.
$ 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
Сообщение об ошибке для go get отключено, я не ошибаюсь.
Я не планирую нажимать модуль на сервер и просто нужен способ ссылки на локальную model
пакета, поэтому я выбрал example.com/localModule/
и example.com/localModule/model
соответственно.
Я использую go1.11 darwin/amd64
на Macbook с MacOS 10.13.6.
Ответы
Ответ 1
У вас могут быть локальные "под" модули, как вы просите, добавив инструкцию require и соответствующий оператор replace с относительным пути к файлу в go.mod.
В "root"./go.mod:
module example.com/localModule
require example.com/localModule/model v0.0.0
replace example.com/localModule/model v0.0.0 => ./model
Ответ 2
Udated:
см. ответ Йостайна Стюхауга
Ответ 3
Причина, по которой вы получаете эту ошибку, заключается в том, что вы определили два модуля, которые не знают, как найти друг друга на локальном диске.
$ go build
main.go:4:8: unknown import path "example.com/localModule/model":
cannot find module providing package example.com/localModule/model
Хотя можно использовать директиву replace
чтобы один модуль мог найти другой модуль на диске, гораздо более распространенным и простым решением является:
- Иметь один файл
go.mod
в вашем хранилище, и - Поместите этот единственный файл
go.mod
в корень вашего хранилища.
Это очень простое решение, и оно означает, что ваши два пакета в репозитории смогут находить друг друга, что позволяет избежать сообщения об ошибке, о котором вы сообщили, а также избежать необходимости в директиве replace
здесь.
Расс Кокс прокомментировал в # 26664:
Для всех, кроме опытных пользователей, вы, вероятно, захотите принять обычное соглашение, что один репо = один модуль. Для долгосрочного развития вариантов хранения кода важно, чтобы хранилище могло содержать несколько модулей, но это почти наверняка не то, что вы хотите сделать по умолчанию.
Если вместо этого вы хотите, чтобы в одном репозитории было определено несколько модулей, есть немало нюансов о том, как это сделать правильно, и есть целый раздел вики-модулей по тому, как управлять сложностью, связанной с несколькими модулями в Единый репозиторий, включая этот совет:
Добавление модулей, удаление модулей и управление версиями модулей с несколькими модулями в одном репозитории требует значительного внимания и тщательности, поэтому почти всегда проще и проще управлять одномодульным репозиторием, чем несколькими модулями в существующем репозитории.
а также
Пожалуйста, внимательно прочитайте все часто задаваемые вопросы в этом подразделе, если вы планируете иметь несколько модулей в одном репозитории.