Heim > Backend-Entwicklung > Golang > Tauchen Sie tief in Go Struct ein

Tauchen Sie tief in Go Struct ein

Linda Hamilton
Freigeben: 2025-01-04 05:02:40
Original
426 Leute haben es durchsucht

In Go ist struct ein Aggregattyp, der zum Definieren und Kapseln von Daten verwendet wird. Es ermöglicht die Kombination von Feldern unterschiedlicher Art. Strukturen können als benutzerdefinierte Datentypen betrachtet werden, ähnlich wie Klassen in anderen Sprachen, sie unterstützen jedoch keine Vererbung. Methoden sind Funktionen, die einem bestimmten Typ (häufig einer Struktur) zugeordnet sind und mit einer Instanz dieses Typs aufgerufen werden können.

Strukturen definieren und initialisieren

Definieren einer Struktur

Strukturen werden mithilfe der Schlüsselwörter type und struct definiert. Hier ist ein Beispiel für eine einfache Strukturdefinition:

type User struct {
  Username    string
  Email       string
  SignInCount int
  IsActive    bool
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Initialisieren einer Struktur

Strukturen können auf verschiedene Arten initialisiert werden.

Initialisierung mit Feldnamen

user1 := User{
  Username:    "alice",
  Email:       "alice@example.com",
  SignInCount: 1,
  IsActive:    true,
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Initialisierung mit Standardwerten

Wenn einige Felder nicht angegeben sind, werden sie auf ihre Nullwerte für die jeweiligen Typen initialisiert.

user2 := User{
  Username: "bob",
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

In diesem Beispiel wird Email mit einer leeren Zeichenfolge ("") initialisiert, SignInCount auf 0 und IsActive auf false.

Initialisierung mit einem Zeiger

Eine Struktur kann auch mit einem Zeiger initialisiert werden.

user3 := &User{
  Username: "charlie",
  Email:    "charlie@example.com",
}
Nach dem Login kopieren
Nach dem Login kopieren

Methoden und Verhalten von Strukturen

In Go dienen Strukturen nicht nur zum Speichern von Daten, sondern es können auch Methoden für sie definiert werden. Dies ermöglicht es Strukturen, Verhalten im Zusammenhang mit ihren Daten zu kapseln. Nachfolgend finden Sie eine detaillierte Erläuterung der Strukturmethoden und des Verhaltens.

Methoden für Strukturen definieren

Methoden werden mithilfe eines Empfängers definiert, der der erste Parameter der Methode ist und den Typ angibt, zu dem die Methode gehört. Der Empfänger kann entweder ein Wertempfänger oder ein Zeigerempfänger sein.

Wertempfänger

Ein Wertempfänger erstellt eine Kopie der Struktur, wenn die Methode aufgerufen wird, sodass Änderungen an Feldern keine Auswirkungen auf die ursprüngliche Struktur haben.

type User struct {
  Username string
  Email    string
}

func (u User) PrintInfo() {
  fmt.Printf("Username: %s, Email: %s\n", u.Username, u.Email)
}
Nach dem Login kopieren
Nach dem Login kopieren

Zeigerempfänger

Ein Zeigerempfänger ermöglicht der Methode, die ursprünglichen Strukturfelder direkt zu ändern.

func (u *User) UpdateEmail(newEmail string) {
  u.Email = newEmail
}
Nach dem Login kopieren

Methodensätze

In Go bilden alle Methoden einer Struktur ihren Methodensatz. Der Methodensatz für einen Wertempfänger umfasst alle Methoden mit Wertempfängern, während der Methodensatz für einen Zeigerempfänger alle Methoden mit Zeiger- und Wertempfängern umfasst.

Schnittstellen und Strukturmethoden

Strukturmethoden werden häufig mit Schnittstellen verwendet, um Polymorphismus zu erreichen. Beim Definieren einer Schnittstelle geben Sie die Methoden an, die eine Struktur implementieren muss.

type UserInfo interface {
  PrintInfo()
}

// User implements the UserInfo interface
func (u User) PrintInfo() {
  fmt.Printf("Username: %s, Email: %s\n", u.Username, u.Email)
}

func ShowInfo(ui UserInfo) {
  ui.PrintInfo()
}
Nach dem Login kopieren

Speicherausrichtung in Strukturen

In Go soll die Speicherausrichtung für Strukturen die Zugriffseffizienz verbessern. Verschiedene Datentypen haben spezifische Ausrichtungsanforderungen, und der Compiler kann Füllbytes zwischen Strukturfeldern einfügen, um diese Anforderungen zu erfüllen.

Was ist Gedächtnisausrichtung?

Speicherausrichtung bedeutet, dass sich Daten im Speicher an Adressen befinden müssen, die ein Vielfaches bestimmter Werte sind. Die Größe eines Datentyps bestimmt seine Ausrichtungsanforderung. Beispielsweise erfordert int32 eine Ausrichtung auf 4 Bytes und int64 eine Ausrichtung auf 8 Bytes.

Warum ist eine Gedächtnisausrichtung notwendig?

Effizienter Speicherzugriff ist entscheidend für die CPU-Leistung. Wenn eine Variable nicht richtig ausgerichtet ist, benötigt die CPU möglicherweise mehrere Speicherzugriffe, um Daten zu lesen oder zu schreiben, was zu Leistungseinbußen führt. Durch die Ausrichtung der Daten sorgt der Compiler für einen effizienten Speicherzugriff.

Regeln für die Strukturgedächtnisausrichtung

  • Feldausrichtung: Die Adresse jedes Felds muss die Ausrichtungsanforderungen seines Typs erfüllen. Der Compiler kann Füllbytes zwischen Feldern einfügen, um eine ordnungsgemäße Ausrichtung sicherzustellen.
  • Strukturausrichtung: Die Größe einer Struktur muss ein Vielfaches der größten Ausrichtungsanforderung unter ihren Feldern sein.

Beispiel:

type User struct {
  Username    string
  Email       string
  SignInCount int
  IsActive    bool
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Ausgabe: 12

Analyse:

  • a ist int8, belegt 1 Byte und ist auf 1 ausgerichtet.
  • b ist int32 und erfordert eine Ausrichtung auf 4 Bytes. Der Compiler fügt 3 Füllbytes zwischen a und b ein, um die Adresse von b auf 4 auszurichten.
  • c ist int8 und erfordert 1 Byte, aber die Gesamtgröße der Struktur muss ein Vielfaches von 4 sein (die größte Ausrichtungsanforderung). Der Compiler fügt am Ende 3 Füllbytes hinzu.

Optimierung der Speicherausrichtung

Sie können Strukturfelder neu anordnen, um das Auffüllen zu minimieren und die Speichernutzung zu reduzieren.

user1 := User{
  Username:    "alice",
  Email:       "alice@example.com",
  SignInCount: 1,
  IsActive:    true,
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Ausgabe: 8

In dieser optimierten Version wird b zuerst platziert und auf 4 Bytes ausgerichtet. a und c werden nacheinander platziert, sodass die Gesamtgröße 8 Byte beträgt, was kompakter ist als die nicht optimierte Version.

Zusammenfassung

  • Strukturfeldern in Go wird Speicher basierend auf ihren Ausrichtungsanforderungen zugewiesen, mit potenziellen Füllbytes.
  • Durch Anpassen der Reihenfolge der Felder kann das Auffüllen minimiert und die Speichernutzung optimiert werden.
  • Verwenden Sie unsafe.Sizeof, um die tatsächliche Speichergröße einer Struktur zu bestimmen.

Verschachtelte Strukturen und Zusammensetzung

In Go sind verschachtelte Strukturen und Kompositionen leistungsstarke Werkzeuge für die Wiederverwendung von Code und die Organisation komplexer Daten. Verschachtelte Strukturen ermöglichen es einer Struktur, eine andere Struktur als Feld einzuschließen, was die Erstellung komplexer Datenmodelle ermöglicht. Die Komposition hingegen erstellt neue Strukturen, indem sie andere Strukturen einschließt, was die Wiederverwendung von Code erleichtert.

Verschachtelte Strukturen

Verschachtelte Strukturen ermöglichen es einer Struktur, eine andere Struktur als Feld einzuschließen. Dadurch werden Datenstrukturen flexibler und organisierter. Hier ist ein Beispiel für eine verschachtelte Struktur:

type User struct {
  Username    string
  Email       string
  SignInCount int
  IsActive    bool
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Strukturzusammensetzung

Composition ermöglicht die Kombination mehrerer Strukturen zu einer neuen Struktur und ermöglicht so die Wiederverwendung von Code. In der Komposition kann eine Struktur mehrere andere Strukturen als Felder enthalten. Dies hilft dabei, komplexere Modelle zu erstellen und gemeinsame Felder oder Methoden zu teilen. Hier ist ein Beispiel für die Strukturzusammensetzung:

user1 := User{
  Username:    "alice",
  Email:       "alice@example.com",
  SignInCount: 1,
  IsActive:    true,
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Unterschiede zwischen verschachtelten Strukturen und Zusammensetzung

  • Verschachtelte Strukturen: Wird verwendet, um Strukturen miteinander zu kombinieren, wobei der Typ eines Feldes in einer Struktur einer anderen Struktur entspricht. Dieser Ansatz wird häufig verwendet, um Datenmodelle mit hierarchischen Beziehungen zu beschreiben.
  • Zusammensetzung: Ermöglicht einer Struktur, Felder aus mehreren anderen Strukturen einzuschließen. Diese Methode wird verwendet, um die Wiederverwendung von Code zu erreichen, sodass eine Struktur komplexere Verhaltensweisen und Attribute aufweisen kann.

Zusammenfassung

Verschachtelte Strukturen und Komposition sind leistungsstarke Funktionen in Go, die bei der Organisation und Verwaltung komplexer Datenstrukturen helfen. Beim Entwerfen von Datenmodellen kann die Verwendung verschachtelter Strukturen und die entsprechende Zusammensetzung Ihren Code klarer und wartbarer machen.

Leere Struktur

Eine leere Struktur in Go ist eine Struktur ohne Felder.

Größe und Speicheradresse

Eine leere Struktur belegt null Byte Speicher. Allerdings kann seine Speicheradresse unter verschiedenen Umständen gleich sein oder auch nicht. Wenn ein Speicher-Escape auftritt, sind die Adressen gleich und zeigen auf runtime.zerobase.

user2 := User{
  Username: "bob",
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Aus der Ausgabe geht hervor, dass die Variablen a, b und Zerobase dieselbe Adresse haben und alle auf die globale Variable runtime.zerobase (runtime/malloc.go) verweisen.

Bezüglich Fluchtszenarien:

  • Variablen c und d entkommen auf den Heap. Ihre Adressen sind 0x590d00 und sie sind im Vergleich gleich (wahr).
  • Variablen e und f haben unterschiedliche Adressen (0xc00008ef47) und sind im Vergleich ungleich (falsch).

Dieses Verhalten ist in Go beabsichtigt. Wenn leere Strukturvariablen nicht maskiert werden, sind ihre Zeiger ungleich. Nach dem Escape werden die Zeiger gleich.

Platzberechnung beim Einbetten leerer Strukturen

Eine leere Struktur selbst belegt keinen Platz, aber wenn sie in eine andere Struktur eingebettet ist, kann sie abhängig von ihrer Position Platz verbrauchen:

  • Wenn es das einzige Feld in der Struktur ist, belegt die Struktur keinen Platz.
  • Wenn es sich um das erste oder mittlere Feld handelt, nimmt es keinen Platz ein.
  • Wenn es das letzte Feld ist, belegt es den gleichen Platz wie das vorherige Feld.
user3 := &User{
  Username: "charlie",
  Email:    "charlie@example.com",
}
Nach dem Login kopieren
Nach dem Login kopieren

Wenn leere Strukturen Elemente von Arrays oder Slices sind:

type User struct {
  Username string
  Email    string
}

func (u User) PrintInfo() {
  fmt.Printf("Username: %s, Email: %s\n", u.Username, u.Email)
}
Nach dem Login kopieren
Nach dem Login kopieren

Anwendungen

Die Eigenschaft der Nullgröße leerer Strukturen ermöglicht deren Verwendung für verschiedene Zwecke ohne zusätzlichen Speicheraufwand.

Verhindern Sie die Initialisierung nicht verschlüsselter Strukturen

type User struct {
  Username    string
  Email       string
  SignInCount int
  IsActive    bool
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Implementieren einer festgelegten Datenstruktur

user1 := User{
  Username:    "alice",
  Email:       "alice@example.com",
  SignInCount: 1,
  IsActive:    true,
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Signalübertragung über Kanäle

Manchmal ist der Inhalt der über einen Kanal übertragenen Daten irrelevant und dient nur als Signal. Leere Strukturen können beispielsweise in Semaphor-Implementierungen verwendet werden:

user2 := User{
  Username: "bob",
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Wir sind Leapcell, Ihre erste Wahl für die Bereitstellung von Go-Projekten in der Cloud.

Deep Dive into Go Struct

Leapcell ist die serverlose Plattform der nächsten Generation für Webhosting, Async-Aufgaben und Redis:

  1. Mehrsprachige Unterstützung
  • Entwickeln Sie mit JavaScript, Python, Go oder Rust.
  1. Stellen Sie unbegrenzt viele Projekte kostenlos bereit
  • Zahlen Sie nur für die Nutzung – keine Anfragen, keine Gebühren.
  1. Unschlagbare Kosteneffizienz
  • Pay-as-you-go ohne Leerlaufgebühren.
  • Beispiel: 25 $ unterstützen 6,94 Millionen Anfragen bei einer durchschnittlichen Antwortzeit von 60 ms.
  1. Optimierte Entwicklererfahrung
  • Intuitive Benutzeroberfläche für mühelose Einrichtung.
  • Vollautomatische CI/CD-Pipelines und GitOps-Integration.
  • Echtzeitmetriken und Protokollierung für umsetzbare Erkenntnisse.
  1. Mühelose Skalierbarkeit und hohe Leistung
  • Automatische Skalierung zur problemlosen Bewältigung hoher Parallelität.
  • Kein Betriebsaufwand – konzentrieren Sie sich nur auf das Bauen.

Erfahren Sie mehr in der Dokumentation!

Folgen Sie uns auf X: @LeapcellHQ


Lesen Sie auf unserem Blog

Das obige ist der detaillierte Inhalt vonTauchen Sie tief in Go Struct ein. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage