Wie importiere ich lokale Pakete in go?

90

Ich bin neu darin, an einem Beispielcode zu arbeiten, den ich lokalisieren möchte.

In der ursprünglichen main.goImportanweisung war es:

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

Jetzt habe ich commonund routerspacke ein/home/me/go/src/myapp

Also habe ich die import-Anweisung konvertiert in:

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

Aber wenn ich renne, go install myappbekomme ich folgende Fehler:

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

Wenn ich commonund routersanstelle von ./commonund ./routersin der import-Anweisung verwende, erhalte ich außerdem Folgendes:

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)

Wie kann ich das beheben?

Karlom
quelle
5
Alle Importe sind "lokal", unabhängig vom Importpfad. Eine ausführliche Erklärung finden Sie unter "Schreiben von Go-Code" .
JimB
21
@JimB Abgesehen von den philosophischen Debatten geht es mir darum, wie das oben erwähnte Problem gelöst werden kann.
Karlom
3
Ich versuche nicht, eine philosophische Aussage zu machen, ich sage buchstäblich, dass alle Importe in Ihr lokales Dateisystem erfolgen. Es gibt nie einen Unterschied, ob sie aus einem Remote-Repo stammen oder nicht. Versuchen Sie nicht, relative Pfade zu verwenden (diese funktionieren manchmal, werden jedoch nicht empfohlen), und lesen Sie das Dokument "Schreiben von Go-Code", insbesondere den Abschnitt "Code-Organisation" .
JimB

Antworten:

63

Nun, ich habe das Problem herausgefunden. Grundsätzlich ist Startpfad für den Import$HOME/go/src

Also musste ich nur myappvor den Paketnamen hinzufügen , das heißt, der Import sollte sein:

import (
    "log"
    "net/http"
    "myapp/common"
    "myapp/routers"
)
Karlom
quelle
3
Die Verwendung eines Projektnamens wie myappist eine schlechte Idee. Wenn Sie beispielsweise den Projektnamen ändern,
schlägt der
7
Was ist die Alternative? Go empfiehlt nicht, relative Importe zu verwenden.
Sam Holmes
11
Natürlich schlagen alle Importe fehl, wenn Sie den Projektnamen ändern. Der Projektname ändert sich selten.
Damien Roche
21
Ab go1.11 können Sie das neue Modulsystem verwenden. go mod init <module_name>und dann einfach import "<module_name>/<pkg_name>".
Schrei
Wie können wir github.com/dgrijalva/jwt-go in unsere .go-Datei importieren? Mein jwt-go-Ordner befindet sich in src / github.com / dgrijalva
Manik Thakur
30

Wenn Sie oben Go 1.5 verwenden, können Sie versuchen, die Vendoring- Funktion zu verwenden. Sie können Ihr lokales Paket im Ordner des Anbieters ablegen und mit einem kürzeren Pfad importieren. In Ihrem Fall können Sie Ihren Common- und Router- Ordner in den Vendor- Ordner legen, so wie es wäre

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

und importiere es so

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

Dies funktioniert, da Go versucht, Ihr Paket ab dem Herstellerverzeichnis Ihres Projekts (sofern mindestens eine .go-Datei vorhanden ist) anstelle von $ GOPATH / src zu suchen.

Zu Ihrer Information: Mit dem Anbieter können Sie mehr tun, da Sie mit dieser Funktion "den gesamten Code Ihrer Abhängigkeit" für ein Paket in das Verzeichnis Ihres eigenen Projekts einfügen können, sodass für alle Builds immer die gleichen Abhängigkeitsversionen abgerufen werden können. Es ist wie npm oder pip in Python, aber Sie müssen Ihre Abhängigkeiten manuell in Ihr Projekt kopieren, oder wenn Sie es einfach machen möchten, versuchen Sie, einen Gouverneur von Daniel Theophanes zu suchen

Weitere Informationen zu dieser Funktion finden Sie hier

Vendor Folder verstehen und verwenden von Daniel Theophanes

Grundlegendes zum Go-Abhängigkeitsmanagement von Lucas Fernandes da Costa

Ich hoffe, Sie oder jemand anderes finden es hilfreich

Arimaulana
quelle
18

Importpfade sind relativ zu Ihren $GOPATHund $GOROOTUmgebungsvariablen. Zum Beispiel mit folgendem $GOPATH:

GOPATH=/home/me/go

Pakete in /home/me/go/src/lib/commonund /home/me/go/src/lib/routerswerden jeweils importiert als:

import (
    "lib/common"
    "lib/routers"
)
wlredeye
quelle
Ja, das erste Beispiel war mein Fehler.
wlredeye
Was meinen Sie mit einem relativen Pfad, der vom Werkzeug nicht unterstützt wird?
wlredeye
2
Sie können keine go installPakete verwenden, die relative Importe verwenden.
JimB
Ich denke, es ist ein Missverständnis hier. Ich meine relativ zu GOPATH. Nicht nur relativ wie "../../mypackage"
wlredeye
Dies bezog sich auf den Teil, den Sie beim Importieren relativ zum aktuellen Verzeichnis behoben haben. Ja, alle Benutzerimporte beziehen sich auf $GOPATH/src.
JimB
5

Lokales Paket ist ein nerviges Problem in go.

Für einige Projekte in unserem Unternehmen entscheiden wir uns, überhaupt keine Unterpakete zu verwenden.

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

Alle Arbeit.

Für einige Projekte verwenden wir Unterpakete und importieren lokale Pakete mit vollständigem Pfad:

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

Wenn wir dieses Projekt jedoch aufteilen, verweisen die Unterpakete immer noch auf das Original.

Tangxinfa
quelle