Относительный импорт из родительского каталога
Как сделать относительный импорт из родительского каталога?
От meme/cmd/meme
:
import "../../../meme"
Это дает неоднозначную ошибку:
matt@stanley:~/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme$ go get bitbucket.org/anacrolix/meme/cmd/meme
can't load package: /home/matt/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme/main.go:8:2: local import "../../../meme" in non-local package
matt@stanley:~/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme$ echo $GOPATH
/home/matt/gopath
Как я могу импортировать локально из родительского каталога?
3 ответа
Спасибо за добавление к вашему вопросу. Сначала ответ, потом какое-то объяснение. Я создал твой код,
- иди, так же, как у вас было. (Я проигнорировал сообщения об ошибках.)
- установка строки импорта в
main.go
вернуться к "../../../meme", как вы хотели сделать. - (комментируя немного кода, содержащего неиспользуемую переменную.)
- затем в каталоге meme / cmd / meme, либо
go run main.go
или жеgo build main.go
работал.
Я был неправ в своем комментарии ранее, когда сказал, что go install works; Я должен был сказать, иди строить.
Ключ, однако, в том, что go build
один не работает; вы должны напечатать go build main.go
, Это связано с тем, что команда go не разрешает "локальный импорт в нелокальных пакетах". Вы правы, что спецификации здесь мало помогают. Он выкрикивает: "Интерпретация ImportPath зависит от реализации". Текущее поведение реализации было установлено с помощью CL 5787055, который впоследствии подробно обсуждался на предметах.
"Локальный" означает относительный путь к файловой системе. Очевидно, что относительный путь, начинающийся с.., является локальным, поэтому хитрость заключается в получении go
команда для обработки main как локального пакета. Это, видимо, не делает этого, когда вы печатаете go build
, но делает, когда вы печатаете go build main.go
,
Изменить: Относительные пути импорта не путь в Go. Отсутствие документации свидетельствует о популярности относительных путей, и я не вижу причин для их использования. Рекомендованная Go организация кода работает довольно хорошо. Каждый пакет должен иметь уникальный путь импорта и импортироваться везде, используя один и тот же путь импорта.
Посмотрите, как пакет, как github.com/ha/doozerd/peer
импортирует своих соседей. Это обычная практика среди проектов Go, и я видел это много раз. пакет camlistore.org/pkg/auth
(также на GitHub; написано одним из основных авторов Go) camlistore.org/pkg/netutil
по полному пути.
Даже если у вас есть команды и библиотеки в одном проекте, этот подход работает. В ваших оригинальных вопросах вы мудро спрашивали о лучших практиках. Я приложил все усилия, чтобы объяснить лучшие практики по этому вопросу.
Пути импорта не могут быть относительными в Go. Я рекомендую прочитать " Как написать код Go", что необходимо для организации проектов Go. Вот краткий обзор:
Сделать каталог как ~/go
для вашего развития Go. Тогда скажи:
$ export GOPATH=~/go
$ mkdir $GOPATH/{src,bin,pkg}
$GOPATH/src
содержит исходный код для всех ваших пакетов Go, даже тех, которые вы скачали с go get
, bin
а также pkg
сохранить вывод компиляций. Пакеты с названием пакета main
являются командами и уступают исполняемым двоичным файлам, которые идут в $GOPATH/bin
, Другие пакеты являются библиотеками и их скомпилированные объектные файлы помещаются в $GOPATH/pkg
,
Теперь, если вы введете свой код в $GOPATH/src/matt/meme
Вы можете импортировать его по import "matt/meme"
, Рекомендуется использовать префикс для имен ваших пакетов и оставлять короткие имена для стандартных библиотек. Вот почему я использовал $GOPATH/src/matt/meme
вместо $GOPATH/src/meme
,
Организуйте свой код вокруг этой идеи.
Релятивный импорт поддерживается при ручном использовании компилятора, компоновщика, ... напрямую. Инструмент 'go' (build) не поддерживает то же самое (как-то сравнимо, например, с Java).
Возможно, это не ответ на исходный вопрос, но я пытался сделать это, когда мне это действительно не нужно, все, что мне нужно было сделать, это обновить
go.mod
временно с
replace
:
module github.com/pselle/foo
replace github.com/pselle/bar => /Users/pselle/Projects/bar
require (
github.com/pselle/bar v1.0.0
)
ссылка:https://thewebivore.com/using-replace-in-go-mod-to-point-to-your-local-module/