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 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 }
Strukturen können auf verschiedene Arten initialisiert werden.
user1 := User{ Username: "alice", Email: "alice@example.com", SignInCount: 1, IsActive: true, }
Wenn einige Felder nicht angegeben sind, werden sie auf ihre Nullwerte für die jeweiligen Typen initialisiert.
user2 := User{ Username: "bob", }
In diesem Beispiel wird Email mit einer leeren Zeichenfolge ("") initialisiert, SignInCount auf 0 und IsActive auf false.
Eine Struktur kann auch mit einem Zeiger initialisiert werden.
user3 := &User{ Username: "charlie", Email: "charlie@example.com", }
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 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.
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) }
Ein Zeigerempfänger ermöglicht der Methode, die ursprünglichen Strukturfelder direkt zu ändern.
func (u *User) UpdateEmail(newEmail string) { u.Email = newEmail }
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.
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() }
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.
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.
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.
Beispiel:
type User struct { Username string Email string SignInCount int IsActive bool }
Ausgabe: 12
Analyse:
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, }
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.
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 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 }
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, }
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.
Eine leere Struktur in Go ist eine Struktur ohne Felder.
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", }
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:
Dieses Verhalten ist in Go beabsichtigt. Wenn leere Strukturvariablen nicht maskiert werden, sind ihre Zeiger ungleich. Nach dem Escape werden die Zeiger gleich.
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:
user3 := &User{ Username: "charlie", Email: "charlie@example.com", }
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) }
Die Eigenschaft der Nullgröße leerer Strukturen ermöglicht deren Verwendung für verschiedene Zwecke ohne zusätzlichen Speicheraufwand.
type User struct { Username string Email string SignInCount int IsActive bool }
user1 := User{ Username: "alice", Email: "alice@example.com", SignInCount: 1, IsActive: true, }
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", }
Wir sind Leapcell, Ihre erste Wahl für die Bereitstellung von Go-Projekten in der Cloud.
Leapcell ist die serverlose Plattform der nächsten Generation für Webhosting, Async-Aufgaben und Redis:
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!