Informationen zu Paketen

Abgeschlossen

Pakete in Go sind wie Bibliotheken oder Module in anderen Programmiersprachen. Sie können Ihren Code packen und an anderer Stelle wiederverwenden. Der Quellcode eines Pakets kann in mehr als einer .go-Datei bereitgestellt werden. Bisher haben wir das Paket main geschrieben und einige Verweise auf andere native Pakete hergestellt.

In diesem Abschnitt erfahren Sie, was ein Paket ist. Außerdem wird erläutert, wie Sie ein Paket erstellen und externe Pakete nutzen können.

Das Paket „main“

Wie Sie möglicherweise bereits festgestellt haben, muss sogar das einfachste Programm in Go Teil eines Pakets sein. Normalerweise ist main das Standardpaket. Dieses Paket haben wir bisher verwendet. Wenn ein Programm Teil des Pakets main ist, generiert Go eine Binärdatei. Wenn diese Datei ausgeführt wird, ruft sie die Funktion main() auf.

Anders ausgedrückt: Wenn Sie das Paket main verwenden, erstellt Ihr Programm eine eigenständige ausführbare Datei. Wenn ein Programm jedoch Teil eines anderen Pakets als main ist, generiert Go keine Binärdatei. Es wird eine Paketarchivdatei generiert, d. h. eine Datei mit der Erweiterung .a.

In Go folgen Paketnamen einer Konvention. Ein Paket verwendet den letzten Teil des Importpfads als Namen. Die Go-Standardbibliothek enthält beispielsweise ein Paket namens math/cmplx, das nützlichen Code für die Arbeit mit komplexen Zahlen bereitstellt. Der Importpfad dieses Pakets lautet math/cmplx, und Sie importieren es wie folgt:

import "math/cmplx"

Um auf Objekte im Paket zu verweisen, verwenden Sie den Paketnamen cmplx wie folgt:

cmplx.Inf()

Erstellen Sie ein Paket.

Erstellen eines Pakets

Erstellen Sie im Verzeichnis $GOPATH/src ein neues Verzeichnis mit dem Namen calculator. Erstellen Sie eine Datei namens sum.go. Das Strukturverzeichnis sollte in etwa wie folgt aussehen:

src/
  calculator/
    sum.go

Initialisieren Sie die Datei sum.go mit dem Namen des Pakets:

package calculator

Nun können Sie damit beginnen, die Funktionen und Variablen für das Paket zu schreiben. Im Gegensatz zu anderen Programmiersprachen stellt Go nicht die Stichwörter public oder private bereit, um anzugeben, ob eine Variable oder Funktion von außerhalb oder innerhalb des Pakets aufgerufen werden kann. Bei Go gibt es allerdings zwei einfachen Regeln:

  • Wenn etwas privat bleiben soll, schreiben Sie den ersten Buchstaben des Namens klein.
  • Wenn etwas öffentlich sein soll, schreiben Sie den ersten Buchstaben des Namens groß.

Fügen Sie dem Rechnerpaket, das Sie erstellen, den folgenden Code hinzu:

package calculator

var logMessage = "[LOG]"

// Version of the calculator
var Version = "1.0"

func internalSum(number int) int {
    return number - 1
}

// Sum two integer numbers
func Sum(number1, number2 int) int {
    return number1 + number2
}

Sehen wir uns einige Elemente dieses Codes genauer an:

  • Die Variable logMessage kann nur innerhalb des Pakets aufgerufen werden.
  • Die Variable Version kann von überall aus erreicht werden. Es wird empfohlen, einen Kommentar hinzufügen, um den Zweck dieser Variablen zu beschreiben. Diese Beschreibung ist hilfreich für alle Benutzer, die das Paket verwenden.
  • Die Funktion internalSum kann nur innerhalb des Pakets aufgerufen werden.
  • Die Funktion Sum kann von überall aus erreicht werden. Es wird empfohlen, einen Kommentar hinzufügen, um den Zweck dieser Funktion zu beschreiben.

Sie können überprüfen, ob alles funktioniert, indem Sie den Befehl go build im Verzeichnis calculator ausführen. Dabei sollte keine ausführbare Binärdatei generiert werden.

Erstellen eines Moduls

Sie haben die Rechnerfunktionen in ein Paket platziert. Nun ist es an der Zeit, das Paket in ein Modul zu platzieren. Go-Module enthalten in der Regel Pakete, die verwandte Funktionen bieten. Das Modul eines Pakets gibt auch den Kontext an, den Go benötigt, um den Code auszuführen, den Sie gruppiert haben. Diese Kontextinformationen umfassen die Go-Version, für die Ihr Code geschrieben wurde.

Außerdem helfen Module anderen Entwicklern dabei, bestimmte Versionen Ihres Codes zu referenzieren, und erleichtern die Arbeit mit Abhängigkeiten. Ein weiterer Vorteil besteht darin, dass der Quellcode des Programms nicht unbedingt im Verzeichnis $GOPATH/src gespeichert sein muss. Wenn Sie diese Einschränkung aufheben, ist es einfacher, gleichzeitig mit verschiedenen Paketversionen in anderen Projekten zu arbeiten.

Wenn Sie also ein Modul für das Paket calculator erstellen möchten, führen Sie diesen Befehl im Stammverzeichnis ($GOPATH/src/calculator) aus:

go mod init github.com/myuser/calculator

Nachdem Sie diesen Befehl ausgeführt haben, wird github.com/myuser/calculator als Name des Moduls übernommen. Sie können diesen Namen verwenden, um in anderen Programmen auf das Paket zu verweisen. Der Befehl erstellt auch eine neue Datei mit dem Namen go.mod. Das Strukturverzeichnis sollte nun wie folgt aussehen:

src/
  calculator/
    go.mod
    sum.go

Der Inhalt der Datei go.mod sollte wie der folgende Code aussehen: Eventuell wird eine andere Go-Version angegeben.

module github.com/myuser/calculator

go 1.14

Wenn Sie in anderen Programmen auf Ihr calculator-Paket verweisen möchten, müssen Sie es mithilfe des Modulnamens importieren. In diesem Fall lautet der Name github.com/myuser/calculator. Im nächsten Abschnitt wird ein Beispiel zur Verwendungsweise dieses Pakets vorgestellt.

Hinweis

In der Vergangenheit war die Verwaltung von Abhängigkeiten in Go nicht ganz einfach. An dem System für die Verwaltung von Abhängigkeiten wird noch immer gearbeitet. Weitere Informationen zu Modulen finden Sie in diesen Beiträgen im Go-Blog.

Herstellen eines Verweises auf ein lokales Paket (ein Modul)

Verwenden Sie nun das Paket. Sie können mit derselben Beispielanwendung weiterarbeiten. Dieses Mal sollten Sie aber nicht die Funktion sum im Paket main verwenden, sondern die Funktion, die Sie vorhin im Paket calculator erstellt haben.

Die Dateistruktur sollte nun wie folgt aussehen:

src/
  calculator/
    go.mod
    sum.go
  helloworld/
    main.go

Verwenden Sie diesen Code für die Datei $GOPATH/src/helloworld/main.go:

package main

import (
  "fmt"
  "github.com/myuser/calculator"
)

func main() {
    total := calculator.Sum(3, 5)
    fmt.Println(total)
    fmt.Println("Version: ", calculator.Version)
}

Die Importanweisung verwendet hierbei den Namen des Pakets, das Sie erstellt haben: calculator. Wenn Sie die Funktion Sum aus diesem Paket aufrufen möchten, müssen Sie den Paketnamen wie in calculator.Sum einschließen. Sie haben außerdem jetzt Zugriff auf die Variable Version. Rufen Sie diese wie folgt auf: calculator.Version.

Wenn Sie jetzt versuchen, das Programm auszuführen, wird es nicht funktionieren. Sie müssen Go mitteilen, dass Sie Module verwenden, um auf andere Pakete zu verweisen. Führen Sie hierzu den folgenden Befehl im Verzeichnis $GOPATH/src/helloworld aus:

go mod init helloworld

Im vorherigen Befehl ist helloworld der Name des Projekts. Mit diesem Befehl wird eine neue go.mod-Datei erstellt. Damit sieht das Strukturverzeichnis wie folgt aus:

src/
  calculator/
    go.mod
    sum.go
  helloworld/
    go.mod
    main.go

Wenn Sie die Datei go.mod öffnen, sollte der Code in etwa wie folgt aussehen: Eventuell wird eine andere Go-Version angegeben.

module helloworld

go 1.14

Da Sie auf eine lokale Kopie des Moduls verweisen, müssen Sie Go darüber informieren, dass Sie keinen Remotespeicherort verwenden möchten. Dafür müssen Sie die Datei go.mod wie folgt manuell ändern, damit sie den Verweis enthält:

module helloworld

go 1.14

require github.com/myuser/calculator v0.0.0

replace github.com/myuser/calculator => ../calculator

Das Stichwort replace gibt an, dass für das Modul ein lokales Verzeichnis anstelle eines Remotespeicherorts verwendet werden soll. In diesem Fall lautet der Speicherort ganz einfach ../calculator, weil sich die Programme helloworld und calculator in $GOPATH/src befinden. Wenn sich die Quelle des Moduls an einem anderen Speicherort befindet, definieren Sie hier den lokalen Pfad.

Verwenden Sie den folgenden Befehl, um das Programm auszuführen:

go run main.go

Die Ausgabe sollte wie folgt lauten:

8
Version:  1.0

Herausforderung 1

Was geschieht, wenn Sie versuchen, die Variable logMessage oder die Funktion internalSumaus dem Paket calculator in der Hauptanwendung aufzurufen? Wird sie ausgeführt? Ausprobieren!

Aufgabenlösung:

package main

import (
 "fmt"
 "github.com/myuser/calculator"
)

func main() {
    total := calculator.internalSum(5)
    fmt.Println(total)
    fmt.Println("Version: ", calculator.logMessage)
}

Veröffentlichen eines Pakets

Es ist relativ einfach, ein Go-Paket zu veröffentlichen. Sie müssen lediglich den Quellcode des Pakets öffentlich verfügbar machen. Die meisten Entwickler*innen verwenden GitHub, um Pakete für die Öffentlichkeit verfügbar zu machen. Deshalb finden Sie in Importanweisungen manchmal Verweise auf github.com.

Wenn Sie z. B. das Paket calculator in Ihrem GitHub-Konto veröffentlichen möchten, müssen Sie ein Repository mit dem Namen calculator erstellen. Die URL sollte in etwa wie folgt aussehen:

https://github.com/myuser/calculator

Sie können Ihren Paketen Versionsnummern hinzufügen, indem Sie Ihr Repository wie folgt kennzeichnen:

git tag v0.1.0
git push origin v0.1.0

Entwickler, die Ihr Paket verwenden möchten (Sie eingeschlossen), verweisen wie folgt auf dieses:

import "github.com/myuser/calculator"

Im Folgenden wird ausführlicher erläutert, wie Sie auf Pakete von Drittanbietern verweisen können.

Verweise auf externe Pakete (Drittanbieterpakete)

Manchmal müssen Ihre Programme auf Pakete verweisen, die von anderen Entwicklern geschrieben wurden. Diese Pakete sind in der Regel auf GitHub verfügbar. Die folgenden Hinweise zum Herstellen von Verweisen auf Drittanbieterpakete sind unabhängig davon gültig, ob Sie ein Paket (ein anderes Paket als main) oder ein eigenständiges Programm (das Paket main) entwickeln.

Fügen Sie einen Verweis auf das Paket rsc.io/quote hinzu:

package main

import (
    "fmt"
    "github.com/myuser/calculator"
    "rsc.io/quote"
)

func main() {
    total := calculator.Sum(3, 5)
    fmt.Println(total)
    fmt.Println("Version: ", calculator.Version)
    fmt.Println(quote.Hello())
}

Wenn Sie Visual Studio Code verwenden, wird die Datei go.mod aktualisiert, wenn Sie sie speichern. Sie sieht jetzt so aus:

module helloworld

go 1.14

require (
    github.com/myuser/calculator v0.0.0
    rsc.io/quote v1.5.2
)

replace github.com/myuser/calculator => ../calculator

rsc.io/quote verweist auf eine bestimmte Version des Pakets. Wenn Sie ein Upgrade der Programmabhängigkeiten durchführen müssen, müssen Sie die Version hier ändern.

Verwenden Sie den folgenden Befehl, um das Programm noch mal auszuführen:

go run main.go

Die Ausgabe sollte wie folgt aussehen:

8
Version:  1.0
Hello, world.

Alle zukünftigen Verweise auf Pakete von Drittanbietern müssen sich in der Datei go.mod befinden. Wenn Sie die Anwendung ausführen oder kompilieren, lädt Go alle ihre Abhängigkeiten herunter.