Strukturen in Go definieren

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.Printlnrufen 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üsselworttypebeschreibt, definiert dieses Beispiel eine Inline-Struktur, indem die Definition vonstructunmittelbar 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.