Comment effectuer une importation relative depuis un répertoire parent?
De meme/cmd/meme
:
import "../../../meme"
Cela donne une erreur ambiguë:
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
Comment importer localement à partir d'un répertoire parent?
Merci d'avoir ajouté à votre question. D'abord, une réponse, puis quelques explications. J'ai construit votre code par,
main.go
retour à "../../../meme", comme vous vouliez le faire.go run main.go
ou go build main.go
travaillé.J'avais tort dans mon commentaire plus tôt quand j'ai dit que go install fonctionne; J'aurais dû dire go build.
Cependant, la clé est que go build
seul ne fonctionne pas; vous devez taper go build main.go
. Cela est dû au fait que la commande go n'autorise pas les "importations locales dans des packages non locaux". Vous avez raison, cette spécification est peu utile ici. Il se dit: "L'interprétation de ImportPath dépend de la mise en œuvre." Le comportement d'implémentation actuel a été défini avec CL 5787055 , qui a ensuite été longuement débatt sur Go-nut.
"Local" signifie indiqué par un chemin relatif du système de fichiers. De toute évidence, un chemin relatif commençant par .. est local, donc l'astuce consiste simplement à obtenir la commande go
pour traiter main comme un package local également. Apparemment, cela ne fonctionne pas lorsque vous tapez go build
, mais le fait lorsque vous tapez go build main.go
.
Edit: Les chemins d'importation relatifs ne sont pas la voie à suivre dans Go. Le manque de documentation montre quelque chose sur la popularité des chemins relatifs, et je ne vois pas de raison de les utiliser. L'organisation de code recommandée par Go fonctionne plutôt bien. Chaque paquet doit avoir un chemin d'importation unique et être importé partout en utilisant ce même chemin d'importation.
Découvrez comment un package comme github.com/ha/doozerd/peer
importe ses voisins . C'est une pratique courante parmi les projets Go et je l'ai vue à maintes reprises. Paquet camlistore.org/pkg/auth
(également sur GitHub ; écrit par l'un des principaux auteurs de Go) importe camlistore.org/pkg/netutil
par le chemin complet.
Même si vous avez à la fois des commandes et des bibliothèques dans le même projet, cette approche fonctionne. Dans vos questions originales, vous avez judicieusement demandé les meilleures pratiques. J'ai fait de mon mieux pour expliquer les meilleures pratiques à ce sujet.
Les chemins d'importation ne peuvent pas être relatifs dans Go. Je recommande de lire Comment écrire du code Go , la lecture essentielle sur l'organisation des projets Go. Voici un bref aperçu:
Créez un répertoire comme ~/go
pour votre développement Go. Alors dire:
$ export GOPATH=~/go
$ mkdir $GOPATH/{src,bin,pkg}
$GOPATH/src
contient le code source de tous vos packages Go, même ceux que vous téléchargez avec go get
. bin
et pkg
conservent la sortie des compilations. Les packages avec le nom du package main
sont des commandes et donnent des exécutables exécutables qui vont à $GOPATH/bin
. Les autres packages sont des bibliothèques et leurs fichiers objets compilés sont placés dans $GOPATH/pkg
.
Maintenant, si vous mettez votre code dans $GOPATH/src/matt/meme
, vous pouvez l'importer par import "matt/meme"
. Il est recommandé d'utiliser un préfixe pour les noms de vos packages et de laisser des noms de packages courts pour les bibliothèques standard. Voilà pourquoi j'ai utilisé $GOPATH/src/matt/meme
au lieu de $GOPATH/src/meme
.
Organisez votre code autour de cette idée.
Les importations relatives sont prises en charge lorsque vous utilisez manuellement le compilateur, l'éditeur de liens, ... directement. L'outil 'go' (build) ne prend pas en charge le même (en quelque sorte comparable à Java par exemple).