Einführung
Abstraktionen um konkrete Details zu erstellen, ist das größte Werkzeug, das eine Programmiersprache einem Entwickler geben kann. Mithilfe von Strukturen können Go-Entwickler die Welt beschreiben, in der ein Go-Programm ausgeführt wird. Anstatt über Zeichenfolgen nachzudenken, die einStreet
,City
oder einPostalCode
beschreiben, können wir mit Strukturen stattdessen über einAddress
sprechen. Sie dienen als natürlicher Zusammenhang fürdocumentation in unseren Bemühungen, zukünftigen Entwicklern (einschließlich uns) mitzuteilen, welche Daten für unsere Go-Programme wichtig sind und wie zukünftiger Code diese Daten angemessen verwenden sollte. Strukturen können auf verschiedene Arten definiert und verwendet werden. In diesem Tutorial werden wir uns jede dieser Techniken ansehen.
Strukturen definieren
Strukturen funktionieren wie Papierformulare, mit denen Sie beispielsweise Ihre Steuern einreichen können. Papierformulare können Felder für Textinformationen wie Ihren Vor- und Nachnamen enthalten. Neben Textfeldern können Formulare Kontrollkästchen enthalten, mit denen boolesche Werte wie "verheiratet" oder "einzeln" oder Datumsfelder für das Geburtsdatum angegeben werden. In ähnlicher Weise sammeln Strukturen verschiedene Daten zusammen und organisieren sie unter verschiedenen Feldnamen. Wenn Sie eine Variable mit einer neuen Struktur initialisieren, ist es, als hätten Sie ein Formular fotokopiert und es für das Ausfüllen vorbereitet.
Um eine neue Struktur zu erstellen, müssen Sie zunächst Go eine Blaupause geben, die die Felder beschreibt, die die Struktur enthält. Diese Strukturdefinition beginnt normalerweise mit dem Schlüsselworttype
, gefolgt vom Namen der Struktur. Verwenden Sie danach das Schlüsselwortstruct
, gefolgt von zwei geschweiften Klammern{}
, in denen Sie die Felder deklarieren, die die Struktur enthalten soll. Nachdem Sie die Struktur definiert haben, können Sie Variablen deklarieren, die diese Strukturdefinition verwenden. In diesem Beispiel wird eine Struktur definiert und verwendet:
package main
import "fmt"
type Creature struct {
Name string
}
func main() {
c := Creature{
Name: "Sammy the Shark",
}
fmt.Println(c.Name)
}
Wenn Sie diesen Code ausführen, wird folgende Ausgabe angezeigt:
outputSammy the Shark
In diesem Beispiel definieren wir zunächst eineCreature
-Struktur, die einName
-Feld vom Typstring
enthält. Innerhalb des Hauptteils vonmain
erstellen wir eine Instanz vonCreature
, indem wir nach dem Namen des TypsCreature
ein Klammerpaar setzen und dann Werte für die Felder dieser Instanz angeben. Für die Instanz inc
wird das FeldName
auf "Sammy the Shark" gesetzt. Innerhalb des Funktionsaufrufs vonfmt.Println
rufen wir die Werte des Felds der Instanz ab, indem wir nach der Variablen, in der die Instanz erstellt wurde, einen Punkt setzen, gefolgt vom Namen des Felds, auf das wir zugreifen möchten. Beispielsweise gibtc.Name
in diesem Fall das FeldName
zurück.
Wenn Sie eine neue Instanz einer Struktur deklarieren, listen Sie im Allgemeinen die Feldnamen mit ihren Werten auf, wie im letzten Beispiel. Wenn alternativ jeder Feldwert während der Instanziierung einer Struktur angegeben wird, können Sie die Feldnamen weglassen, wie im folgenden Beispiel:
package main
import "fmt"
type Creature struct {
Name string
Type string
}
func main() {
c := Creature{"Sammy", "Shark"}
fmt.Println(c.Name, "the", c.Type)
}
Die Ausgabe ist dieselbe wie im letzten Beispiel:
outputSammy the Shark
Wir habenCreature
ein zusätzliches Feld hinzugefügt, um dieType
der Kreatur alsstring
zu verfolgen. Bei der Instanziierung vonCreature
innerhalb des Hauptteils vonmain
haben wir uns für die Verwendung der kürzeren Instanziierungsform entschieden, indem wir Werte für jedes Feld in der angegebenen Reihenfolge angegeben und deren Feldnamen weggelassen haben. In der DeklarationCreature{"Sammy", "Shark"}
nimmt das FeldName
den WertSammy
und das FeldType
den WertShark
an, daName
zuerst im Feld erscheint Typdeklaration, gefolgt vonType
.
Dieses kürzere Anmeldeformular hat einige Nachteile, die dazu geführt haben, dass die Go-Community in den meisten Fällen das längere Formular bevorzugt. Sie müssen Werte für jedes Feld in der Struktur angeben, wenn Sie die Kurzdeklaration verwenden. Sie können keine Felder überspringen, die Sie nicht interessieren. Dies führt schnell dazu, dass kurze Deklarationen für Strukturen mit vielen Feldern verwirrend werden. Aus diesem Grund wird das Deklarieren von Strukturen mithilfe der Kurzform in der Regel bei Strukturen mit wenigen Feldern verwendet.
Die Feldnamen in den bisherigen Beispielen haben alle mit Großbuchstaben begonnen. Dies ist wichtiger als eine stilistische Präferenz. Die Verwendung von Groß- oder Kleinbuchstaben für Feldnamen beeinflusst, ob Ihre Feldnamen für Code zugänglich sind, der in anderen Paketen ausgeführt wird.
Exportieren von Strukturfeldern
Felder einer Struktur folgen denselben Exportregeln wie andere Bezeichner in der Programmiersprache Go. Wenn ein Feldname mit einem Großbuchstaben beginnt, kann er von Code außerhalb des Pakets, in dem die Struktur definiert wurde, gelesen und geschrieben werden. Wenn das Feld mit einem Kleinbuchstaben beginnt, kann nur Code innerhalb des Pakets dieser Struktur dieses Feld lesen und schreiben. In diesem Beispiel werden exportierte und nicht exportierte Felder definiert:
package main
import "fmt"
type Creature struct {
Name string
Type string
password string
}
func main() {
c := Creature{
Name: "Sammy",
Type: "Shark",
password: "secret",
}
fmt.Println(c.Name, "the", c.Type)
fmt.Println("Password is", c.password)
}
Dies wird Folgendes ausgeben:
outputSammy the Shark
Password is secret
Wir haben unseren vorherigen Beispielen ein zusätzliches Feld hinzugefügt,secret
. secret
ist ein nicht exportiertesstring
-Feld. Dies bedeutet, dass jedes andere Paket, das versucht, einCreature
zu instanziieren, nicht auf seinsecret
-Feld zugreifen oder dieses festlegen kann. Im selben Paket können wir wie in diesem Beispiel auf diese Felder zugreifen. Damain
auch im Paketmain
enthalten ist, kann es aufc.password
verweisen und den dort gespeicherten Wert abrufen. Es ist üblich, nicht exportierte Felder in Strukturen zu haben, auf die über exportierte Methoden zugegriffen werden kann.
Inline-Strukturen
Zusätzlich zur Definition eines neuen Typs zur Darstellung einer Struktur können Sie auch eine Inline-Struktur definieren. Diese spontanen Strukturdefinitionen sind in Situationen nützlich, in denen das Erfinden neuer Namen für Strukturtypen unnötig wäre. Beispielsweise verwenden Tests häufig eine Struktur, um alle Parameter zu definieren, die einen bestimmten Testfall ausmachen. Es wäre umständlich, neue Namen wieCreatureNamePrintingTestCase
zu finden, wenn diese Struktur nur an einer Stelle verwendet wird.
Inline-Strukturdefinitionen werden auf der rechten Seite einer Variablenzuweisung angezeigt. Sie müssen unmittelbar danach eine Instanz davon bereitstellen, indem Sie ein zusätzliches Klammerpaar mit Werten für jedes der von Ihnen definierten Felder bereitstellen. Das folgende Beispiel zeigt eine Inline-Strukturdefinition:
package main
import "fmt"
func main() {
c := struct {
Name string
Type string
}{
Name: "Sammy",
Type: "Shark",
}
fmt.Println(c.Name, "the", c.Type)
}
Die Ausgabe dieses Beispiels lautet:
outputSammy the Shark
Anstatt einen neuen Typ zu definieren, der unsere Struktur mit dem Schlüsselworttype
beschreibt, definiert dieses Beispiel eine Inline-Struktur, indem die Definition vonstruct
unmittelbar nach dem Kurzzuweisungsoperator:=
platziert wird. Wir definieren die Felder der Struktur wie in den vorherigen Beispielen, müssen dann jedoch sofort ein weiteres Klammerpaar und die Werte angeben, die jedes Feld annehmen wird. Die Verwendung dieser Struktur ist jetzt genau die gleiche wie zuvor - wir können auf Feldnamen in Punktnotation verweisen. Die häufigste Stelle, an der Inline-Strukturen deklariert werden, sind Tests, da häufig einmalige Strukturen definiert werden, die Daten und Erwartungen für einen bestimmten Testfall enthalten.
Fazit
Strukturen sind Sammlungen heterogener Daten, die von Programmierern definiert werden, um Informationen zu organisieren. Die meisten Programme verarbeiten enorme Datenmengen, und ohne Strukturen wäre es schwierig, sich zu merken, welchestring
oderint
Variablen zusammen gehörten oder welche unterschiedlich waren. Wenn Sie das nächste Mal Gruppen von Variablen jonglieren, fragen Sie sich, ob diese Variablen möglicherweise besser mitstruct
gruppiert werden könnten. Diese Variablen haben möglicherweise schon immer ein Konzept auf höherer Ebene beschrieben.