Wie schreibe ich Go-Pakete

Ein Go-Paket besteht aus Go-Dateien, die sich im selben Verzeichnis befinden und an deren Anfang sich derselbe package . Mit Paketen, die eine Verbindung zu Programmen herstellen, können Sie deren Funktionen erweitern. Einige Pakete sind Teil der Standard-Go-Bibliothek. Wenn Sie Go verwenden, sind diese bereits installiert. Andere Pakete werden mit dem Befehl go get installiert. Sie können auch Ihre eigenen Go-Pakete schreiben, Dateien in speziellen Verzeichnissen erstellen und die Regeln des Paketdesigns einhalten.



Das Material, dessen Übersetzung wir heute veröffentlichen, ist ein Leitfaden für die Entwicklung von Go-Paketen, die mit anderen Dateien verbunden werden können.

Voraussetzungen


  • Richten Sie Ihre Go-Softwareumgebung ein (erfahren Sie hier , wie das geht ). Erstellen Sie einen Go-Arbeitsbereich (der fĂĽnfte Punkt des obigen Materials ist diesem Thema gewidmet). Im nächsten Abschnitt dieses Materials finden Sie Beispiele, deren Reproduktion zu Hause empfohlen wird. So können Sie besser mit ihnen umgehen.
  • Um Ihr Wissen ĂĽber GOPATH zu vertiefen, GOPATH Sie einen Blick auf dieses Material.

Pakete schreiben und importieren


Das Schreiben von Paketcode entspricht dem Schreiben von normalem Go-Code. Pakete können Deklarationen von Funktionen, Typen und Variablen enthalten, die dann in anderen Go-Programmen verwendet werden können.

Bevor wir mit dem Erstellen eines neuen Pakets beginnen können, müssen wir zum Go-Arbeitsbereich gehen. Es befindet sich auf dem von der GOPATH Variablen angegebenen GOPATH . Lassen Sie unsere Organisation zum Beispiel gopherguides heißen. Gleichzeitig verwenden wir als Repository GitHub . Dies führt dazu, dass wir entlang des von GOPATH angegebenen GOPATH die folgende Ordnerstruktur haben:

 └── $GOPATH    └── src        └── github.com            └── gopherguides 

Wir werden das Paket nennen, das wir in diesem Handbuch entwickeln werden, greet . Erstellen Sie dazu das greet Verzeichnis gopherguides . Infolgedessen hat die vorhandene Ordnerstruktur die folgende Form:

 └── $GOPATH    └── src        └── github.com            └── gopherguides                └── greet 

Jetzt können wir die erste Datei zum greet hinzufügen. In der Regel wird eine Datei, die der Einstiegspunkt eines Pakets ist, als Paketverzeichnis bezeichnet. In diesem Fall bedeutet dies, dass wir im Verzeichnis greet.go Datei greet.go erstellen:

 └── $GOPATH    └── src        └── github.com            └── gopherguides                └── greet                    └── greet.go 

In diese Datei können wir Code schreiben, den wir in unseren Projekten wiederverwenden möchten. In diesem Fall erstellen wir die Hello Funktion, die den Text Hello, World! .

Ă–ffnen Sie die Datei greet.go in einem Texteditor und fĂĽgen Sie den folgenden Code hinzu:

 package greet import "fmt" func Hello() {    fmt.Println("Hello, World!") } 

Lassen Sie uns den Inhalt dieser Datei analysieren. Die erste Zeile jeder Datei sollte den Namen des Pakets enthalten, in dem wir arbeiten. Da wir uns im greet package , wird hier das SchlĂĽsselwort package verwendet, gefolgt vom Paketnamen:

 package greet 

Dies weist den Compiler an, alles in der Datei als Teil des greet zu akzeptieren.

Als nächstes werden die erforderlichen Pakete mithilfe der import Anweisung import . In diesem Fall benötigen wir nur ein Paket - fmt :

 import "fmt" 

Und schlieĂźlich erstellen wir die Hello Funktion. Sie wird die Funktionen des fmt Pakets verwenden, um die Zeichenfolge Hello, World! ::

 func Hello() {    fmt.Println("Hello, World!") } 

Nachdem das greet erstellt wurde, können Sie es in jedem anderen Paket verwenden. Erstellen wir ein neues Paket, in dem wir das greet Paket verwenden.

Wir werden nämlich ein example erstellen. Dazu gehen wir von denselben Annahmen aus, von denen wir ausgegangen sind, und erstellen das greet . Erstellen Sie zunächst den example Ordner gopherguides :

 └── $GOPATH    └── src        └── github.com            └── gopherguides                    └── example 

Erstellen Sie nun eine Datei, die der Paketeinstiegspunkt ist. Wir betrachten dieses Paket als ausfĂĽhrbares Programm und nicht als Paket, dessen Code in anderen Paketen verwendet werden soll. Dateien, die die Eingabepunkte von Programmen sind, werden normalerweise als main.go :

 └── $GOPATH    └── src        └── github.com            └── gopherguides                └── example                    └── main.go 

Öffnen Sie die Datei main.go im Editor und main.go folgenden Code ein, mit dem Sie die Funktionen des greet Pakets nutzen können:

 package main import "github.com/gopherguides/greet" func main() {    greet.Hello() } 

Wir haben das greet Paket in die Datei main.go importiert. main.go bedeutet, dass wir zum Aufrufen der in diesem Paket deklarierten Funktion die Punktnotation verwenden mĂĽssen. Eine Punktnotation ist eine Konstruktion, bei der ein Punkt zwischen dem Paketnamen und dem Ressourcennamen dieses zu verwendenden Pakets eingefĂĽgt wird. Im greet Paket spielt beispielsweise die Hello Funktion die Rolle einer Ressource. Wenn Sie diese Funktion aufrufen mĂĽssen, wird die Punktnotation verwendet : greet.Hello() .

Jetzt können Sie das Terminal öffnen und das Programm ausführen:

 go run main.go 

Danach zeigt das Terminal Folgendes an:

 Hello, World! 

Lassen Sie uns nun darĂĽber sprechen, wie in Paketen deklarierte Variablen verwendet werden. greet.go Sie dazu die Variablendeklaration zur Datei greet.go :

 package greet import "fmt" var Shark = "Sammy" func Hello() {    fmt.Println("Hello, World!") } 

Ă–ffnen Sie die Datei main.go und fĂĽgen Sie eine Zeile hinzu, in der fmt.Println() Funktion fmt.Println() der Wert der im Paket greet.go deklarierten Shark Variablen greet.go . Bringen Sie main.go in das folgende Formular:

 package main import (    "fmt"    "github.com/gopherguides/greet" ) func main() {    greet.Hello()    fmt.Println(greet.Shark) } 

FĂĽhren Sie das Programm erneut aus:

 go run main.go 

Jetzt wird sie Folgendes ausgeben:

 Hello, World! Sammy 

Lassen Sie uns nun darĂĽber sprechen, wie Typen in Paketen deklariert werden. Erstellen Sie einen Octopus Typ mit den Feldern Name und Color und erstellen Sie eine Typmethode. Diese Methode gibt beim Aufruf den speziell verarbeiteten Inhalt von Octopus Feldern zurĂĽck. greet.go in die folgende Form:

 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 main.go nun main.go , erstellen Sie eine Instanz der Struktur des neuen Typs und verweisen Sie auf die String() -Methode:

 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()) } 

Nachdem Sie eine Instanz von Octopus mit einem Konstrukt erstellt haben, das wie oct := greet.Octopus , können Sie über den main.go Datei main.go auf die Methoden und Eigenschaften des Typs main.go . Auf diese Weise können Sie insbesondere den Befehl oct.String() am Ende der Datei main.go verwenden, ohne auf greet zurückgreifen zu müssen. Darüber hinaus können wir beispielsweise mit der oct.Color Konstruktion auf das Feld der oct.Color . Gleichzeitig greifen wir, wie beim Aufrufen der Methode, nicht auf die greet .

Die String Methode vom Typ Octopus verwendet die Funktion fmt.Sprintf , um den Satz zu bilden, und gibt mit return das Ergebnis, den String, an den Methodenaufruf zurĂĽck (in diesem Fall befindet sich diese Stelle in main.go ).

FĂĽhren Sie das Programm erneut aus:

 go run main.go 

Folgendes wird an die Konsole ausgegeben:

 Hello, World! Sammy The octopus's name is "Jesse" and is the color orange. 

Nachdem wir Octopus mit der String Methode ausgestattet haben, verfügen wir über einen Mechanismus zur Ausgabe von Typinformationen, der für die Wiederverwendung geeignet ist. Wenn Sie in Zukunft das Verhalten dieser Methode ändern müssen, die in vielen Projekten verwendet werden kann, reicht es aus, den Code in greet.go zu bearbeiten.

Entitätsexport


Möglicherweise haben Sie bemerkt, dass alles, mit dem wir beim Zugriff auf das greet haben, Namen hat, die mit einem Großbuchstaben beginnen. Go verfügt nicht über Zugriffsmodifikatoren wie public , private oder protected , die in anderen Sprachen verfügbar sind. Die Sichtbarkeit von Entitäten für externe Mechanismen wird durch die Tatsache gesteuert, mit welchem ​​Buchstaben, mit einem kleinen oder großen, ihre Namen beginnen. Daher sind Typen, Variablen und Funktionen, deren Namen mit einem Großbuchstaben beginnen, außerhalb des aktuellen Pakets verfügbar. Code, der außerhalb des Pakets sichtbar ist, wird als exportiert bezeichnet.

Wenn Sie den Octopus Typ mit einer neuen Methode namens reset ausstatten, kann diese Methode aus dem greet Paket aufgerufen werden, nicht jedoch aus der main.go Datei, die sich auĂźerhalb des greet Pakets befindet. Hier ist eine aktualisierte Version von 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!") } 

Versuchen wir, reset aus der Datei 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() } 

Dies fĂĽhrt zu folgendem Kompilierungsfehler:

 oct.reset undefined (cannot refer to unexported field or method greet.Octopus.reset) 

Um die reset vom Typ Octopus zu exportieren, mĂĽssen Sie sie umbenennen und den ersten Buchstaben in Kleinbuchstaben r durch GroĂźbuchstaben R ersetzen R Wir tun dies, indem wir greet.go bearbeiten:

 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!") } 

Dies führt dazu, dass wir Reset von anderen Paketen aus aufrufen können, ohne dass Fehlermeldungen auftreten:

 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()) } 

FĂĽhren Sie das Programm aus:

 go run main.go 

Folgendes gelangt zur Konsole:

 Hello, World! Sammy The octopus's name is "Jesse" and is the color orange The octopus's name is "" and is the color . 

Durch Aufrufen der Reset Methode haben wir die Felder Name und Color unserer Octopus Instanz gelöscht. Wenn Sie String aufrufen, bei dem zuvor der Inhalt der Felder Name und Color angezeigt wurde, wird jetzt nichts mehr angezeigt.

Zusammenfassung


Das Schreiben von Go-Paketen unterscheidet sich nicht vom Schreiben von normalem Go-Code. Wenn Sie den Paketcode jedoch in eigenen Verzeichnissen ablegen, können Sie den Code isolieren, der in allen anderen Go-Projekten verwendet werden kann. Hier haben wir darüber gesprochen, wie Funktionen, Variablen und Typen in Paketen deklariert werden, wie diese Entitäten außerhalb von Paketen verwendet werden und wo Pakete gespeichert werden, die für ihre wiederholte Verwendung ausgelegt sind.

Liebe Leser! Welche Programme schreiben Sie normalerweise auf Go? Verwenden Sie darin proprietäre Pakete?

Source: https://habr.com/ru/post/de464289/


All Articles