Jak zaimportować pakiety lokalne w go?

90

Jestem nowy i pracuję nad przykładowym kodem, który chcę zlokalizować.

W oryginalnym main.gooświadczeniu importowym było to:

 import (
    "log"
    "net/http"
    "github.com/foo/bar/myapp/common"
    "github.com/foo/bar/myapp/routers"
)

Teraz mam commoni routerspakuję/home/me/go/src/myapp

Więc przekonwertowałem instrukcję import na:

import (
    "log"
    "net/http"
    "./common"
    "./routers"
)

Ale kiedy uruchamiam go install myapp, otrzymuję te błędy:

can't load package: /home/me/go/src/myapp/main.go:7:3: local import "./common" in non-local package

Ponadto, kiedy używam commoni routerszamiast ./commoniw ./routersinstrukcji import, otrzymuję:

myapp/main.go:7:3: cannot find package "common" in any of:
    /usr/local/go/src/common (from $GOROOT)
    /home/me/go/src/common (from $GOPATH)
myapp/main.go:8:2: cannot find package "routers" in any of:
    /usr/local/go/src/routers (from $GOROOT)
    /home/me/go/src/routers (from $GOPATH)

Jak mogę to naprawić?

Karlom
źródło
5
Wszystkie importy są „lokalne”, niezależnie od ścieżki importu. Aby uzyskać szczegółowe wyjaśnienie, zobacz „Jak napisać kod Go” .
JimB
21
@JimB odkładając na bok debaty filozoficzne, interesuje mnie sposób rozwiązania wspomnianego powyżej problemu.
Karlom,
3
Nie próbuję formułować filozoficznych stwierdzeń, mówię dosłownie, że wszystkie importy mają miejsce w lokalnym systemie plików; nie ma żadnej różnicy, czy pochodzą one ze zdalnego repozytorium, czy nie. Nie próbuj używać ścieżek względnych (czasami działają, ale są odradzane) i przejdź przez dokument „Jak napisać kod Go”, a konkretnie przez sekcję „Organizacja kodu” .
JimB,

Odpowiedzi:

63

Cóż, odkryłem problem. Zasadniczo ścieżka początkowa Go do importu to$HOME/go/src

Musiałem więc tylko dodać myappprzed nazwami pakietów, czyli import powinien wyglądać następująco:

import (
    "log"
    "net/http"
    "myapp/common"
    "myapp/routers"
)
Karlom
źródło
3
używanie nazwy projektu jak myappjest złym pomysłem, na przykład jeśli zmienisz nazwę projektu, cały import się nie powiedzie
TomSawyer
7
Jaka jest alternatywa? Go nie zaleca używania importu względnego.
Sam Holmes
11
Oczywiście wszystkie operacje importowania zakończą się niepowodzeniem, jeśli zmienisz nazwę projektu. Nazwa projektu rzadko się zmienia.
Damien Roche
21
Cóż, od wersji go1.11 możesz korzystać z nowego systemu modułów. go mod init <module_name>a potem po prostu import "<module_name>/<pkg_name>".
krzyk
Jak możemy zaimportować github.com/dgrijalva/jwt-go do naszego pliku .go? Mój folder jwt-go znajduje się w src / github.com / dgrijalva
Manik Thakur
30

Jeśli używasz wersji Go 1.5 powyżej, możesz spróbować użyć funkcji sprzedawcy . Pozwala umieścić pakiet lokalny w folderze dostawcy i zaimportować go z krótszą ścieżką. W twoim przypadku możesz umieścić folder wspólny i routery w folderze dostawcy, tak aby tak było

myapp/
--vendor/
----common/
----routers/
------middleware/
--main.go

i zaimportuj go w ten sposób

import (
    "common"
    "routers"
    "routers/middleware"
)

To zadziała, ponieważ Go spróbuje wyszukać pakiet, zaczynając od katalogu dostawcy projektu (jeśli ma co najmniej jeden plik .go) zamiast $ GOPATH / src.

Do Twojej wiadomości: Możesz zrobić więcej z dostawcą, ponieważ ta funkcja umożliwia umieszczenie „całego kodu zależności” dla pakietu w katalogu własnego projektu, dzięki czemu zawsze będzie mógł uzyskać te same wersje zależności dla wszystkich kompilacji. To jest jak npm lub pip w Pythonie, ale musisz ręcznie skopiować swoje zależności do swojego projektu lub jeśli chcesz to ułatwić, spróbuj wyglądać na govendora Daniela Theophanesa

Aby dowiedzieć się więcej o tej funkcji, spróbuj poszukać tutaj

Zrozumienie i korzystanie z folderu dostawcy autorstwa Daniela Theophanesa

Zrozumienie zarządzania w Go Dependency przez Lucasa Fernandesa da Costa

Mam nadzieję, że Ty lub ktoś inny uzna to za pomocne

arimaulana
źródło
18

Ścieżki importu są względne w stosunku do zmiennych użytkownika $GOPATHi $GOROOTśrodowiska. Na przykład z następującymi elementami $GOPATH:

GOPATH=/home/me/go

Paczki znajdujące się w /home/me/go/src/lib/commoni /home/me/go/src/lib/routerssą importowane odpowiednio jako:

import (
    "lib/common"
    "lib/routers"
)
wlredeye
źródło
Tak, pierwszym przykładem był mój błąd.
wlredeye
Co masz na myśli mówiąc o ścieżce względnej, która nie jest obsługiwana przez narzędzia?
wlredeye
2
Nie możesz go installpakietów, które używają importu względnego.
JimB
Myślę, że to nieporozumienie. Mam na myśli w stosunku do GOPATH. Nie tylko względne, jak „../../mypackage”
wlredeye
Było to w odniesieniu do części, którą naprawiłeś w odniesieniu do importu względem bieżącego katalogu. Tak, wszystkie importy użytkowników odnoszą się do $GOPATH/src.
JimB
5

Pakiet lokalny jest denerwującym problemem w podróży.

W przypadku niektórych projektów w naszej firmie decydujemy się w ogóle nie używać pakietów pomocniczych.

  • $ glide install
  • $ go get
  • $ go install

Cała praca.

W przypadku niektórych projektów używamy pakietów podrzędnych i importujemy pakiety lokalne z pełną ścieżką:

import "xxxx.gitlab.xx/xxgroup/xxproject/xxsubpackage

Ale jeśli rozwidlimy ten projekt, wówczas podpakiety nadal odnoszą się do oryginalnego.

tangxinfa
źródło