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

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

Отmeme/cmd/meme:

import "../../../meme"

Это дает неоднозначную ошибку:

[email protected]:~/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

[email protected]:~/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme$ echo $GOPATH

/home/matt/gopath

Как я могу импортировать локально из родительского каталога?

 Matt Joiner22 мая 2012 г., 04:52
@ Соня, ты пробовал использовать инструмент go? Я добавлю больше деталей.
 Sonia21 мая 2012 г., 21:21
Я попробовал это несколькими способами и не увидел неоднозначную ошибку, о которой вы упомянули. Вы имеете в виду, что нашли формулировку неоднозначной или что текст сообщения включал слово неоднозначно. Два способа, которые я попробовал, были meme / cmd / meme в GOPATH, а затем вне GOPATH. В обоих случаях относительный путь импорта работал хорошо для меня. Можете ли вы рассказать подробнее о том, что у вас не работает?
 Matt Joiner22 мая 2012 г., 08:51
@ Соня: я добавила несколько примеров.
 Sonia22 мая 2012 г., 06:46
Да. Я предположил, что у вас есть пакет в меме и исполняемый файл в меме / cmd / меме. Для случая GOPATH, запустите или установите установленный исполняемый файл. Для случая вне GOPATH я скомпилировал мем-пакет с инструментом go go 6g и паком инструментов go. Тогда импорт в основной пакет должен был быть ../../meme, чтобы указать на .a, но в противном случае перейдите к инструменту 6g и инструменту 6l для создания рабочего исполняемого файла, который получил доступ к пакету.

Ответы на вопрос(3)

Edit: Относительные пути импорта не подходят для Go. Отсутствие документации свидетельствует о популярности относительных путей, и я не вижу причин для их использования. Рекомендованная Go организация кода работает довольно хорошо. Каждый пакет должен иметь уникальный путь импорта и быть импортированнымeverywhere используя тот же путь импорта.

Посмотрите, как пакет, какgithub.com/ha/doozerd/peer импортирует своих соседей, Это обычная практика среди проектов Go, и я видел это много раз. пакетcamlistore.org/pkg/auth (также наGitHub; написано одним из основных авторов го) импортаcamlistore.org/pkg/netutil по полному пути.

Даже если у вас есть команды и библиотеки в одном проекте, этот подход работает. В ваших оригинальных вопросах вы мудро спрашивали о лучших практиках. Я приложил все усилия, чтобы объяснить лучшие практики по этому вопросу.

Import paths can't be relative in 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.

Организуйте свой код вокруг этой идеи.

 10 янв. 2015 г., 05:00
Не проверял это, но сработало нормально: не загружайте ваш форк в отдельную директорию. Добавьте его в качестве удаленного к текущему git-репо в правильном каталоге.
 09 сент. 2013 г., 21:07
Относительные пути хороши для одного (критического IMO) варианта использования: работа с разветвленными хранилищами. Если вы разветвляете чье-либо репозиторий на github, вам придется обновить все операторы импорта, чтобы они ссылались на вашу копию, а затем помните, что не следует выдвигать эти восходящие потоки (или ожидать, что вышестоящие потоки исключат их при объединении). Просто становится неаккуратным.
 22 мая 2012 г., 09:40
@ MattJoiner Вы правы. Я не знал, что это возможно с помощью инструмента Go. Но в любом случае я не думаю, что мы должны их использовать. Нужно обновить мой ответ.
 07 янв. 2015 г., 22:34
Хотя я понимаю, что это «лучшая практика» Способ организации проекта Go, на практике это нарушает стандартный рабочий процесс для участия через github. например если я раскошелюсьgithub.com/ha/doozerd/peerКлонируй мою вилку (github.com/morphatic/doozerd/peer), внесите изменения в соседние файлы / папки, а затем попробуйте запустить тесты, мои изменения не видны, потому чтоimport заявления относятся к восходящему репо. Есть ли способ обойти это?
 Matt Joiner21 мая 2012 г., 20:46
Я полагаю, что они могут Мостафа, но это недокументировано.
Решение Вопроса

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

go get, just as you had it. (I ignored the error messages.) setting the import line in main.go back to "../../../meme", as you wanted to do. (commenting out a little bit of code containing an unused variable.) then in the meme/cmd/meme directory, either go run main.go or go build main.go worked.

Я был неправ в своем комментарии ранее, когда сказал, что go install works; Я должен был сказать, иди строить.

Ключ, однако, в том, чтоgo build один не работает; вы должны напечататьgo build main.go, Это связано с тем, что команда go не разрешает & quot; локальный импорт в нелокальных пакетах. & Quot; Вы правы, что спецификации здесь мало помогают. Он выкрикивает: «Интерпретация ImportPath зависит от реализации». Текущее поведение реализации было установлено сCL 5787055, который был впоследствиидолго обсуждался на орешках.

& Quot; Локальная & Quot; означает, что указано с относительным путем файловой системы. Очевидно, что относительный путь, начинающийся с .., является локальным, поэтому хитрость заключается в полученииgo команда для обработки main как локального пакета. Это, очевидно, не делает этого, когда вы печатаетеgo build, но делает, когда вы печатаетеgo build main.go.

Релятивный импорт поддерживается при ручном использовании компилятора, компоновщика, ... напрямую. «Перейти» (build) инструмент не поддерживает то же самое (как-то сравнимо, например, с Java).

 21 мая 2012 г., 22:56
Пока возможно. Пожалуйста, отметьте, что это нежелательное занятие.

Ваш ответ на вопрос