Wikipedia · einfach zusammengefasst · Stand
Go (Programmiersprache)
Go (auch Golang) ist eine kompilierbare Programmiersprache, die Nebenläufigkeit und automatische Speicherbereinigung unterstützt. Entwickelt wurde Go von …
Inhalt6 Abschnitte
Grundidee und Zweck
Go, auch Golang genannt, ist eine kompilierbare Programmiersprache mit starker, statischer Typisierung, automatischer Speicherbereinigung und eingebauter Unterstützung für Nebenläufigkeit. Sie wurde bei Google von Robert Griesemer, Rob Pike und Ken Thompson entworfen. Go erschien 2009; die erste stabile Version wurde 2012 veröffentlicht. Zu den Paradigmen gehören nebenläufige, imperative, strukturierte, modulare, objektorientierte und generische Programmierung.
Go wurde entwickelt, um Probleme von C, C++, Java und ähnlichen Sprachen zu verringern. Im Mittelpunkt standen skalierbare Netzwerkdienste, Cluster- und Cloud Computing, große Codebasen und große Entwicklerteams. Go besitzt deutlich weniger Schlüsselwörter als Sprachen der C-Familie und wurde auf schnelle Kompilierung ausgelegt. Die Sprache orientiert sich syntaktisch an C, übernimmt aber auch Einflüsse aus Pascal, Modula und insbesondere Oberon. Das Nebenläufigkeitsmodell folgt den Communicating Sequential Processes (CSP) und steht damit in der Tradition von Newsqueak, Alef und Limbo.
Go erlaubt Zeiger, verzichtet aber auf Zeigerarithmetik. Der Quellcode kann durch Pakete modularisiert werden. Go läuft unter anderem auf Linux, macOS, FreeBSD, Windows und Fuchsia; DragonFly BSD, Plan 9, Solaris und z/OS werden experimentell unterstützt. Go steht unter der BSD-Lizenz.
Sprachmerkmale und Aufbau
Go bietet Closures, also Funktionen, die auf ihre umgebende Umgebung zugreifen können, Reflexion, Typsicherheit und automatische Speicherbereinigung. Generische Typen wurden mit Version 1.18 eingeführt. Unicode wird als UTF-8 unterstützt: sowohl Zeichenketten als auch Bezeichner im Quelltext dürfen Unicode-Buchstaben und -Ziffern enthalten. Deshalb ist beispielsweise Δt = t2 - t1 als Bezeichnerausdruck möglich.
Objektorientierte Programmierung ist vorhanden, aber nicht klassenbasiert. Klassen und Klassenvererbung gibt es bewusst nicht. Datentypen können Methoden besitzen. Polymorphie, also die Verwendung unterschiedlicher konkreter Typen über eine gemeinsame Schnittstelle, wird durch Interfaces erreicht. Die Zuordnung eines Datentyps zu einem Interface erfolgt implizit beim Kompilieren, wenn der Datentyp die erforderlichen Methoden besitzt. Dadurch soll eine lose Kopplung entstehen.
Anstelle von Vererbung und Typ-Hierarchien verwendet Go Komposition. Beim sogenannten Embedding (Einbettung), einer Form von Mixins, kann eine Datenstruktur andere Datentypen einbetten und dadurch deren Methoden und Datenfelder erhalten.
Wichtige Syntaxregeln
Die Syntax ähnelt im Wesentlichen C. Anweisungen müssen jedoch nicht mit einem Semikolon abgeschlossen werden. Der Datentyp steht bei Deklarationen hinter dem Bezeichner, was insbesondere die Deklaration von Funktionstypen vereinfacht. Code-Blöcke werden mit geschweiften Klammern abgegrenzt. Bedingungen in if-, for- oder switch-Konstruktionen stehen anders als in vielen anderen Sprachen nicht in Klammern.
Neben = als Zuweisungsoperator gibt es :=. Dieser Operator verbindet Deklaration, Typinferenz und Zuweisung. Eine Variable erhält also einen vom Compiler ermittelten Typ, wenn dieser aus dem zugewiesenen Wert hervorgeht. Go besitzt 25 Schlüsselwörter und damit weniger als ANSI C.
Mehrzeilige Kommentare werden mit /* und */ geschrieben; // leitet einen Kommentar bis zum Zeilenende ein. Jede Quelldatei gehört genau einem Paket an, das am Anfang mit package angegeben wird. Funktionen werden mit func eingeleitet. Die Funktion main im Paket main ist der Einsprungpunkt eines Programms. Funktionen können mehrere Werte zurückgeben. Häufig wird als letzter Rückgabewert mitgeteilt, ob ein Funktionsaufruf erfolgreich war, und dieser Status wird unmittelbar mit einer Bedingung geprüft.
Jede Variable besitzt einen festgelegten Typ und muss verwendet werden. Die Ausnahme ist der Blank Identifier _, der als anonymer Platzhalter eine Zuweisung ignoriert.
Beispiele, Typen und Zeiger
Ein minimales Go-Programm lautet sinngemäß: package main, import "fmt" und eine main-Funktion mit fmt.Println("Hallo Welt"). Es gibt den String Hallo Welt aus.
Ein weiteres Beispiel berechnet Pi näherungsweise mit der Leibniz-Reihe. Dafür werden 5000 Go-Routinen gestartet. Jede berechnet einen Summanden und schreibt ihn in den Kanal ch; anschließend werden die Ergebnisse aus dem Kanal addiert und mit 4 multipliziert, weil die Leibniz-Reihe Pi/4 berechnet. Als Ausgabe erscheint 3.141392653591793. Die Abweichung zur eigentlichen Kreiszahl ab der vierten Nachkommastelle wird vor allem mit der langsamen Konvergenz der Leibniz-Reihe erklärt.
Im Gegensatz zu C müssen unterschiedliche Typen ausdrücklich konvertiert werden. Ein int-Wert kann nicht ohne Konvertierung in einer float-Variablen gespeichert werden. Beispielsweise wird aus int durch float64(i) ein float64-Wert und durch uint(f) ein uint-Wert. Bei 8-Bit-Ganzzahlen reicht uint8 von 0 bis 255, int8 von −128 bis 127. Die strikte Typisierung erleichtert das Erkennen schwer auffindbarer Programmierfehler. Wird bei einer Deklaration direkt ein Wert zugewiesen, kann der Typ entfallen: i := 100. Diese Kurzform ist nur innerhalb von Funktionen möglich.
Go verwendet Zeiger. Ein Zeiger enthält die Adresse eines Speicherbereichs. Mit &n wird die Adresse der Variablen n ermittelt; der Typ eines Zeigers wird mit einem vorangestellten * geschrieben, beispielsweise *int. Mit *p wird der Wert an der in p gespeicherten Adresse gelesen. Ein Zeiger ohne Adresse hat den Wert nil und kann mit p == nil oder p != nil geprüft werden. Zeiger ermöglichen unter anderem die Übergabe von Werten an Funktionen, etwa beim Tausch zweier Integer-Variablen. Zusammengefasst liefert & eine Adresse, während * den dort gespeicherten Wert ermittelt. Zeigerarithmetik ist in Go nicht vorgesehen.
Nebenläufigkeit und Kanäle
Nebenläufigkeit wird in Go durch Go-Routinen und Kanäle (Channels) unterstützt. Go-Routinen sind leichtgewichtige, nebenläufig ausgeführte Abläufe. Kanäle ermöglichen ihre synchrone oder asynchrone Kommunikation und übertragen jeweils Daten eines festen Typs. Ein Kanal kann durch make(chan typ) als synchroner Kanal oder durch make(chan typ, größe) als gepufferter, asynchroner Kanal erzeugt werden, wenn größe > 0 ist. Auch Kanäle, die selbst Kanäle übertragen, sind möglich.
Bei einem synchronen Kanal blockiert das Lesen, bis eine andere Go-Routine schreibt, und das Schreiben, bis eine andere Routine liest. Bei einem asynchronen Kanal tritt die Blockierung erst auf, wenn der Kanal leer oder sein Puffer voll ist. Die Anzahl der Go-Routinen, die einen Kanal lesen oder beschreiben, ist nicht begrenzt. Daten werden mit kanal <- Wert geschrieben und mit variable = <-kanal gelesen. Mit for kann ein Kanal bis zu seiner Schließung gelesen werden. Das select-Konstrukt ermöglicht das gleichzeitige Warten auf mehrere Kanäle; ausgeführt wird der erste nicht mehr blockierte case, bei mehreren möglichen Fällen erfolgt eine pseudozufällige Auswahl.
Trotz dieser Synchronisationsmechanismen kann ein Deadlock auftreten. Dann beendet die Go-Laufzeitumgebung das Programm. In einem Beispiel empfängt die Go-Routine zehnMal einen String, schreibt ihn zehnmal über denselben synchronen Kanal zurück und schließt den Kanal anschließend. main startet diese Routine, sendet Hallo und gibt die empfangenen zehn Strings mit for s := range kanal aus. Das Schließen ist notwendig, damit die Schleife endet.
Compiler, Werkzeug und Entwicklung
Wichtige Implementierungen sind Gc und gccgo. Gc ist der offizielle Go-Compiler. Er wurde zunächst von Ken Thompson in C geschrieben, beruhte auf der Plan-9-Toolchain und wurde mit Version 1.5 nach Go übersetzt; seitdem ist er self-hosting. Früher gab es je nach Zielarchitektur verschiedene Befehle, etwa 8 g für x86, 6 g für x86_64 und 5 g für ARM. Seit Version 1.5 werden sie durch go tool compile zusammengefasst; die Zielarchitektur wird über GOARCH gewählt.
gccgo ist ein von Ian Taylor entwickeltes Go-Frontend für die GNU Compiler Collection. Das in C++ geschriebene Frontend verwendet rekursiven Abstieg zum Parsen. Die weiteren Backend-Schritte übernimmt GCC. Dadurch ist die Kompilierzeit höher als beim Gc-Compiler, der erzeugte Code kann jedoch effizienter sein. Beide Compiler verwenden eine parallele Mark-and-Sweep-Speicherbereinigung.
Das Kommandozeilenwerkzeug go dient als Fassade für mehrere Entwicklungsaufgaben: go get installiert Pakete aus Quelltext-Repositories wie GitHub oder Google Code, go fmt formatiert Quelltext automatisch, go test führt Tests aus, go doc erzeugt Dokumentation aus Kommentaren und go build kompiliert ein Projekt. Bei der empfohlenen Verzeichnisstruktur sind dafür keine Makefiles nötig.
Die Entwurfsphase begann am 21. September 2007 als 20-Prozent-Projekt. Am 30. Oktober 2009 wurde Go in einem Google TechTalk präsentiert; am 10. November 2009 erfolgte die angekündigte Veröffentlichung als freie Software. Version 1 wurde am 28. März 2012 freigegeben. Seitdem gelten Sprachspezifikation und Standardbibliothek als stabil und sollen innerhalb der 1.x-Serie auf Quelltextebene abwärtskompatibel bleiben. Go 1.1 erschien am 14. Mai 2013, Go 1.2 bis Go 1.10 folgten jeweils sechs Monate später. Die erste GopherCon fand vom 24. bis 26. April 2014 in Denver statt.
Das Maskottchen ist eine von Renée French entworfene Taschenratte (Gopher). Logo und Maskottchen stehen unter der Creative-Commons-Attribution-3.0-Lizenz. Als aktuelle Version ist im Artikel 1.27.1 vom 1. September 2026 angegeben.
Lernvideos zu Go (Programmiersprache)
10:24
Let Go and Trust God
Be Still Biblical Meditations · 6,6 Mio. Aufrufe
9:09
Woyzeck to go (Büchner in 9 Minuten)
Sommers Weltliteratur to go · 1 Mio. Aufrufe
12:15
Der Besuch der alten Dame to go (Dürrenmatt in 12 Minuten)
Sommers Weltliteratur to go · 627.445 Aufrufe
11:05
Corpus Delicti to go (Juli Zeh in 11 Minuten)
Sommers Weltliteratur to go · 624.993 Aufrufe