Относительный импорт из родительского каталога

Как сделать относительный импорт из родительского каталога?

От 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 ответа

Решение

Спасибо за добавление к вашему вопросу. Сначала ответ, потом какое-то объяснение. Я создал твой код,

  1. иди, так же, как у вас было. (Я проигнорировал сообщения об ошибках.)
  2. установка строки импорта в main.go вернуться к "../../../meme", как вы хотели сделать.
  3. (комментируя немного кода, содержащего неиспользуемую переменную.)
  4. затем в каталоге 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/

Другие вопросы по тегам