web-dev-qa-db-fra.com

Importation relative depuis le répertoire parent

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?

41
Matt Joiner

Merci d'avoir ajouté à votre question. D'abord, une réponse, puis quelques explications. J'ai construit votre code par,

  1. allez chercher, comme vous l'aviez. (J'ai ignoré les messages d'erreur.)
  2. définition de la ligne d'importation dans main.go retour à "../../../meme", comme vous vouliez le faire.
  3. (commentant un peu de code contenant une variable inutilisée.)
  4. puis dans le répertoire meme/cmd/meme, soit 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.

17
Sonia

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/peerimporte 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.

48
Mostafa

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).

3
zzzz