Bien que la réponse acceptée soit toujours correcte en ce qui concerne le besoin de faire correspondre les répertoires avec les noms des packages, vous devez vraiment migrer vers l'utilisation des modules Go au lieu d'utiliser GOPATH. Les nouveaux utilisateurs qui rencontrent ce problème peuvent être confus au sujet des mentions de l'utilisation de GOPATH (comme je l'étais), qui sont maintenant obsolètes. Donc, je vais essayer de clarifier ce problème et de fournir des conseils associés pour éviter cette situation lors de l'utilisation des modules Go.
Si vous êtes déjà familiarisé avec les modules Go et que vous rencontrez ce problème, passez directement à mes sections plus spécifiques ci-dessous qui couvrent certaines des conventions Go faciles à négliger ou à oublier.
Ce guide explique les modules Go : https://golang.org/doc/code.html
Organisation du projet avec les modules Go
Une fois que vous migrez vers les modules Go, comme mentionné dans cet article, organisez le code du projet comme décrit :
Un dépôt contient un ou plusieurs modules. Un module est une collection de packages Go liés qui sont publiés ensemble. Un dépôt Go contient généralement un seul module, situé à la racine du dépôt. Un fichier nommé go.mod déclare le chemin du module: le préfixe du chemin d'importation pour tous les packages dans le module. Le module contient les packages dans le répertoire contenant son fichier go.mod ainsi que des sous-répertoires de ce répertoire, jusqu'au prochain sous-répertoire contenant un autre fichier go.mod (le cas échéant).
Le chemin de chaque module sert non seulement de préfixe du chemin d'importation pour ses packages, mais indique également où la commande go doit chercher pour le télécharger. Par exemple, pour télécharger le module golang.org/x/tools, la commande go consulterait le dépôt indiqué par https://golang.org/x/tools (décrit plus en détail ici).
Un chemin d'importation est une chaîne utilisée pour importer un package. Le chemin d'importation d'un package est son chemin de module joint à son sous-répertoire dans le module. Par exemple, le module github.com/google/go-cmp contient un package dans le répertoire cmp/. Le chemin d'importation de ce package est github.com/google/go-cmp/cmp. Les packages de la bibliothèque standard n'ont pas de préfixe de chemin de module.
Vous pouvez initialiser votre module de cette manière :
$ go mod init github.com/mitchell/foo-app
Votre code n'a pas besoin d'être situé sur github.com pour être compilé. Cependant, il est préférable de structurer vos modules comme s'ils devaient finalement être publiés.
Comprendre ce qui se passe lors de la tentative d'obtention d'un package
Un excellent article ici parle de ce qui se passe lorsque vous essayez d'obtenir un package ou un module : https://medium.com/rungo/anatomy-of-modules-in-go-c8274d215c16 Il discute de l'endroit où le package est stocké et vous aidera à comprendre pourquoi vous pourriez rencontrer cette erreur si vous utilisez déjà des modules Go.
Assurez-vous que la fonction importée a été exportée
Remarquez que si vous avez des difficultés à accéder à une fonction d'un autre fichier, vous devez vous assurer d'avoir exporté votre fonction. Comme décrit dans le premier lien que j'ai fourni, une fonction doit commencer par une lettre majuscule pour être exportée et rendue disponible pour l'importation dans d'autres packages.
Noms de répertoires
Un autre détail crucial (comme mentionné dans la réponse acceptée) est que les noms des répertoires définissent les noms de vos packages. (Vos noms de package doivent correspondre à ceux de leurs répertoires.) Vous pouvez voir des exemples de cela ici : https://medium.com/rungo/everything-you-need-to-know-about-packages-in-go-b8bac62b74cc Cela dit, le fichier contenant votre méthode main
(c'est-à-dire le point d'entrée de votre application) est en quelque sorte exempt de cette exigence.
Par exemple, j'avais des problèmes avec mes imports lorsque j'utilisais une structure comme celle-ci :
/mon-app
go.mod
/src
main.go
/utils
utils.go
Je ne pouvais pas importer le code dans utils
dans mon package main
.
Cependant, une fois que j'ai mis main.go
dans son propre sous-répertoire, comme indiqué ci-dessous, mes imports ont fonctionné parfaitement :
/mon-app
go.mod
/src
/app
| main.go
/utils
utils.go
Dans cet exemple, mon fichier go.mod ressemble à ceci :
module git.mydomain.com/path/to/repo/mon-app
go 1.14
Lorsque j'ai enregistré main.go après avoir ajouté une référence à utils.MyFunction()
, mon IDE a automatiquement inclus la référence à mon package de cette manière :
import "git.mydomain.com/chemin/vers/repo/mon-app/src/mon-app"
(J'utilise VS Code avec l'extension Golang.)
Remarquez que le chemin d'importation incluait le sous-répertoire du package.
Gérer un référentiel privé
Si le code fait partie d'un référentiel privé, vous devez exécuter une commande git pour activer l'accès. Sinon, vous pouvez rencontrer d'autres erreurs. Cet article mentionne comment faire cela pour des référentiels privés Github, BitBucket et GitLab : https://medium.com/cloud-native-the-gathering/go-modules-with-private-git-repositories-dfe795068db4 Ce problème est également discuté ici : Quelle est la bonne manière de "go get" un référentiel privé ?
2 votes
Je rencontre le même problème lorsque je vais chercher github.com/adonovan/gopl.io/tree/master/ch1/helloworld La raison en est qu'il n'y a pas de fichier nommé helloworld.go. go get fonctionne en faisant correspondre le nom du package et le nom du fichier.
0 votes
Il se peut également que vous ayez besoin de mettre à jour Go. J'ai rencontré un problème similaire où j'avais du code existant utilisant go.mod pour définir un module. Sur une machine de test, j'avais téléchargé le code et j'essayais de le compiler mais Go me donnait toutes sortes d'erreurs liées à GOPATH et l'incapacité de trouver des modules. C'était la version Go 1.7. Dès que j'ai mis à jour Go, tout a fonctionné sans problème.
0 votes
Tapez ceci dans le terminal pour une explication à jour
$ go help gopath