So verwenden Sie benutzerdefinierte Pakete

177

Ich versuche, ein benutzerdefiniertes Paket in Go zu erstellen und zu verwenden. Es ist wahrscheinlich etwas sehr Offensichtliches, aber ich kann nicht viele Informationen darüber finden. Grundsätzlich habe ich diese beiden Dateien im selben Ordner:

mylib.go

package mylib

type SomeType struct {

}

main.go

package main

import (
    "mylib"
)

func main() {

}

Wenn ich es versuche go run main.go, erhalte ich folgende Fehlermeldung:

main.go:4:2: import "mylib": cannot find package

Ich habe versucht, go build mylib.gozuerst auszuführen, aber es scheint nichts zu tun (keine Datei generiert, keine Fehlermeldung). Also eine Idee, wie ich das machen könnte?

Laurent
quelle
Ich habe keine GOPATH-Variable gesetzt, nur GOROOT.
Laurent
1
Führen Sie go installdas Verzeichnis mylibzuerst aus und versuchen Sie es erneut.
Joe
1
Siehe auch diesen Thread .
Kostix
@ Joe, es kann immer noch nicht funktionieren, wenn "go install" im Inneren ausgeführt wird
hunter_tech

Antworten:

174

Lesen und verstehen Sie zunächst das Dokument "So schreiben Sie Go-Code" .

Die tatsächliche Antwort hängt von der Art Ihres "benutzerdefinierten Pakets" ab.

Wenn es von allgemeinem Nutzen sein soll, sollten Sie das sogenannte "Github-Code-Layout" verwenden . Grundsätzlich machen Sie Ihre Bibliothek zu einem separaten go getTabellenprojekt.

Wenn Ihre Bibliothek für den internen Gebrauch bestimmt ist, können Sie folgendermaßen vorgehen:

  1. Platzieren Sie das Verzeichnis mit den Bibliotheksdateien unter dem Verzeichnis Ihres Projekts.
  2. Verweisen Sie im Rest Ihres Projekts auf die Bibliothek, indem Sie ihren Pfad relativ zum Stammverzeichnis Ihres Arbeitsbereichs verwenden, der das Projekt enthält.

Demonstrieren:

src/
  myproject/
    mylib/
      mylib.go
      ...
    main.go

Jetzt, in der obersten Ebene main.go, könnten Sie import "myproject/mylib"und es würde OK funktionieren.

kostix
quelle
1
Wie kann ich mylib importieren, wenn ich unter src / ein neues Projekt (myproject2) erstelle?
Kiril
2
@Kiril, du meinst, wie importierst du mylibin den Code von myproject2? Dann lautet die Antwort "mithilfe von import "myproject/mylib"- die Idee ist, dass Go nach importierten Pfaden in jedem Verzeichnis sucht, das es aus der GOPATHUmgebungsvariablen extrahiert (sie werden als" Arbeitsbereiche "bezeichnet), aber diese Suche ist (zum Glück) nicht rekursiv, also sind solche Pfade effektiv an ihren jeweiligen Arbeitsplätzen "verankert".
kostix
4
Ein weiteres Muss: "Paketnamen" .
Kostix
1
@MatthiasSommer, normalerweise - indem Sie diese Mylib in ein gemeinsames Paket extrahieren, das jeder Microservice verwendet. Wie genau "Verwendungen" definiert sind, hängt von Ihrem bevorzugten Workflow ab. In der Unternehmensentwicklung wird normalerweise Vendoring verwendet. Bei den jüngsten go modEntwicklungen ist jedoch möglicherweise ein Modul die Antwort (und go modunterstützt auch das Vendoring von Modulen).
Kostix
1
@LeiYang, "das zu importierende Paket" ist ein Verzeichnis mit einer oder mehreren Go-Quelldateien. Was das Erstellen eines Pakets in eine .lib-Datei und das anschließende Importieren der lib-Datei betrifft, hängt die Antwort davon ab, wonach Sie wirklich fragen wollten. Wenn Sie sich mit der Kompilierungsgeschwindigkeit befassen, befürchten Sie nicht: Die Go-Toolchain-Caches Alle Build-Ergebnisse auf Paketbasis. Wenn Sie stattdessen fragen
möchten
67

Für diese Art von Ordnerstruktur:

main.go
mylib/
  mylib.go

Der einfachste Weg ist, dies zu verwenden:

import (
    "./mylib"
)
Laurent
quelle
1
Dies funktioniert in neueren Versionen von go nicht mehr, da das Paket nicht gefunden wird. Der korrekte Import wäre foo/mylib(vorausgesetzt, der Ordner mit main.go ist foo).
Nemo
6
@nemo, mit der neuesten Version von go verwende ich immer "./mylib" und es funktioniert.
Laurent
3
Mit go 1.2 stimme ich @ this.lau_
canadadry
8
Seien Sie sich bewusst, dass dies go installPause macht . Wenn Sie ein eigenständiges Projekt go builderstellen, das heruntergeladen und ausgeführt werden soll , ist dies in Ordnung. Ich würde jedoch das oben erwähnte "Github-Code-Layout" verwenden (auch wenn es sich nicht um Bitbucket oder ähnliches handelt), wenn Sie volle go installUnterstützung wünschen .
photoionisiert
Ich schlage vor, diesen Weg nicht zu benutzen. Es wird Godef brechen. godef versteht es nicht über "." Importe
König Jk
6

Für ein auf GitHub gehostetes Projekt tun die Leute normalerweise Folgendes:

github.com/
  laike9m/
    myproject/
      mylib/
        mylib.go
        ...
      main.go

mylib.go

package mylib

...

main.go

import "github.com/laike9m/myproject/mylib"

...
laike9m
quelle
6

Ich bin ein erfahrener Programmierer, aber ganz neu in der Go-Welt! Und ich gebe zu, ich hatte nur wenige Schwierigkeiten, Go zu verstehen ... Ich hatte das gleiche Problem, als ich versuchte, meine go-Dateien in Unterordnern zu organisieren. So wie ich es gemacht habe:

GO_Directory (dasjenige, das $ GOPATH zugewiesen ist)

GO_Directory //the one assigned to $GOPATH
__MyProject
_____ main.go
_____ Entites
_____ Fiboo // in my case, fiboo is a database name
_________ Client.go // in my case, Client is a table name

In der Datei MyProject \ Entities \ Fiboo \ Client.go

package Fiboo

type Client struct{
    ID int
    name string
}

in der Datei MyProject \ main.go

package main

import(
    Fiboo "./Entity/Fiboo" 
)

var TableClient  Fiboo.Client

func main(){
    TableClient.ID = 1
    TableClient.name = 'Hugo'

    // do your things here
}

(Ich verwende Go 1.9 unter Ubuntu 16.04)

Und denk dran, ich bin ein Neuling auf Go. Wenn das, was ich tue, schlechte Praxis ist, lass es mich wissen!

Diego Favero
quelle
3

eine andere Lösung: zu $ GOPATH
hinzufügen src/myproject.

Dann import "mylib"wird kompiliert.

Helin Wang
quelle
Dies funktioniert nicht für Go-Get-Table-Pfade wie von Github gehostete Pakete.
Gustav