Zugriff auf lokale Pakete innerhalb eines go-Moduls (go 1.11)

79

Ich probiere das neue Modulsystem von Go aus und habe Probleme beim Zugriff auf lokale Pakete. Das folgende Projekt befindet sich in einem Ordner auf meinem Desktop außerhalb meines Gopathen.

Meine Projektstruktur sieht aus wie:

/
  - /platform
      - platform.go
  - main.go
  - go.mod

// platform.go
package platform

import "fmt"

func Print() {
    fmt.Println("Hi")
}

// main.go
package main

import "platform"

func main() {
    platform.Print()
}

go build main.go sagt mir

cannot find module for path platform
David Alsh
quelle
2
Hallo David, wenn du glaubst, dass meine Antwort deine Frage beantwortet, kannst du sie als Antwort markieren. Vielen Dank!
Halil Kaskavalci
Maven Golang Plugin Da 2.3.3 auch die Arbeit mit lokalen Modulen ermöglicht (es fügt automatisch lokale Pfade während des Builds hinzu), können Sie sich ein Beispiel ansehen. github.com/raydac/mvn-golang/tree/master/mvn-golang- Beispiele /…
Igor Maznitsa

Antworten:

51

Ich würde Ihnen dringend empfehlen, die Toolchain go zu verwenden, mit der diese Probleme sofort behoben werden können. Visual Studio Code mit dem vscode-go Plugin ist wirklich nützlich.

Das Problem hierbei ist, dass Go relative Pfade in Bezug auf Ihre $GOPATH/srcoder modulein import-Anweisung benötigt. Je nachdem, wo Sie sich in Ihrem befinden GOPATH, sollte der Importpfad dies auch enthalten. In diesem Fall muss die import-Anweisung den Pfad des go-Moduls enthaltengo.mod

GOPATH

Angenommen, Ihr Projekt befindet sich hier:

$GOPATH/src/github.com/myuser/myproject

Ihr Importpfad sollte sein:

import "github.com/myuser/myproject/platform"

VGO

Angenommen, Ihre go.mod-Datei lautet:

module example.com/myuser/myproject

Ihr Importpfad sollte sein:

import "example.com/myuser/myproject/platform"
Halil Kaskavalci
quelle
Dies war ein Knaller - im Fall von Go-Modulen - ich muss dem Muster von vgo folgen, wobei ich den Pfad der import-Anweisung mit dem Namen des Moduls beginne. Vielen Dank!
David Alsh
12
Warten Sie, ich bin verwirrt. Wenn sich mein Modul nur irgendwo in meinem Dateisystem befindet, wie findet es das Modulsystem?
Narfanator
1
Wenn Sie sich in einem Modul befinden, werden Pakete im selben Modul unter Verwendung des Paketimportpfads und des Speicherorts der go.modDatei auf der Festplatte gefunden, sofern die Importpfade vollständige Importpfade sind, die mit dem Modulnamen beginnen (z. B. import "github.com/my/module/pkg"`). Wenn Sie Pakete in anderen Modulen suchen möchten, die sich an anderer Stelle auf Ihrer Festplatte befinden, kommt hier eine Ersetzungsanweisung ins
Spiel
5
Warum verwenden alle weiterhin URL-Formate? Die Frage war sehr klar: localmodule / localmodule.go das war's. Warum gibt es hier Githubs und example.com?
Holms
@holms die Antwort und der Kommentar über Ihnen erklären es, aber um zu verdeutlichen, hat die Sprache keinen Mechanismus, um interne Pakete zu finden, nur das go-Tool. Das Go-Tool hängt entweder von GOPATH oder der Modulkonfiguration (go.mod) ab. Sie verwenden im Wesentlichen die Funktion go tools, um Ihre lokalen Pakete wie jede andere Art von Paket zu behandeln . Siehe auch einige der anderen Antworten auf diese Frage.
user4893106
105

Lassen Sie mich dies zunächst modulesals Sammlungen von definieren packages. In Go 11 verwende ich Go-Module wie die folgenden:

Wenn sich beide Pakete im selben Projekt befinden, können Sie einfach Folgendes tun: In go.mod:

module github.com/userName/moduleName

und in deinem main.go

import "github.com/userName/moduleName/platform"

Wenn es sich jedoch um separate Module handelt, dh um unterschiedliche physische Pfade, und Sie dennoch lokal importieren möchten, packagesohne dies beispielsweise remote in Github zu veröffentlichen, können Sie dies mithilfe der replaceDirektive erreichen.

Angesichts des Modulnamens ist github.com/otherModuleund platform, wie Sie es genannt haben, das einzige Paket darin. Fügen Sie in Ihrem Hauptmodul go.moddie folgenden Zeilen hinzu:

module github.com/userName/mainModule

require "github.com/userName/otherModule" v0.0.0
replace "github.com/userName/otherModule" v0.0.0 => "local physical path to the otherModule"

Hinweis: Der Pfad sollte auf das Stammverzeichnis des Moduls verweisen und kann absolut oder relativ sein.

Im Inneren main.go, um ein bestimmtes Paket wie platformvon zu importieren otherModule:

import "github.com/userName/otherModule/platform"

Hier ist eine sanfte Einführung in Golang-Module

Muhammad Soliman
quelle
3
OMG diese Antwort hat mir sehr geholfen. Danke :)
Adis Azhar
2
Ich habe eine go.mod verwendet, die nur die Direktive replace enthält. Die Direktive require war nicht erforderlich, um das Projekt zu erstellen.
mh-cbon