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ć?


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

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


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

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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.