Skip to content

Datenstrukturen

Obwohl Go eine einfache Syntax hat, verfügt es über mehrere leistungsstarke Kern-Datenstrukturen. Diese Datenstrukturen sind die grundlegenden Bausteine von Go-Programmen. Ein tiefes Verständnis ihrer Implementierungsprinzipien hilft dabei, effizienteren Code zu schreiben. Dieser Artikel stellt die am häufigsten verwendeten Datenstrukturen in Go und deren zugrundeliegende Implementierungen vor.

Grundlegende Datenstrukturen

Slice

Ein Slice ist die am häufigsten verwendete Datenstruktur in Go und eine Abstraktion und Kapselung von Arrays. Hauptmerkmale:

  • Dynamische Größe: Die Länge eines Slices kann dynamisch wachsen
  • Referenzsemantik: Beim Übergeben eines Slices wird nur die Struktur kopiert, nicht das zugrundeliegende Array
  • Erweiterungsmechanismus: Wenn die Kapazität nicht ausreicht, wird automatisch erweitert

Ein Slice wird zur Laufzeit durch die slice-Struktur repräsentiert, die einen Zeiger auf das zugrundeliegende Array, die Länge und die Kapazität enthält.

String

Ein String ist einer der grundlegendsten Datentypen in Go. Hauptmerkmale:

  • Unveränderlichkeit: Ein String kann nach der Erstellung nicht mehr geändert werden
  • UTF-8-Kodierung: Normalerweise repräsentiert er UTF-8-kodierten Text
  • Nullwert-Sicherheit: Der Nullwert eines Strings ist der leere String "", nicht nil

Ein String wird zur Laufzeit durch die stringStruct-Struktur repräsentiert, die einen Zeiger auf ein Byte-Array und die Länge enthält.

Container-Datenstrukturen

Map

Eine Map ist ein in Go eingebauter Schlüssel-Wert-Container, der auf Hashtabellen implementiert ist. Hauptmerkmale:

  • Hashtabellen-Implementierung: Schnelle Lokalisierung von Elementen durch Hash-Funktionen
  • Automatische Erweiterung: Automatische Erweiterung, wenn der Lastfaktor zu hoch wird
  • Nicht nebenläufigkeitssicher: Nebenläufiges Lesen und Schreiben erfordert zusätzliche Synchronisationsmechanismen

Eine Map wird zur Laufzeit durch die hmap-Struktur repräsentiert, die ein Bucket-Array, einen Hash-Seed und eine Elementanzahl enthält.

Syncmap

sync.Map ist eine nebenläufigkeitssichere Map aus der Standardbibliothek, geeignet für Szenarien mit vielen Lese- und wenigen Schreiboperationen. Hauptmerkmale:

  • Lese-Schreib-Trennung: Verwendet zwei Maps (read und dirty) zur Implementierung der Lese-Schreib-Trennung
  • Atomare Operationen: Die read-Map verwendet atomare Operationen ohne Sperren
  • Progressive Migration: Wenn die Miss-Anzahl einen Schwellenwert erreicht, wird dirty zu read befördert

sync.Map bietet durch Raum-Zeit-Tausch in bestimmten Szenarien bessere Leistung als map + mutex.

Nebenläufigkeits-Datenstrukturen

Channel

Ein Channel ist ein typischer Vertreter der CSP-Philosophie in Go und wird zur Kommunikation zwischen Goroutinen verwendet. Hauptmerkmale:

  • Goroutinen-Kommunikation: Datenübertragung zwischen Goroutinen durch Channels
  • Synchronisationsmechanismus: Ungepufferte Channels können zur Goroutinen-Synchronisation verwendet werden
  • Gesperrte Warteschlange: Die zugrundeliegende Implementierung ist eine gesperrte Ringwarteschlange

Ein Channel wird zur Laufzeit durch die hchan-Struktur repräsentiert, die einen Ringpuffer und Warteschlangen enthält.

Select-Multiplexing

select kann gleichzeitig den Status mehrerer Channels überwachen und Multiplexing implementieren. Hauptmerkmale:

  • Nicht-blockierend: Kann nicht-blockierend prüfen, ob mehrere Channels verfügbar sind
  • Zufällige Auswahl: Wenn mehrere Channels gleichzeitig verfügbar sind, wird zufällig einer ausgewählt
  • Timeout-Kontrolle: Zusammen mit time.After kann ein Timeout-Mechanismus implementiert werden

select wird zur Laufzeit durch die scase-Struktur für jeden Zweig repräsentiert und überprüft den Channel-Status durch einen Polling-Mechanismus.

Lernempfehlungen

Es wird empfohlen, in folgender Reihenfolge zu lernen:

  1. Zuerst Slice und String lernen, um die grundlegenden Datenstrukturen zu verstehen
  2. Dann Map lernen, um die Implementierung von Hashtabellen zu verstehen
  3. Anschließend Channel lernen, um den Goroutinen-Kommunikationsmechanismus zu verstehen
  4. Dann Select-Multiplexing lernen, um Multiplexing-Techniken zu beherrschen
  5. Schließlich Syncmap lernen, um die Implementierung nebenläufigkeitssicherer Datenstrukturen zu verstehen

Golang by www.golangdev.cn edit