Sebbene la risposta accettata sia ancora corretta sulla necessità di abbinare le directory con i nomi dei pacchetti, è necessario migrare all'utilizzo dei moduli Go invece di utilizzare GOPATH. I nuovi utenti che riscontrano questo problema potrebbero essere confusi riguardo alle menzioni dell'uso di GOPATH (come lo ero io), che ora sono obsolete. Quindi, proverò a risolvere questo problema e fornirò una guida per prevenire questo problema quando si utilizzano i moduli Go.
Se hai già familiarità con i moduli Go e riscontri questo problema, passa alle mie sezioni più specifiche di seguito che trattano alcune delle convenzioni Go che sono facili da ignorare o dimenticare.
Questa guida spiega i moduli Go: https://golang.org/doc/code.html
Organizzazione del progetto con moduli Go
Una volta eseguita la migrazione ai moduli Go, come menzionato in quell'articolo, organizza il codice del progetto come descritto:
Un repository contiene uno o più moduli. Un modulo è una raccolta di pacchetti Go correlati che vengono rilasciati insieme. Un repository Go contiene in genere un solo modulo, situato nella radice del repository. Un file chiamato go.mod lì dichiara il percorso del modulo: il prefisso del percorso di importazione per tutti i pacchetti all'interno del modulo. Il modulo contiene i pacchetti nella directory contenente il suo file go.mod e le sue sottodirectory, fino alla successiva sottodirectory contenente un altro file go.mod (se presente).
Il percorso di ogni modulo non serve solo come prefisso del percorso di importazione per i suoi pacchetti, ma indica anche dove dovrebbe essere il comando go per scaricarlo. Ad esempio, per scaricare il modulo golang.org/x/tools, il comando go dovrebbe consultare il repository indicato da https://golang.org/x/tools (descritto di più qui).
Un percorso di importazione è una stringa utilizzata per importare un pacchetto. Il percorso di importazione di un pacchetto è il percorso del suo modulo unito alla sua sottodirectory all'interno del modulo. Ad esempio, il modulo github.com/google/go-cmp contiene un pacchetto nella directory cmp /. Il percorso di importazione di quel pacchetto è github.com/google/go-cmp/cmp. I pacchetti nella libreria standard non hanno un prefisso di percorso del modulo.
Puoi inizializzare il tuo modulo in questo modo:
$ go mod init github.com/mitchell/foo-app
Il codice non deve trovarsi su github.com per poter essere compilato. Tuttavia, è consigliabile strutturare i moduli come se alla fine saranno pubblicati.
Capire cosa succede quando si cerca di ottenere un pacchetto
C'è un ottimo articolo qui che parla di cosa succede quando si tenta di ottenere un pacchetto o un modulo: https://medium.com/rungo/anatomy-of-modules-in-go-c8274d215c16
Discute dove è archiviato il pacchetto e lo farà aiutarti a capire perché potresti ricevere questo errore se stai già utilizzando i moduli Go.
Assicurarsi che la funzione importata sia stata esportata
Nota che se hai problemi ad accedere a una funzione da un altro file, devi assicurarti di aver esportato la tua funzione. Come descritto nel primo link che ho fornito, una funzione deve iniziare con una lettera maiuscola per essere esportata e resa disponibile per l'importazione in altri pacchetti.
Nomi delle directory
Un altro dettaglio critico (come menzionato nella risposta accettata) è che i nomi delle directory sono ciò che definisce i nomi dei pacchetti. (I nomi dei pacchetti devono corrispondere ai nomi delle loro directory.) Puoi vedere esempi di questo qui: https://medium.com/rungo/everything-you-need-to-know-about-packages-in-go-b8bac62b74cc
With ciò detto, il file contenente il main
metodo (ovvero il punto di ingresso dell'applicazione) è in qualche modo esente da questo requisito.
Ad esempio, ho avuto problemi con le mie importazioni durante l'utilizzo di una struttura come questa:
/my-app
├── go.mod
├── /src
├── main.go
└── /utils
└── utils.go
Non sono riuscito a importare il codice nel utils
mio main
pacchetto.
Tuttavia, una volta inserito main.go
nella propria sottodirectory, come mostrato di seguito, le mie importazioni hanno funzionato perfettamente:
/my-app
├── go.mod
├── /src
├── /app
| └── main.go
└── /utils
└── utils.go
In questo esempio, il mio file go.mod è simile al seguente:
module git.mydomain.com/path/to/repo/my-app
go 1.14
Quando ho salvato main.go dopo aver aggiunto un riferimento a utils.MyFunction()
, il mio IDE ha inserito automaticamente il riferimento al mio pacchetto in questo modo:
import "git.mydomain.com/path/to/repo/my-app/src/my-app"
(Sto usando VS Code con l'estensione Golang.)
Si noti che il percorso di importazione includeva la sottodirectory del pacchetto.
Trattare con un repository privato
Se il codice fa parte di un repository privato, è necessario eseguire un comando git per abilitare l'accesso. Altrimenti, puoi riscontrare altri errori Questo articolo menziona come farlo per i repository Github, BitBucket e GitLab privati: https://medium.com/cloud-native-the-gathering/go-modules-with-private-git- repository-dfe795068db4
Questo problema è anche discusso qui: qual è il modo corretto di "andare a prendere" un repository privato?