Mimo że mam GOPATH
ustawione prawidłowo, nadal nie mogę znaleźć własnych pakietów w trybie „go build” lub „go run”. Co ja robię źle?
$ echo $GOROOT
/usr/local/go
$ echo $GOPATH
/home/mitchell/go
$ cat ~/main.go
package main
import "foobar"
func main() { }
$ cat /home/mitchell/go/src/foobar.go
package foobar
$ go build main.go
main.go:3:8: import "foobar": cannot find package
$ go help gopath
Odpowiedzi:
Nie działa, ponieważ
foobar.go
plik źródłowy nie znajduje się w katalogu o nazwiefoobar
.go build
igo install
spróbuj dopasować katalogi, a nie pliki źródłowe.$GOPATH
na prawidłowy katalog, npexport GOPATH="$HOME/go"
foobar.go
do$GOPATH/src/foobar/foobar.go
i budowanie powinno działać dobrze.Dodatkowe zalecane kroki:
$GOPATH/bin
do swojego$PATH
:PATH="$GOPATH/bin:$PATH"
main.go
do podfolderu$GOPATH/src
np$GOPATH/src/test
go install test
powinien teraz utworzyć plik wykonywalny,$GOPATH/bin
który można wywołać, wpisując gotest
w terminalu.źródło
GOPATH=/usr/local/go-pkgs
, więc Go szuka/usr/local/go-pkgs/src/<package-name>
źródła, alego get
wstawia je/usr/local/go-pkgs/src/gopkg.in/<package-name>
. Dlaczego po instalacji powinienem ręcznie przenosić wszystkie moje pakiety? To po prostu głupie.go get
normalnie umieszcza pakiety w,$GOPATH/src/
więc jeśli zadzwoniszgo get domain.com/path/to/package
, skończy się w$GOPATH/src/domain.com/path/to/package
. Myślę, że próbujesz pobrać paczkę zgopkg.in
? Jeśli tak, jest to absolutnie zamierzone zachowanie i powinieneś po prostu zaimportować je z ich pełną nazwą; np.import "gopkg.in/yaml.v1"
jak również opisano w dok .Edit: ponieważ chodziło GOPATH patrz fasmat „s odpowiedź (upvoted)
Jak wspomniano w „ Jak mam znaleźć mój pakiet? ”, Musisz umieścić pakiet
xxx
w kataloguxxx
.Zobacz specyfikację języka Go :
package math
Organizacja Kodeksu wspomina:
(„obszar roboczy” to wpis ścieżki w Twoim
GOPATH
: ta zmienna może odnosić się do wielu ścieżek, aby Twój „src, bin, pkg
” był)(Oryginalna odpowiedź)
Powinieneś także ustawić
GOPATH
~ / go, a nieGOROOT
, jak pokazano w „ Jak napisać kod Go ”.To różni się od
GOROOT
:źródło
Chociaż zaakceptowana odpowiedź jest nadal poprawna, jeśli chodzi o konieczność dopasowania katalogów do nazw pakietów, naprawdę musisz przejść do używania modułów Go zamiast używania GOPATH. Nowi użytkownicy, którzy napotkają ten problem, mogą być zdezorientowani wzmiankami o używaniu GOPATH (tak jak ja), które są teraz nieaktualne. Postaram się więc wyjaśnić ten problem i udzielić wskazówek związanych z zapobieganiem temu problemowi podczas korzystania z modułów Go.
Jeśli znasz już moduły Go i masz ten problem, przejdź do moich bardziej szczegółowych sekcji poniżej, które obejmują niektóre konwencje Go, które łatwo przeoczyć lub zapomnieć.
Ten przewodnik uczy o modułach Go: https://golang.org/doc/code.html
Organizacja projektu za pomocą modułów Go
Po migracji do modułów Go, jak wspomniano w tym artykule, zorganizuj kod projektu zgodnie z opisem:
Możesz zainicjować swój moduł w następujący sposób:
$ go mod init github.com/mitchell/foo-app
Twój kod nie musi znajdować się na github.com, aby mógł zostać zbudowany. Jednak najlepszą praktyką jest uporządkowanie modułów w taki sposób, jakby były ostatecznie publikowane.
Zrozumienie, co się dzieje podczas próby odebrania paczki
Jest tutaj świetny artykuł, który mówi o tym, co się dzieje, gdy próbujesz uzyskać pakiet lub moduł: https://medium.com/rungo/anatomy-of-modules-in-go-c8274d215c16 Omawia, gdzie pakiet jest przechowywany i będzie pomoże Ci zrozumieć, dlaczego możesz otrzymać ten błąd, jeśli już używasz modułów Go.
Upewnij się, że zaimportowana funkcja została wyeksportowana
Zwróć uwagę, że jeśli masz problemy z dostępem do funkcji z innego pliku, musisz upewnić się, że funkcja została wyeksportowana. Jak opisano w pierwszym linku, który podałem, funkcja musi zaczynać się od dużej litery, aby można ją było wyeksportować i udostępnić do zaimportowania do innych pakietów.
Nazwy katalogów
Kolejnym krytycznym szczegółem (jak wspomniano w zaakceptowanej odpowiedzi) jest to, że nazwy katalogów definiują nazwy twoich pakietów. (Nazwy twoich pakietów muszą być zgodne z nazwami ich katalogów.) Możesz zobaczyć przykłady tutaj: https://medium.com/rungo/everything-you-need-to-know-about-packages-in-go-b8bac62b74cc With To powiedziawszy, plik zawierający twoją
main
metodę (tj. punkt wejścia twojej aplikacji) jest jakby zwolniony z tego wymogu.Na przykład miałem problemy z importem, gdy korzystałem z takiej struktury:
/my-app ├── go.mod ├── /src ├── main.go └── /utils └── utils.go
Nie udało mi się zaimportować kodu
utils
do mojegomain
pakietu.Jednak po umieszczeniu
main.go
we własnym podkatalogu, jak pokazano poniżej, mój import działał dobrze:/my-app ├── go.mod ├── /src ├── /app | └── main.go └── /utils └── utils.go
W tym przykładzie mój plik go.mod wygląda następująco:
module git.mydomain.com/path/to/repo/my-app go 1.14
Kiedy zapisałem main.go po dodaniu odwołania do
utils.MyFunction()
, moje IDE automatycznie pobierało odwołanie do mojego pakietu w następujący sposób:import "git.mydomain.com/path/to/repo/my-app/src/my-app"
(Używam VS Code z rozszerzeniem Golang).
Zwróć uwagę, że ścieżka importu zawierała podkatalog do pakietu.
Radzenie sobie z prywatnym repo
Jeśli kod jest częścią prywatnego repozytorium, musisz uruchomić polecenie git, aby umożliwić dostęp. W przeciwnym razie możesz napotkać inne błędy Ten artykuł wspomina, jak to zrobić w przypadku prywatnych repozytoriów Github, BitBucket i GitLab: https://medium.com/cloud-native-the-gathering/go-modules-with-private-git- repositories-dfe795068db4 Ten problem jest również omawiany tutaj: Jaki jest właściwy sposób na „zdobycie” prywatnego repozytorium?
źródło
TL; DR: konwencje Follow Go! (lekcja na własnej skórze), sprawdź starsze wersje go i usuń je. Zainstaluj najnowsze.
Dla mnie rozwiązanie było inne. Pracowałem na współdzielonym serwerze Linux i po
GOPATH
kilkukrotnej weryfikacji moich i innych zmiennych środowiskowych nadal nie działał. Napotkałem kilka błędów, w tym „Nie można znaleźć pakietu” i „Nierozpoznana ścieżka importu”. Po próbie ponownej instalacji tego rozwiązania zgodnie z instrukcjami na golang.org (łącznie z częścią odinstalowującą ) nadal występowały problemy.Zajęło mi trochę czasu, zanim zdałem sobie sprawę, że wciąż istnieje stara wersja, która nie została odinstalowana (
go version
a potem uruchomionawhich go
... DAHH), co doprowadziło mnie do tego pytania i ostatecznie rozwiązane.źródło
W ostatnich wersjach go, począwszy od 1.14, musimy to zrobić
go mod vendor
przed budowaniem lub uruchomieniem, ponieważ domyślnie go dołącza-mod=vendor
do poleceń go. Więc po wykonaniu tej czynnościgo mod vendor
, jeśli spróbujemy budować, nie napotkamy tego problemu.źródło
Rozwiązałem ten problem, wyłączając go env GO111MODULE
go env -w GO111MODULE=off
źródło
Czy próbowałeś dodać katalog bezwzględny go do swojej „ścieżki”?
export PATH=$PATH:/directory/to/go/
źródło