Ein Paket besteht aus Go-Dateien, die sich in demselben Verzeichnis befinden und am Anfang dieselbe Paketanweisung haben. Sie können zusätzliche Funktionen aus Paketen einbinden, um Ihre Programme komplexer zu gestalten. Einige Pakete sind über die Go-Standardbibliothek verfügbar und werden daher mit Ihrer Go-Installation installiert. Andere können mit dem Befehlgo get
von Go installiert werden. Sie können auch Ihre eigenen Go-Pakete erstellen, indem Sie Go-Dateien in demselben Verzeichnis erstellen, in dem Sie Code mithilfe der erforderlichen Paketanweisung freigeben möchten.
Dieses Tutorial führt Sie durch das Schreiben von Go-Paketen zur Verwendung in anderen Programmdateien.
Voraussetzungen
-
Richten Sie eine Go-Programmierumgebung nach einem der Tutorials aus derHow To Install and Set Up a Local Programming Environment for Go-Serie ein. Erstellen Sie Ihren Go Workspace gemäß Schritt 5 in den Tutorials zur lokalen Programmierumgebung. Lesen Sie den ersten Abschnitt Schreiben und Importieren von Paketen, um das Beispiel und die Namenskonventionen in diesem Artikel zu befolgen.
-
Lesen Sie unseren ArtikelUnderstanding the GOPATH, um Ihr Wissen über den GOPATH zu vertiefen.
Pakete schreiben und importieren
Das Schreiben eines Pakets entspricht dem Schreiben einer beliebigen anderen Go-Datei. Pakete können Definitionen von Funktionen,types undvariables enthalten, die dann in anderen Go-Programmen verwendet werden können.
Bevor wir ein neues Paket erstellen, müssen wir uns in unserem Go-Arbeitsbereich befinden. Dies liegt normalerweise unter unserengopath
. In diesem Tutorial nennen wir beispielsweise das Paketgreet
. Zu diesem Zweck haben wir in unseremgopath
unter unserem Projektbereich ein Verzeichnis mit dem Namengreet
erstellt. Wenn unsere Organisationgopherguides
wäre und wir das Paketgreet
unter der Organisation erstellen möchten, während wir Github als Code-Repository verwenden, würde unser Verzeichnis folgendermaßen aussehen:
└── $GOPATH
└── src
└── github.com
└── gopherguides
Das Verzeichnisgreet
befindet sich im Verzeichnisgopherguides
:
└── $GOPATH
└── src
└── github.com
└── gopherguides
└── greet
Schließlich können wir die erste Datei in unser Verzeichnis aufnehmen. Es wird allgemein angenommen, dass die Dateiprimary
oderentry point
in einem Paket nach dem Namen des Verzeichnisses benannt ist. In diesem Fall erstellen wir eine Datei mit dem Namengreet.go
im Verzeichnisgreet
:
└── $GOPATH
└── src
└── github.com
└── gopherguides
└── greet
└── greet.go
Mit der erstellten Datei können wir beginnen, unseren Code zu schreiben, den wir wiederverwenden oder projektübergreifend freigeben möchten. In diesem Fall erstellen wir eine Funktion namensHello
, dieHello World
ausgibt.
Öffnen Sie die Dateigreet.go
in Ihrem Texteditor und fügen Sie den folgenden Code hinzu:
greet.go
package greet
import "fmt"
func Hello() {
fmt.Println("Hello, World!")
}
Lassen Sie uns diese erste Datei aufschlüsseln. Die erste Zeile jeder Datei benötigt den Namen derpackage
, in denen Sie arbeiten. Da Sie sich im Paketgreet
befinden, verwenden Sie das Schlüsselwortpackage
, gefolgt vom Namen des Pakets:
package greet
Dadurch wird der Compiler angewiesen, alles in der Datei als Teil des Paketsgreet
zu behandeln.
Als Nächstes deklarieren Sie alle anderen Pakete, die Sie mit der Anweisungimport
verwenden müssen. Sie verwenden in dieser Datei nur eine - das Paketfmt
:
import "fmt"
Zuletzt erstellen Sie die FunktionHello
. Es wird das Paketfmt
verwendet, umHello, World!
auszudrucken:
func Hello() {
fmt.Println("Hello, World!")
}
Nachdem Sie das Paketgreet
geschrieben haben, können Sie es in jedem anderen von Ihnen erstellten Paket verwenden. Erstellen Sie ein neues Paket, in dem Sie das Paketgreet
verwenden.
Sie erstellen ein Paket mit dem Namenexample
. Dies bedeutet, dass Sie ein Verzeichnis mit dem Namenexample
benötigen. Erstellen Sie dieses Paket in der Organisation Ihresgopherguides
, sodass die Verzeichnisstruktur folgendermaßen aussieht:
└── $GOPATH
└── src
└── github.com
└── gopherguides
└── example
Nachdem Sie das Verzeichnis für Ihr neues Paket erstellt haben, können Sie die Einstiegspunktdatei erstellen. Da dies ein ausführbares Programm sein wird, wird es als bewährte Methode angesehen, die Einstiegspunktdateimain.go
zu benennen:
└── $GOPATH
└── src
└── github.com
└── gopherguides
└── example
└── main.go
Öffnen Sie in Ihrem Texteditormain.go
und fügen Sie den folgenden Code hinzu, um das Paketgreet
aufzurufen:
main.go
package main
import "github.com/gopherguides/greet"
func main() {
greet.Hello()
}
Da Sie ein Paket importieren, müssen Sie die Funktion aufrufen, indem Sie den Paketnamen in Punktnotation referenzieren. Dot notation ist die Praxis, einen Punkt.
zwischen dem Namen des von Ihnen verwendeten Pakets und der Ressource in dem Paket, das Sie verwenden möchten, einzufügen. In Ihremgreet
-Paket haben Sie beispielsweise dieHello
-Funktion als Ressource. Wenn Sie diese Ressource aufrufen möchten, verwenden Sie die Punktnotationgreet.Hello()
.
Jetzt können Sie Ihr Terminal öffnen und das Programm in der Befehlszeile ausführen:
go run main.go
In diesem Fall erhalten Sie die folgende Ausgabe:
OutputHello, World!
Um zu sehen, wie Sie Variablen in einem Paket verwenden können, fügen wir Ihrergreet.go
-Datei eine Variablendefinition hinzu:
greet.go
package greet
import "fmt"
var Shark = "Sammy"
func Hello() {
fmt.Println("Hello, World!")
}
Öffnen Sie als Nächstes Ihremain.go
-Datei und fügen Sie die folgende hervorgehobene Zeile hinzu, um die Variable vongreet.go
in einerfmt.Println()
-Funktion aufzurufen:
main.go
package main
import (
"fmt"
"github.com/gopherguides/greet"
)
func main() {
greet.Hello()
fmt.Println(greet.Shark)
}
Sobald Sie das Programm erneut ausführen:
go run main.go
Sie erhalten folgende Ausgabe:
OutputHello, World!
Sammy
Lassen Sie uns abschließend auch einen Typ in der Dateigreet.go
definieren. Sie erstellen den TypOctopus
mit den Feldernname
undcolor
und einer Funktion, die die Felder beim Aufruf ausgibt:
greet.go
package greet
import "fmt"
var Shark = "Sammy"
type Octopus struct {
Name string
Color string
}
func (o Octopus) String() string {
return fmt.Sprintf("The octopus's name is %q and is the color %s.", o.Name, o.Color)
}
func Hello() {
fmt.Println("Hello, World!")
}
Öffnen Siemain.go
, um am Ende der Datei eine Instanz dieses Typs zu erstellen:
main.go
package main
import (
"fmt"
"github.com/gopherguides/greet"
)
func main() {
greet.Hello()
fmt.Println(greet.Shark)
oct := greet.Octopus{
Name: "Jesse",
Color: "orange",
}
fmt.Println(oct.String())
}
Sobald Sie mitoct := greet.Octopus
eine Instanz vom TypOctopus
erstellt haben, können Sie auf die Funktionen und Felder des Typs im Namespace der Dateimain.go
zugreifen. Auf diese Weise können Sieoct.String()
in die letzte Zeile schreiben, ohnegreet
aufzurufen. Sie können beispielsweise auch eines der Typfelder wieoct.Color
aufrufen, ohne auf den Namen des Paketsgreet
zu verweisen.
Die MethodeString
für den TypOctopus
verwendet die Funktionfmt.Sprintf
, um einen Satz zu erstellen, undreturns
das Ergebnis, eine Zeichenfolge, für den Aufrufer (in diesem Fall Ihre Hauptleitung) Programm).
Wenn Sie das Programm ausführen, erhalten Sie folgende Ausgabe:
go run main.go
OutputHello, World!
Sammy
The octopus's name is "Jesse" and is the color orange.
Durch Erstellen derString
-Methode fürOctopus
haben Sie jetzt eine wiederverwendbare Möglichkeit, Informationen zu Ihrem benutzerdefinierten Typ auszudrucken. Wenn Sie das Verhalten dieser Methode in Zukunft ändern möchten, müssen Sie nur diese eine Methode bearbeiten.
Exportierter Code
Möglicherweise haben Sie bemerkt, dass alle Deklarationen in der von Ihnen aufgerufenengreet.go
-Datei groß geschrieben wurden. Go hat nicht das Konzept vonpublic
,private
oderprotected
Modifikatoren wie andere Sprachen. Die Sichtbarkeit nach außen wird durch die Großschreibung gesteuert. Typen, Variablen, Funktionen usw., die mit einem Großbuchstaben beginnen, sind außerhalb des aktuellen Pakets öffentlich verfügbar. Ein Symbol, das außerhalb des Pakets sichtbar ist, wird alsexported
betrachtet.
Wenn SieOctopus
eine neue Methode hinzufügen, diereset
heißt, können Sie sie aus dem Paketgreet
aufrufen, jedoch nicht aus der Dateimain.go
, die sich außerhalb vonmain.go
befindet. t4) s Paket:
greet.go
package greet
import "fmt"
var Shark = "Sammy"
type Octopus struct {
Name string
Color string
}
func (o Octopus) String() string {
return fmt.Sprintf("The octopus's name is %q and is the color %s.", o.Name, o.Color)
}
func (o *Octopus) reset() {
o.Name = ""
o.Color = ""
}
func Hello() {
fmt.Println("Hello, World!")
}
Wenn Sie versuchen,reset
aus der Dateimain.go
aufzurufen:
main.go
package main
import (
"fmt"
"github.com/gopherguides/greet"
)
func main() {
greet.Hello()
fmt.Println(greet.Shark)
oct := greet.Octopus{
Name: "Jesse",
Color: "orange",
}
fmt.Println(oct.String())
oct.reset()
}
Sie erhalten den folgenden Kompilierungsfehler:
Outputoct.reset undefined (cannot refer to unexported field or method greet.Octopus.reset)
Umexport
diereset
Funktionalität vonOctopus
zu erhalten, aktivieren Sie dieR
inreset
:
greet.go
package greet
import "fmt"
var Shark = "Sammy"
type Octopus struct {
Name string
Color string
}
func (o Octopus) String() string {
return fmt.Sprintf("The octopus's name is %q and is the color %s.", o.Name, o.Color)
}
func (o *Octopus) Reset() {
o.Name = ""
o.Color = ""
}
func Hello() {
fmt.Println("Hello, World!")
}
Infolgedessen können SieReset
von Ihrem anderen Paket aus aufrufen, ohne eine Fehlermeldung zu erhalten:
main.go
package main
import (
"fmt"
"github.com/gopherguides/greet"
)
func main() {
greet.Hello()
fmt.Println(greet.Shark)
oct := greet.Octopus{
Name: "Jesse",
Color: "orange",
}
fmt.Println(oct.String())
oct.Reset()
fmt.Println(oct.String())
}
Nun, wenn Sie das Programm ausführen:
go run main.go
Sie erhalten folgende Ausgabe:
OutputHello, World!
Sammy
The octopus's name is "Jesse" and is the color orange
The octopus's name is "" and is the color .
Durch Aufrufen vonReset
haben Sie alle Informationen in den FeldernName
undColor
gelöscht. Wenn Sie die MethodeString
aufrufen, wird nichts gedruckt, woName
undColor
normalerweise angezeigt werden, da die Felder jetzt leer sind.
Fazit
Das Schreiben eines Go-Pakets entspricht dem Schreiben einer beliebigen anderen Go-Datei. Wenn Sie es jedoch in einem anderen Verzeichnis ablegen, können Sie den Code isolieren, der an einer anderen Stelle wiederverwendet werden soll. In diesem Lernprogramm wurde das Schreiben von Definitionen in ein Paket behandelt, die Verwendung dieser Definitionen in einer anderen Go-Programmdatei erläutert und die Optionen für die Aufbewahrung des Pakets für den Zugriff darauf erläutert.