Das gleichnamige asiatische Brettspiel ist unter Spiele/Go zu finden.
Go ist eine seit 2009 von Google entwickelte Programmiersprache mit Ähnlichkeiten zu C++, Java und Erlang. Sie ist kompilierbar, nebenläufig und besitzt eine automatische Speicherbereinigung. Zur Zeit wird Go für Linux, Mac OS X und experimentell für Windows angeboten, es ist also weitestgehend plattformunabhängig. Durch die umfangreiche Standardbibliothek werden von Haus aus z.B. Netzwerkprogrammierung (TCP, HTTP), formatierte Textein/-ausgabe, Systemaufrufe etc. unterstützt.
Ende März 2012 wurde die Version 1.0 veröffentlicht
. Go befand sich bis dahin noch in Entwicklung, was es weiterhin schwierig macht, Tutorials oder gar Bücher zum Thema zu finden. Hilfe bieten hier die Homepage der Sprache, ein Tutorial von Miek Gieben und die Mailinglist "go-nuts". Zusätzlich liefert die vor kurzem erschienene interaktive Go-Tour eine gute Einführung (siehe Links).
Ein Aspekt, der Go von "älteren" Programmiersprachen wie C++ abhebt, ist die Verwendung des gesamten UTF-8 Zeichensatzes im Quelltext. Dies gilt sowohl für Variablennamen als auch in der Textausgabe. Somit bleiben z.B. Probleme mit Umlauten aus. Weiteres zu den Besonderheiten unter Syntax.
Die Programmiersprache ist nicht in den offiziellen Paketquellen enthalten. Man kann aber auf ein "Personal Package Archiv" (PPA) [1] ausweichen.
Adresszeile zum Hinzufügen des PPAs:
ppa:gophers/go
Zusätzliche Fremdquellen können das System gefährden.
Weitere Informationen bietet die
PPA-Beschreibung vom Benutzer/Team gophers.
Damit Pakete aus dem PPA genutzt werden können, müssen die Paketquellen neu eingelesen werden.
Nach dem Aktualisieren der Paketquellen kann das folgende Paket installiert [2] werden:
golang (ppa)
Darin enthalten sind Compiler, Linker und verschiedene Werkzeuge zur Formatierung des Quellcodes oder zum Nachinstallieren von Bibliotheken.
Wer Go ähnlich wie Python ausprobieren möchte, kann dies im Go Playground
tun. Allerdings werden hier nicht alle Bibliotheken und Funktionen unterstützt.
Wer sich etwas mehr Komfort bei der Quellcode-Erstellung wünscht, aber nicht gleich auf eine Entwicklungsumgebung umsteigen möchte, kann sich Gedit etwas verschönern. Gedit unterstützt zwar von Haus aus viele Sprachen, Go ist allerdings noch nicht dabei. Eine Anleitung zum nachträglichen Hinzufügen von Syntax-Highlighting ist hier
zu finden.
Sucht man eine vollständige Entwicklungsumgebung, sollte man sich GolangIDE
ansehen, eine auf Go spezialisierte Version der Entwicklungsumgebung LiteIDE. Sie unterstützt einiges, was den Programmieralltag erleichtert:
Syntax-Highlighting, konfigurierbar
Projektmanagement
Gut integriertes Debugging
Automatische Formatierung des Quellcodes mit gofmt
Baumansicht von Funktionen und Variablen
Übersichtliche Bedienung et cetera.
Zur Zeit wird sie auf der Projektseite für Linux, Windows und Mac OS X als Download
angeboten.
Eventuell bekommt man beim Kompilieren eines Programms eine Fehlermeldung, da LiteIDE den Compiler im falschen Pfad sucht oder Standardbibliotheken wie "fmt" nicht findet. In dem Fall muss man im LiteIDE-Ordner unter /usr/share/liteide/environment/ die Datei linux32.env oder je nach Architektur linux64.env editieren und die enthaltenen Variablen anpassen:
1 2 3 4 | GOROOT=/usr/lib/go GOBIN=/usr/bin GOARCH=amd64 #(oder GOARCH=386 bei 32-Bit Systemen) GOOS=linux |
Nach dem Speichern muss man in LiteIDE in der Dropdown-Liste der oberen Toolbar die editierte Datei auswählen, dann sollte es funktionieren!
Das Paket golang enthält viele Programme zur Go-Programmierung. Hier eine Auswahl der wichtigsten:
| Tools | |
| Befehl | Bedeutung |
6g / 8g | Compiler, Übersicht der Argumente in der Dokumentation oder bei Eingabe des Befehls ohne Parameter |
6l / 8l | Linker, Übersicht der Argumente s.o. |
gofmt | Formatiert Quellcode nach dem festgelegten Schema. |
cgo | Compiler für Go-Programme, die C-Code beinhalten |
goinstall | Befehl für die Installation von zusätzlichen Bibliotheken von github etc., z.B. für Audio oder Grafik. |
gomake | Auf Go-Makefiles spezialisierte Variante von GNU-Make |
Für den Anfang wird wie gewöhnlich nichts als der eben installierte Compiler und ein Texteditor (zum Beispiel Gedit) benötigt. Man öffnet diesen und legt die Datei first.go an:
1 2 3 4 5 6 7 8 9 | //Datei first.go /* erstes Go-Programm */ package main import "fmt" func main () { fmt.Println("Hallo golang!") fmt.Println("Hallo 世界!"); } |
| Erläuterung | |
| Zeile | Bedeutung |
| 1+2 | Kommentare, wie in C++ oder Java |
| 3 | Name des Pakets des Programms, Standard ist "main" |
| 4 | Das Paket "fmt" aus der Standardbibliothek wird eingebunden. Es stellt formatierte Textein/-ausgabe ähnlich print-/scanf zu Verfügung. |
| 6 | Hauptfunktion des Programms ohne Parameter oder Rückgabewert. Funktionen werden in Go mit dem Schlüsselwort "func" eingeleitet. |
| 7 | Die Funktion "Println" aus dem importierten Paket "fmt" wird per Punktoperator aufgerufen. Als Parameter steht hier der String "Hallo golang!". Möglich sind aber auch Variablen, Objekte oder Funktionen (mit Rückgabewert). |
| 8 | Erneut die funktion "Println", diesmal mit chinesischen Schriftzeichen. Wie bereits erwähnt, kann der gesamte UTF-8 Zeichensatz verwendet werden. Dieser Funktionsaufruf wird mit einem Semikolon abgeschlossen. Dies ist zwar wie oben nicht erforderlich, aber trotzdem möglich. |
| 9 | Die main-Funktion wird geschlossen. |
Nun wird der Quelltext kompiliert:
6g -o /home/benutzer/Dokumente/first.6 /home/benutzer/Dokumente/first.go
und gelinkt:
6l -o /home/benutzer/Dokumente/first /home/benutzer/Dokumente/first.6
Der Compiler erstellt aus dem Quelltext first.go zunächst die Datei first.6, die dann gelinkt und somit zur ausführbaren Datei wird.
Der Compilername 6g setzt sich zusammen aus der x64-Architektur und "Go". Dem entsprechend muss auf 32-Bit Systemen "8g" (x86-Architektur) verwendet werden. Das Gleiche gilt für den Linker (6l / 8l).
Startet man das Programm sieht die Ausgabe so aus:
benutzer@pc-name:~$ /home/benutzer/Dokumente/first Hallo golang! Hallo 世界!
Go verfügt gegenüber altbewährten Programmiersprachen über einige interessante Neuerungen, oder kombiniert zumindest Vorteile einzelner Sprachen miteinander.
In Go gibt es verschiedene Möglichkeiten, Variablen zu deklarieren und zu initialisieren:
1 2 3 4 5 6 | //Beispiel 1 var txt1 string //Deklaration txt1 = "zugewiesen" //Initialisierung //Beispiel 2 txt2 := txt1 |
Hier wird zunächst die Variable "txt1" mit dem Schlüsselwort "var" (bekannt aus JavaScript) vom Typ "string" deklariert. Auffällig ist, dass im Gegensatz zu C/C++/etc. der Typ der Variable hinter dem Namen steht. Im nächsten Schritt wird dann der Variable ein String zugewiesen.
Das zweite Beispiel arbeitet mit dem Zuweisungsoperator ":=". Dieser kombiniert die beschriebenen Schritte: er legt eine Variable "txt2" an und weist ihr den Wert von "txt1" zu. Hier muss kein Typ angegeben werden, da der Compiler diesen automatisch aus dem zugewiesenen Wert (hier string) erkennt.
Funktionen können in Go sehr umfangreich definiert werden:
1 2 3 | func (t typ) funktionsname(q int) (r,s int) { return 0,0 } |
Wie bereits erwähnt, wird jede Funktion mit dem Schlüsselwort "func" eingeleitet. Im folgenden wird die Syntax dieses Prototyps erläutert:
| Erläuterung | ||
| Teil | Optional | Beschreibung |
(t typ) | ja | Funktionen können auf einen bestimmten Typen festgelegt werden, z.B. nur Strings / TCP-Connections etc. |
funktionsname | nein | Der Name der Funktion, über den sie später aufgerufen wird. Muss groß_ geschrieben werden, wenn die Funktion in anderen Bibliotheken nutzbar sein soll! |
(q int) | jein; () erforderlich | Deklaration der Parameter, die der Funktion übergeben werden können |
(r,s int) | ja | Deklaration der Rückgabewerte der Funktion. Richtig, in Go können Funktionen mehrere Werte zurückgeben! Dazu später mehr. |
return 0,0 | nein | Return-statement, beendet die Funktion und gibt den/die Wert/Werte zurück |
1 2 3 | func merge(a,b string) string { return a+b, a, b } |
Die Funktion "merge" akzeptiert zwei Strings als Parameter. Diese werden dann zusammengefügt und jeweils einzeln zurückgegeben. Die Funktion ist also vom Typ string und hat 3 Rückgabewerte.
Nun gibt es verschiedene Möglichkeiten, diese Funktion zu nutzen:
1 2 3 4 5 | //Möglichkeit 1 add, a, b := merge("zusammen", "führen") fmt.Println(add) fmt.Println(a) fmt.Println(b) |
Hier werden die 3 neuen Variablen add, a und b per Zuweisungsoperator deklariert und mit den 3 Rückgabewerten der Funktion "merge" initialisiert. Die Ausgabe wäre dem entsprechend:
zusammenführen zusammen führen
Nun kann es z.B. bei Funktionen der Standardbibliothek vorkommen, das diese mehrere Werte zurückgeben, man allerdings nur mit einem arbeiten möchte. Würde man diese Werte allerdings beim Aufruf einfach ignorieren, gäbe es einen Compiler-Fehler. Abhilfe schafft hier die pseudo-Variable "_" (als Beispiel dient hier die oben definierte Funktion "merge"):
1 2 3 | //Möglichkeit 2 add, _, _ := merge("zusammen", "führen") fmt.Println(add) |
Ausgegeben wird hier nur noch:
zusammenführen
Jetzt wird nur noch das zusammengeführte Ergebnis der Variablen "add" zugewiesen, die beiden anderen Werte werden den Pseudovariablen. Somit werden sie respektiert, aber direkt verworfen. Sinn ergibt dies zum Beispiel, wenn man bei einem Schreibvorgang nicht an der Anzahl der geschriebenen Bits interessiert ist.
1 2 3 | func printStuff() { fmt.Println("Some stuff....") } |
Natürlich geht es auch ganz rudimentär: Diese Funktion braucht keine Parameter und gibt keine Werte zurück.
Die Funktions-Syntax zu kennen, ist wichtig, um die Paketdokumentation
zu verstehen!
Ein weiteres Schmankerl der neuen Programmiersprache ist die sogenannte "Nebenläufigkeit". Dieses von Erlang inspirierte Feature ermöglicht es, auf vergleichsweise einfache Weise parallel zu programmieren, eine Art Thread-Programmierung:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package main import ( "fmt" "time" ) func wake(zeit int, grund string) { time.Sleep(zeit*1e9) fmt.Println("Zeit abgelaufen: ", grund) } func main() { go wake(180, "Tee!") go wake(200, "Wichtiger Termin!") time.Sleep(500e9) } |
Zuerst wird die Funktion "wake" definiert. Sie akzeptiert als Parameter eine Zeit (in Sekunden) und einen Grund als String. Wird sie aufgerufen, wartet sie die übergebene Zeit und gibt dann eine Meldung mit dem Grund des Aufrufs aus.
Das Entscheidende kommt erst in der main-Funktion: Die Funktion "wake" wird hier mit dem Schlüsselwort go aufgerufen. Ohne go würde die zweite wake-Funktion erst aufgerufen werden, wenn die erste beendet wird, also nach 3 Minuten. Ein go startet die Funktionen jedoch nebenläufig, also parallel. So wird man nach 3 Minuten an den Tee, und 20 Sekunden später an den wichtigen Termin erinnert.
Im Gegensatz zu diesem Beispiel ist die einfache Nebenläufigkeit z.B. bei Spielen erforderlich, wo gleichzeitig die Eingaben vom Benutzer interpretiert werden, und im Hintergrund z.B. Timer laufen.
Die Sleep-Funktion danach ist hier erforderlich, da sich sonst nach den Funktionsaufrufen das Hauptprogramm und somit auch die sog. Go-Routinen beenden würden. Professionell ist das nicht, da man meistens nicht weiß, wie lange man warten muss. Dann würde man die Routinen entweder zu früh abwürgen oder unnötig Rechenzeit verschwenden.
Golang-nuts Mailinglist
- Googlemail-Adresse erforderlich
Go Presentation
Go-Präsentation von Andrew Gerrand
Diese Revision wurde am 29. März 2012 15:11 von aasche erstellt.
Die folgenden Schlagworte wurden dem Artikel zugewiesen:
Programmierung
2004 – 2012 ubuntuusers.de • Einige Rechte vorbehalten