Go programmieren für Dummies 3527719466, 9783527719464

Go ist eine der neueren Programmiersprachen, die Softwareentwickler in ihrer Werkzeugkiste haben sollten. Die Sprache wu

145 11 18MB

German Pages 320 [422] Year 2022

Report DMCA / Copyright

DOWNLOAD PDF FILE

Table of contents :
Titelblatt
Impressum
Über den Autor
Einleitung
Über dieses Buch
Törichte Annahmen über den Leser
Symbole, die in diesem Buch verwendet werden
Weitere Ressourcen
Wie es weitergeht
Teil I: Erste Schritte mit Go
Kapitel 1: Auf die Plätze, fertig, Go!
Mit Go zum beruflichen Erfolg
Installieren von Go auf Ihrem Computer
Verwenden einer integrierten Entwicklungsumgebung (IDE) mit Go
Ihr erstes Go-Programm
Vergleich von Go mit anderen Programmiersprachen
Kapitel 2: Datentypen
Deklarieren von Variablen
Deklarieren von Konstanten
Entfernen von ungenutzten Variablen
Verwenden von Strings
Konvertieren von Datentypen
Kapitel 3: Entscheidungsfindung
Entscheidungen mittels if/else
Verwenden der switch-Anweisung bei mehreren Bedingungen
Kapitel 4: Noch einmal und noch einmal: Programmschleifen
Durchlaufen von Schleifen mit der for-Anweisung
Iteration über einen Wertebereich
Verwenden von Sprungmarken mit der for-Schleife
Kapitel 5: Übersichtlicher Code dank Funktionen
Definieren einer Funktion
Verwenden von anonymen Funktionen
Teil II: Datenstrukturen
Kapitel 6: Datensammlungen in Arrays und Slices
Allzeit bereit mit Arrays
Strukturell flexibel mit Slices
Slicing von Wertebereichen
Kapitel 7: Logische Datenorganisation mit Structs
Definieren von Structs für Sammlungen aus Datenelementen
Erzeugen von Structs
Kopieren von Structs
Definieren von Methoden in Structs
Vergleichen von Structs
Kapitel 8: Beziehungen und Maps
Erstellen von Maps in Go
Verwenden von Structs und Maps in Go
Kapitel 9: Datencodierung mit JSON
Grundlagen von JSON
Decodieren des JSON-Formats
Codieren des JSON-Formats
Kapitel 10: Methodensignaturen mit Interfaces
Arbeiten mit Interfaces in Go
Wozu sind Interfaces gut?
Teil III: Multitasking in Go
Kapitel 11: Threading mit Goroutinen
Das Grundprinzip von Goroutinen
Verwenden von Goroutinen mit gemeinsamen Ressourcen
Synchronisieren von Goroutinen
Kapitel 12: Kommunikation zwischen Goroutinen mit Kanälen
Das Grundprinzip von Kanälen
Iterieren über Kanäle
Asynchrones Warten auf Kanäle
Verwenden von gepufferten Kanälen
Teil IV: Übersichtlicher Code
Kapitel 13: Pakete in Go
Arbeiten mit Paketen
Verwenden von Drittanbieter-Paketen
Kapitel 14: Module für Paketgruppen
Erstellen eines Moduls
Testen und Zusammensetzen eines Moduls
Veröffentlichen eines Moduls auf GitHub
Teil V: Go in Aktion
Kapitel 15: Verwendung von Web-APIs mit Go
Funktionsprinzip von Web-APIs
Abrufen der Daten von Webservices in Go
Kapitel 16: Eigene Webservices mit REST-APIs
Erstellen von Webservices mit REST-APIs
Erstellen einer REST-API in Go
Kapitel 17: Verwendung von Datenbanken
Einrichten eines MySQL-Datenbankservers
Herstellen der Verbindung zur MySQL-Datenbank in Go
Teil VI: Der Top-Ten-Teil
Kapitel 18: Zehn praktische Go-Pakete zum Erstellen von Anwendungen
color
now
go-pushbullet
goid
json2go
gojq
turtle
go-http-client
notify
gosx-notifier
Kapitel 19: Zehn nützliche Go-Ressourcen
Die offizielle Go-Website
Go by Example
Go-Tour
Häufig gestellte Fragen zu Go
Go Playground
Go Bootcamp
Effective Go
Gophercises
Tutorialspoint
Stack Overflow
Abbildungsverzeichnis
Stichwortverzeichnis
End User License Agreement
Recommend Papers

Go programmieren für Dummies
 3527719466, 9783527719464

  • 0 0 0
  • Like this paper and download? You can publish your own PDF file online for free in a few minutes! Sign Up
File loading please wait...
Citation preview

Go programmieren für Dummies

Schummelseite ERSTE SCHRITTE MIT GO IM WEB Es gibt Situationen, in denen Go nicht auf dem lokalen Computer installiert werden kann. Vielleicht sitzen Sie ja an einem Computer Ihres Arbeitgebers und haben nur eingeschränkte Benutzerrechte. Oder Ihnen steht gerade gar kein eigener Computer zur Verfügung. Was auch immer der Grund ist: Sie brauchen nicht zu verzagen, denn es gibt verschiedene Alternativen im Internet und integrierte Entwicklungsumgebungen (IDEs), mit denen Sie Ihre ersten eigenen Go-Programme testen können. Die folgenden drei sind ziemlich cool: Go Playground (https://play.golang.org/): Der Go Playground ist ein Webservice, der über die Server der offiziellen Go-Website betrieben wird. Er bietet eine Testumgebung mit einem Großteil der Standardbibliothek, sodass Sie Ihren Programmcode online ausprobieren können, ohne Go installieren zu müssen. Eine besonders gern genutzte Funktion ist die Codeweitergabe. Durch Klick auf die Schaltfläche SHARE wird Ihrem Code eine feste URL zugeteilt. Auf diese Weise können Sie zum Beispiel Programmausschnitte an Mitglieder Ihres Entwicklungsteams weiterleiten oder als Lehrkraft im Rahmen von Programmierkursen Beispielcode für die Teilnehmenden bereitstellen. Der Code lässt sich in der Testumgebung bearbeiten, kompilieren und ausführen. JDoodle Online GO Lang IDE (https://www.jdoodle.com/execute-go-online): Eine weitere IDE im Web für Go ist die JDoodle Online GO Lang IDE. Wenngleich der Go Playground sehr einfach zu benutzen ist, kann Ihr dort eingegebenes Programm nur über die Ausgabekonsole mit dem Rest der Welt interagieren. Benötigt Ihr Programm eine Benutzereingabe (zum Beispiel für die Funktion fmt.Scanln()), haben Sie also Pech. Hier kommt die JDoodle Online GO Lang IDE ins Spiel. Mit dieser Umgebung können Sie ein interaktives Go-Programm erstellen, das sowohl Eingaben entgegennehmen als auch Ausgaben zurückliefern kann. Obendrein haben Sie die Wahl, ob Ihr Programm in der Cloud oder als lokale Kopie auf Ihrem Computer gespeichert werden soll. Bei Bedarf können Sie auch eine lokale Datei in die JDoodle Online GO Lang IDE hochladen. Die vielleicht interessanteste Funktion der JDoodle Online GO Lang IDE ist die Option zur kollaborativen Programmierung. Dadurch können mehrere Personen gleichzeitig ein Programm bearbeiten – ideal für Onlineschulungen.

Repl.it – Compiler und Interpreter für Go (https://repl.it/languages/go): Der Compiler und Interpreter für Go von Repl.it ist online verfügbar und ermöglicht es Ihnen, Dateien und Ordner mit Programmcode hochzuladen. Außerdem gibt es eine interaktive Konsole, über die Ihr Go-Programm Eingaben entgegennimmt und Ausgaben zurückliefert. Eine recht nützliche Funktion der Repl.it-IDE ist zudem ihre Integration mit GitHub zur Versionskontrolle. Auch die interaktive Codeweitergabe wird unterstützt, um besser im Team programmieren zu können.

KONVERTIERUNG VON JSON-DATEN IN EIN GOFORMAT Beim Programmieren wird Ihnen früher oder später das JSON-Datenformat begegnen. Daten, die in dieser JavaScript Object Notation vorliegen, müssen in ein Format überführt werden, das sich in Ihrem Go-Programm leichter verarbeiten lässt. Mit den folgenden Onlinetools können Sie die JSON-Strings direkt in Go-Strukturen konvertieren: JSON-to-Go (https://mholt.github.io/json-to-go) Transform (https://transform.tools/json-to-go) Json2Struct (http://json2struct.mervine.net/)

NUTZUNG VON GOLANG IN DOCKER Wenn Sie Docker verwenden, können Sie Ihre Go-Programme aus einem DockerContainer heraus ausführen. Um ein Go-Beispielprogramm in einem Golang-Docker-Container zu installieren, geben Sie folgenden Befehl im Terminal oder in der Eingabeaufforderung ein:

$ docker run golang go get -v

github.com/golang/example/hello/… Dieser Befehl installiert das Go-Beispielprogramm (https://github.com/golang/example/hello) in einem Golang-Container. Die Ellipse (…) repräsentiert Anweisungen zum Herunterladen, Zusammensetzen und Installieren aller Objekte im Repository (einschließlich Bibliotheken und Binärdateien). Sie haben nun einen Golang-Container, in dem sich das Go-Beispielprogramm befindet. Als Nächstes müssen Sie den Container einem neuen Docker-Image d

d

Si kü fti

Si di

P

füh

ö ht

zuordnen, sodass Sie künftig, wenn Sie dieses Programm ausführen möchten, ganz einfach einen Container aus diesem neuen Image erstellen können. Geben Sie den folgenden Befehl im Terminal oder in der Windows-Eingabeaufforderung ein:

$ docker commit $(docker ps -lq) hellogo Der Befehl docker ps -lq liefert die ID des zuletzt ausgeführten Containers. Dieser Befehl weist den Container, in dem sich das Go-Beispielprogramm befindet, einem neuen Docker-Image namens hellogo zu. Mit dem folgenden Befehl lässt sich dies überprüfen:

$ docker images REPOSITORY hellogo

TAG latest

IMAGE ID 2c1d28ef93cb

CREATED About a minute ago

SIZE

723MB

Führen Sie nun das Go-Beispielprogramm über das neu erstellte hellogo-DockerImage aus:

$ docker run hellogo hello Hello, Go examples! Wenn Sie diese Ausgabe sehen, wurde Ihr Go-Programm korrekt ausgeführt. Manchmal möchten Sie Ihr Programm vielleicht in einem »Wegwerfcontainer« ausführen (zum Beispiel um nur sicherzustellen, dass das Programm überhaupt läuft). Dazu können Sie folgenden Befehl verwenden:

$ docker run --rm golang sh -c "go get github.com/golang/example/hello/… && exec hello" Hello, Go examples! Dieser Befehl führt einen Golang-Container aus, ruft das Go-Beispielprogramm ab und nutzt die Shell (sh) zum Ausführen (exec) des hello-Programms. Bei Bedarf können Sie Ihr Go-Programm auch mit einer spezifischen Version von Go ausführen lassen. Der folgende Befehl führt das Go-Beispielprogramm in Version 1.5 von Go in einem Wegwerfcontainer aus:

$ docker run --rm golang:1.5 sh -c "go get github.com/golang/example/hello/… && exec hello" Unable to find image 'golang:1.5' locally

1.5: Pulling from library/golang

357ea8c3d80b: Pull complete





Status: Downloaded newer image for golang:1.5

Hello, Go examples!

Go programmieren für Dummies Bibliografische Information der Deutschen Nationalbibliothek Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar. © 2022 Wiley-VCH GmbH, Boschstraße 12, 69469 Weinheim, Germany Original English language edition Go Programming Language For Dummies © 2021 by Wiley Publishing, Inc All rights reserved including the right of reproduction in whole or in part in any form. This translation published by arrangement with John Wiley and Sons, Inc. Copyright der englischsprachigen Originalausgabe Go Programming Language For Dummies © 2021 by Wiley Publishing, Inc. Alle Rechte vorbehalten inklusive des Rechtes auf Reproduktion im Ganzen oder in Teilen und in jeglicher Form. Diese Übersetzung wird mit Genehmigung von John Wiley and Sons, Inc. publiziert. Wiley, the Wiley logo, Für Dummies, the Dummies Man logo, and related trademarks and trade dress are trademarks or registered trademarks of John Wiley & Sons, Inc. and/or its affiliates, in the United States and other countries. Used by permission. Wiley, die Bezeichnung »Für Dummies«, das Dummies-Mann-Logo und darauf bezogene Gestaltungen sind Marken oder eingetragene Marken von John Wiley & Sons, Inc., USA, Deutschland und in anderen Ländern. Das vorliegende Werk wurde sorgfältig erarbeitet. Dennoch übernehmen Autoren und Verlag für die Richtigkeit von Angaben, Hinweisen und Ratschlägen sowie eventuelle Druckfehler keine Haftung. Print ISBN: 978-3-527-71946-4

ePub ISBN: 978-3-527-83753-3 Coverfoto: © SriWidiawati – stock.adobe.com

Korrektur: Matthias Delbrück, Dossenheim/Bergstraße

Über den Autor Wei-Meng Lee ist Gründer des Unternehmens Developer Learning Solutions, das sich auf Schulungen zu aktuellen Technologien spezialisiert hat. Nach dem Motto »Learning by Doing« legt er in seinen Kursen besonderen Wert auf anwendungsnahe Inhalte und schafft es dank seiner langjährigen Erfahrung, komplexe Technologietrends verständlich zu erklären. Lee schreibt regelmäßig für Online- und Printpublikationen wie DevX.com, MobiForge.com oder CODE Magazine und ist Autor mehrerer Bücher. Wenn er nicht gerade beim Programmieren die Finger über die Tastatur sausen lässt, ist Lee auch auf Konferenzen und Branchenveranstaltungen anzutreffen – von den RigaDevDays bis hin zur NDC in Oslo, London oder Kopenhagen.

Widmung Ich widme dieses Buch meiner lieben Frau Sze Wa und unserer Tochter Chloe und danke beiden aus vollem Herzen dafür, dass sie es trotz meines unregelmäßigen Terminplans mit mir aushalten und mich so wunderbar unterstützen, wenn mal wieder ein Buchabgabetermin näher rückt!

Danksagung des Autors Buchprojekte finde ich immer spannend, obwohl sie mit langen Arbeitsstunden und einer ganzen Menge Stress einhergehen. Dass am Ende trotzdem ein akkurates Werk dabei herauskommt, liegt zweifelsohne an den vielen Beiträgen zahlreicher engagierter Helden und Heldinnen hinter den Kulissen. Ich möchte diese Gelegenheit nutzen, um stellvertretend einigen besonderen Personen zu danken, ohne die dieses Buch nicht möglich gewesen wäre.

Bedanken möchte ich mich bei Patrice Choong, Leiter der Fakultät für InfoComm-Technologien an der Ngee Ann Polytechnic, der es mir ermöglicht hat, den Lehrplan für die Go School und die Data School mitzugestalten. Vielen Dank für dein Vertrauen, Patrice! Danken möchte ich auch meinen Eltern, meiner Frau und meiner Tochter für all ihre Unterstützung. Selbstlos haben sie immer wieder ihre eigenen Pläne an meinen gefüllten Terminkalender beim Schreiben dieses Buches angepasst. Tausend Dank! Ich hab euch lieb!

Inhaltsverzeichnis Cover Titelblatt Impressum Über den Autor Einleitung Über dieses Buch Törichte Annahmen über den Leser Symbole, die in diesem Buch verwendet werden Weitere Ressourcen Wie es weitergeht

Teil I: Erste Schritte mit Go Kapitel 1: Auf die Plätze, fertig, Go! Mit Go zum beruflichen Erfolg Installieren von Go auf Ihrem Computer Verwenden einer integrierten Entwicklungsumgebung (IDE) mit Go Ihr erstes Go-Programm Vergleich von Go mit anderen Programmiersprachen

Kapitel 2: Datentypen Deklarieren von Variablen Deklarieren von Konstanten Entfernen von ungenutzten Variablen Verwenden von Strings Konvertieren von Datentypen

Kapitel 3: Entscheidungsfindung Entscheidungen mittels if/else Verwenden der switch-Anweisung bei mehreren Bedingungen

K

i l4 N

h i

l

d

h i

l

Kapitel 4: Noch einmal und noch einmal: Programmschleifen Durchlaufen von Schleifen mit der for-Anweisung Iteration über einen Wertebereich Verwenden von Sprungmarken mit der for-Schleife

Kapitel 5: Übersichtlicher Code dank Funktionen Definieren einer Funktion Verwenden von anonymen Funktionen

Teil II: Datenstrukturen Kapitel 6: Datensammlungen in Arrays und Slices Allzeit bereit mit Arrays Strukturell flexibel mit Slices Slicing von Wertebereichen

Kapitel 7: Logische Datenorganisation mit Structs Definieren von Structs für Sammlungen aus Datenelementen Erzeugen von Structs Kopieren von Structs Definieren von Methoden in Structs Vergleichen von Structs

Kapitel 8: Beziehungen und Maps Erstellen von Maps in Go Verwenden von Structs und Maps in Go

Kapitel 9: Datencodierung mit JSON Grundlagen von JSON Decodieren des JSON-Formats Codieren des JSON-Formats

Kapitel 10: Methodensignaturen mit Interfaces Arbeiten mit Interfaces in Go Wozu sind Interfaces gut?

Teil III: Multitasking in Go Kapitel 11: Threading mit Goroutinen D

G

d i

i

G

ti

Das Grundprinzip von Goroutinen Verwenden von Goroutinen mit gemeinsamen Ressourcen Synchronisieren von Goroutinen

Kapitel 12: Kommunikation zwischen Goroutinen mit Kanälen Das Grundprinzip von Kanälen Iterieren über Kanäle Asynchrones Warten auf Kanäle Verwenden von gepufferten Kanälen

Teil IV: Übersichtlicher Code Kapitel 13: Pakete in Go Arbeiten mit Paketen Verwenden von Drittanbieter-Paketen

Kapitel 14: Module für Paketgruppen Erstellen eines Moduls Testen und Zusammensetzen eines Moduls Veröffentlichen eines Moduls auf GitHub

Teil V: Go in Aktion Kapitel 15: Verwendung von Web-APIs mit Go Funktionsprinzip von Web-APIs Abrufen der Daten von Webservices in Go

Kapitel 16: Eigene Webservices mit REST-APIs Erstellen von Webservices mit REST-APIs Erstellen einer REST-API in Go

Kapitel 17: Verwendung von Datenbanken Einrichten eines MySQL-Datenbankservers Herstellen der Verbindung zur MySQL-Datenbank in Go

Teil VI: Der Top-Ten-Teil Kapitel 18: Zehn praktische Go-Pakete zum Erstellen von Anwendungen color

now go-pushbullet goid json2go gojq turtle go-http-client notify gosx-notifier

Kapitel 19: Zehn nützliche Go-Ressourcen Die offizielle Go-Website Go by Example Go-Tour Häufig gestellte Fragen zu Go Go Playground Go Bootcamp Effective Go Gophercises Tutorialspoint Stack Overflow

Abbildungsverzeichnis Stichwortverzeichnis End User License Agreement

Tabellenverzeichnis Kapitel 1 Tabelle 1.1: Umgebungsvariablen für verschiedene Betriebssysteme

Kapitel 3 Tabelle 3.1: Vergleichsoperatoren in Go Tabelle 3.2: Logische Operatoren in Go

K

i l

Kapitel 5 Tabelle 5.1: Referenzdatum zum Formatieren von Datum und Uhrzeit in Go Tabelle 5.2: Ausgabe eines Datums basierend auf gewählter Formatierung

Kapitel 14 Tabelle 14.1: Unterverzeichnisse von $GOPATH

Kapitel 16 Tabelle 16.1: Optionen für curl

Illustrationsverzeichnis Kapitel 1 Abbildung 1.1: Die Go-Installationsdatei steht zum Herunterladen bereit. Abbildung 1.2: Der Go-Installationsvorgang ist abgeschlossen. Abbildung 1.3: Visual Studio Code wird zum ersten Mal gestartet. Abbildung 1.4: Visual Studio Code ist einsatzbereit. Abbildung 1.5: Das Symbol ERWEITERUNGEN ganz unten in der Aktivitätsleiste Abbildung 1.6: Für Visual Studio Code gibt es zahlreiche GoErweiterungen. Abbildung 1.7: Zur Einführung in die Programmierung mit Go schreiben Sie ein typi... Abbildung 1.8: Die Kommandozeile kann direkt in Visual Studio Code aufgerufen wer...

Kapitel 5 Abbildung 5.1: Beim Aufruf der Funktion tausch() werden die Werte von x und y in ... Abbildung 5.2: Beim Aufruf der Funktion tausch() werden nun die Speicheradressen ...

Kapitel 6 Abbildung 6.1: Arrays sind Sammlungen von Datenelementen desselben Typs. Abbildung 6.2: Ein Array mit fünf ganzzahligen Elementen hat Indexwerte von 0 bis... Abbild

6 3 Ei

idi

i

l

A

i G i t

it i

T b ll

Abbildung 6.3: Ein zweidimensionales Array in Go ist mit einer Tabelle vergleichb... Abbildung 6.4: Ein dreidimensionales Array in Go ist mit einem Quader vergleichba... Abbildung 6.5: Die Elemente eines dreidimensionalen Arrays als Quader Abbildung 6.6: Eine Slice wird durch einen Header mit drei Feldern repräsentiert. Abbildung 6.7: Die Kapazität einer Slice kann größer sein als ihre Länge. Abbildung 6.8: Eine Slice wird erzeugt und mit Anfangswerten initialisiert. Abbildung 6.9: Wenn eine Slice ihre Kapazitätsgrenze erreicht und weitere Element... Abbildung 6.10: Die Slice t kann zwei weitere Elemente aufnehmen, ohne ihre Kapaz... Abbildung 6.11: Wird eine Slice einer Variablen zugewiesen, wird dadurch eine wei... Abbildung 6.12: Eine Modifikation von Slice u wirkt sich auch auf Slice t aus. Abbildung 6.13: Durch das Anhängen eines Elements überschreitet Slice t ihre Kapa... Abbildung 6.14: Eine Slice wird einer Slicing-Operation unterzogen und das Ergebn... Abbildung 6.15: Die Kapazität der Slice ändert sich nach dem Slicing. Abbildung 6.16: Ein Element wird in eine Slice eingefügt. Abbildung 6.17: Ein Element wird aus einer Slice entfernt.

Kapitel 7 Abbildung 7.1: Die Funktion neuerPunkt() liefert als Rückgabewert einen Zeiger au... Abbildung 7.2: pt4 und pt5 zeigen auf dieselbe Struct-Instanz. Abbildung 7.3: pt6 zeigt auf eine neue Instanz der punkt-Struktur. Abbildung 7.4: Eine Kopie von pt6 ist in pt7 hinterlegt und wird von pt8 referenz...

Kapitel 8 Abbildung 8.1: Diese Map enthält drei Paare aus Schlüssel und zugehörigem Wert. Abbildung 8.2: Alle Elemente der Map wurden als Structs zur Slice p hinzugefügt.

K

i l9

Kapitel 9 Abbildung 9.1: Mit dem JSONLint-Tool können Sie JSON-Code validieren. Abbildung 9.2: Der Typ von kurse ist map[string] interface{}. Abbildung 9.3: Für den Wert von kurse wird der Typ map[string] interface{} zugesi... Abbildung 9.4: Mehrere Go-Strukturen speichern Kundendaten.

Kapitel 11 Abbildung 11.1: Zwei Funktionen werden nebenläufig als Goroutinen ausgeführt und ... Abbildung 11.2: Der neue Wert des Guthabens wird unter Umständen nicht rechtzeiti...

Kapitel 12 Abbildung 12.1: Jede der Goroutinen versucht, ihre Teilsumme an den Kanal zu send...

Kapitel 13 Abbildung 13.1: Das main-Paket umfasst zwei physische Dateien. Abbildung 13.2: Die Dokumentation Ihrer Go-Pakete wird in Form von Webseiten ange... Abbildung 13.3: Für die von Ihnen installierten Pakete gibt es eine praktische Do... Abbildung 13.4: Zu jedem installierten Paket sind Informationen verfügbar. Abbildung 13.5: Godoc erstellt automatisch die Dokumentation für Ihre Pakete.

Kapitel 14 Abbildung 14.1: Über die grüne Schaltfläche erstellen Sie ein neues GitHub-Reposi... Abbildung 14.2: Vergeben Sie einen Namen für Ihr neues GitHubRepository. Abbildung 14.3: Sie können nun Ihre Dateien auf GitHub hochladen. Abbildung 14.4: Ziehen Sie Ihre hochzuladenden Dateien in dieses Viereck. Abbildung 14.5: Dateien und Ordner werden per Drag-and-drop auf GitHub hochgelade... Abbildung 14.6: Durch Klick auf die Schaltfläche COMMIT CHANGES werden Ihre Änder... Abbild

14 7 D

M d l

d

f l

i h

öff

tli ht!

Abbildung 14.7: Das Modul wurde erfolgreich veröffentlicht!

Kapitel 15 Abbildung 15.1: Ein Client kommuniziert mit einer Web-API. Abbildung 15.2: Um die API von Fixer zu verwenden, benötigen Sie ein Benutzerkont... Abbildung 15.3: Der JSON-Validator überprüft die von der Fixer-API gesendeten JSO... Abbildung 15.4: Der JSON-Validator überprüft die von der Fixer-API gesendete JSON... Abbildung 15.5: Der JSON-Validator überprüft die von der OpenWeatherAPI gesendet... Abbildung 15.6: Der JSON-Validator überprüft die von der OpenWeatherAPI gesendet...

Kapitel 16 Abbildung 16.1: Eine HTTP-Nachricht wird an eine Web-API gesendet, die daraufhin ... Abbildung 16.2: Die URL einer REST-API besteht aus mehreren Komponenten. Abbildung 16.3: Mithilfe von HTTP-Methoden können Sie mit der RESTAPI kommunizie... Abbildung 16.4: Mit dem gorilla/mux-Paket können Sie REST-APIs in Go erstellen. Abbildung 16.5: Pfadvariablen werden extrahiert. Abbildung 16.6: Die Query-Komponente enthält Schlüssel-Wert-Paare.

Kapitel 17 Abbildung 17.1: Wählen Sie die gewünschte Setup-Option. Abbildung 17.2: Legen Sie ein sicheres Passwort für das RootBenutzerkonto fest. Abbildung 17.3: Per MySQL Workbench können Sie mit dem MySQLServer interagieren.

Einleitung Wer heutzutage als Programmierer aktiv werden möchte, hat zahlreiche Programmiersprachen zur Auswahl. Zu den beliebtesten zählen unter anderem C++, C#, Go, Java, JavaScript, Python, R und Swift. Jede dieser Sprachen wurde für spezifische Problemstellungen konzipiert. Je nachdem, was Sie entwickeln wollen (Webanwendungen, Apps für Mobilgeräte oder Desktopprogramme), kann es durchaus sein, dass Sie sich mehr als eine Programmiersprache aneignen müssen. Und warum ausgerechnet Go? Eine Antwort auf diese Frage liefert die Entstehungsgeschichte von Go. Drei Techniker bei Google waren nämlich so frustriert mit den diversen Tools, die ihnen für ihre Aufgaben zur Verfügung standen, dass sie beschlossen, eine neue Sprache zu entwickeln. Dabei setzten sie sich zum Ziel, nützliche Aspekte anderer Programmiersprachen zu kombinieren, gleichzeitig aber deren Schwachstellen zu beheben. Go sollte vor allem die folgenden Kriterien erfüllen: Statische Typisierung und Laufzeiteffizienz wie bei C Einfache Lesbarkeit und Anwendbarkeit wie bei Python und JavaScript Hohe Leistungsfähigkeit beim Netzwerk- und Multiprozessorbetrieb Aufgrund der Probleme mit existierenden Programmiersprachen war das Google-Team gezwungen, eine gänzlich neue Sprache zu erschaffen. Möglichst effizient und schnörkellos sollte sie sein. Und Multithreading sowie Nebenläufigkeit sollte sie natürlich auch unterstützen. Dieses Buch erläutert die Grundlagen von Go (auch bekannt als Golang) und erklärt Ihnen Schritt für Schritt, wie Sie sich diese immer beliebtere Programmiersprache zunutze machen, um schnelle und skalierbare Anwendungen zu entwickeln.

Über dieses Buch Im Buch finden Sie viele kompakte und leicht verständliche Programmbeispiele, die Sie gut nachvollziehen und selbst ausprobieren können. Jedes Kapitel stellt außerdem einen eigenständigen Themenblock dar. Sie müssen also nicht unbedingt alles der Reihe nach von der ersten bis zur letzten Seite lesen. Ein bestimmtes Thema interessiert Sie besonders? Dann blättern Sie einfach zum entsprechenden Kapitel vor. Sollten Sie es eilig haben, können Sie getrost all jene Texte überspringen, die sich in Infokästen befinden oder durch das TechnikerSymbol gekennzeichnet sind (mehr dazu im Abschnitt Symbole, die in diesem Buch verwendet werden). Diese Textstellen bieten weiterführende Informationen, sind aber zum Verständnis nicht zwingend erforderlich. Im gesamten Buch folge ich zudem den üblichen Konventionen der … für Dummies-Reihe: Text, den Sie exakt übernehmen sollen, sowie Internetadressen erscheinen in Festbreitenschrift. Wenn Sie eine digitale Version dieses Buches auf einem Gerät mit bestehender Internetverbindung lesen, können Sie Links auch anklicken oder antippen, zum Beispiel diesen hier: www.fuer-dummies.de. Beachten Sie, dass sich bei manchen Links die Adresse über zwei Zeilen erstreckt. Wenn Sie die Printausgabe des Buches lesen und eine solche Webseite aufrufen möchten, geben Sie die Adresse so im Browser ein, wie sie abgedruckt ist, jedoch ohne irgendeinen Zeilenumbruch. Wörter, die Sie eingeben sollen und die zusätzlich kursiv hervorgehoben sind, dienen als Platzhalter. Das heißt, Sie müssen sie jeweils durch passende Wörter ersetzen. Lautet die Anweisung beispielsweise: »Geben Sie Ihr Passwort ein und bestätigen Sie mit OK«, so müssen Sie Ihr Passwort durch Ihr tatsächliches Passwort ersetzen.

Programmoberflächenelemente wie Menübefehle, Optionen etc. werden in KAPITÄLCHEN gesetzt. Wenn Sie eine bestimmte Taste auf Ihrer Tastatur drücken sollen, wird diese ebenfalls hervorgehoben (zum Beispiel: ).

Falls die Listings im eBook-Display nicht gut lesbar sind oder nicht korrekt dargestellt werden, empfehlen wir Ihnen, sich die Beispieldateien von der Webseite des Buches herunterzuladen: www.wiley-vch.de/9783527719464

Törichte Annahmen über den Leser Dieses Buch richtet sich an alle, die bisher gar nicht oder nur wenig mit Go gearbeitet haben. Als Go-Neuling sind Sie hier genau richtig. Allerdings nehme ich bei meinen Erklärungen an, dass Sie folgende Vorkenntnisse besitzen: Sie sind mit den Grundlagen der Programmierung vertraut. Sie verstehen das Konzept von Datenstrukturen (z. B. Array, Dictionary, Struct). Sie können mit einem Computer umgehen und die Beispiele in diesem Buch selbstständig ausprobieren.

Symbole, die in diesem Buch verwendet werden Wie in anderen Werken aus der … für Dummies-Reihe tauchen auch in diesem Buch am Seitenrand ab und zu kleine Symbole auf, die Sie auf bestimmte Inhalte hinweisen.

Dieses Symbol markiert Informationen, die so wichtig oder nützlich sind, dass Sie sie unbedingt im Hinterstübchen behalten sollten. Neben dem Techniker-Symbol finden Sie weiterführende Erklärungen oder Details, die Sie auch überspringen können, wenn Sie gerade keine Lust auf trockene Theorie haben. Die Tipps neben dem Glühbirnen-Symbol bringen etwas Licht ins Dunkel und sollen Ihnen die Arbeit mit Go erleichtern. Wenn Sie auf dieses Warnschild stoßen, lesen Sie die zugehörige Textstelle ganz genau. Sie enthält Hinweise, welche Fehler Sie vermeiden sollten, damit Sie sich beim Programmieren keine Steine in den Weg legen.

Weitere Ressourcen Am Anfang dieses Buches finden Sie wie üblich einige »Schummelseiten«, die Sie sich ausschneiden und griffbereit neben den Computer legen können. Und damit Sie die Programmbeispiele nicht alle mühsam per Hand abtippen müssen, stehen die Quelltexte in Dateiform unter folgender Adresse zum Herunterladen bereit: www.wiley-vch.de/ISBN9783527719464.

Wie es weitergeht Befassen Sie sich zum allerersten Mal mit Go? Dann beginnen Sie am besten mit Kapitel 1 und lesen der Reihe nach die weiteren Kapitel. Wenn Sie hingegen schon Grundkenntnisse zu Go mitbringen und sofort mit praktischen Anwendungsbeispielen loslegen möchten, hält Teil V passende Inhalte für Sie parat. Unabhängig von Ihren bisherigen

Erfahrungen mit Go können Sie natürlich auch jederzeit über das Inhaltsverzeichnis oder den Index gezielt nach Themen suchen, die Sie besonders interessieren. Zu guter Letzt noch ein Rat für alle Neulinge: Probieren geht über Studieren und aus Fehlern wird man klug! Führen Sie die Programmbeispiele auf Ihrem Computer aus, nehmen Sie ruhig hier und da Änderungen vor und ärgern Sie sich nicht, wenn mal etwas nicht wie gewünscht funktioniert. Je mehr Fehler Ihnen unterlaufen, desto besser werden Sie die behandelten Themen verstehen. Ich wünsche Ihnen viel Erfolg und Vergnügen beim Programmieren mit Go!

Teil I

Erste Schritte mit Go



IN DIESEM TEIL … Schreiben Sie Ihr erstes Go-Programm. Lernen Sie grundlegende Datentypen in Go kennen und deklarieren Variablen und Konstanten. Programmieren Sie Entscheidungsstrukturen mithilfe von logischen Operatoren und Vergleichsoperatoren. Erstellen Sie Programmschleifen und lassen Code wiederholt ausführen. Verwenden Sie Funktionen, um Ihre Go-Programme übersichtlicher zu gestalten.

Kapitel 1

Auf die Plätze, fertig, Go! IN DIESEM KAPITEL Vorteile von Go Go auf Ihrem Computer installieren Mit einer IDE arbeiten Go-Programme schreiben und ihre Funktionsweise verstehen Go im Vergleich mit anderen Programmiersprachen

Go ist eine quelloffene Programmiersprache, die von Google erstmals im Jahr 2009 vorgestellt wurde und inzwischen immer mehr Fans findet. Mit dieser Sprache können Sie unterschiedlichste Aufgaben bewältigen und vor allem schnelle, skalierbare Anwendungen entwickeln. Hinter Go stecken einige ziemlich clevere Köpfe, allen voran: Ken Thompson (Designer und Erfinder von Unix und C), Rob Pike (CoEntwickler des UTF-8- und Unix-Formats) und Robert Griesemer (ein Google-Informatiker). Wenn Sie sich für technische Details interessieren und des Englischen mächtig sind, können Sie im Artikel »Go at Google: Language Design in the Service of Software Engineering« (https://talks.golang.org/2012/splash.article) nachlesen, welche Problemstellungen ursprünglich mit Go bei Google angegangen werden sollten. In diesem Kapitel erfahren Sie, warum Go Ihrer Karriere zuträglich ist, wo diese Sprache überall eingesetzt werden kann und welche ersten Schritte Sie unternehmen müssen, um selbst mit Go zu programmieren.

Da die Website von Go unter der Adresse https://golang.org zu erreichen ist, hat sich auch die Bezeichnung Golang für diese Programmiersprache etabliert. Der offizielle Name ist jedoch Go und wird demzufolge in diesem Buch beibehalten.

Mit Go zum beruflichen Erfolg Programmiersprachen gibt es heute viele, doch Go sticht aus der breiten Masse hervor. Dies hat mehrere Gründe: Go lässt sich leicht erlernen. Durch seine Syntax ist Go eine gut lesbare Sprache. Die objektorientierte Programmierung wird nicht unterstützt, sodass Sie sich keine Gedanken um Klassen und Vererbung und all die komplexen Merkmale dieses Programmierparadigmas machen müssen. Bei der objektorientierten Programmierung (OOP) dreht sich alles um Datenobjekte. Es geht also primär nicht um Funktionen oder Logik, sondern um Daten. Ein wesentliches Konzept bei der OOP ist die Klasse (quasi eine Art Vorlage für Datenobjekte). Angenommen, Sie möchten Ihre Anwendung mit mehreren Schaltflächen versehen. Damit Sie den zugehörigen Programmcode nicht wiederholt für jede einzelne Schaltfläche schreiben müssen, können Sie eine Klasse für eine generische Schaltfläche definieren und diese dann zum Erstellen Ihrer gewünschten Schaltflächen nutzen. Dabei hat jede Schaltfläche ihre eigenen Attribute (Merkmale). Mithilfe von Vererbung können Sie bei der OOP mehrere Subklassen aus der generischen Schaltflächenklasse erzeugen, um unterschiedliche Arten von Schaltflächen zu generieren, beispielsweise Schaltflächen in Rechteckform oder mit abgerundeten Ecken und so weiter. Go hat eine geringere Funktionsauswahl als andere Programmiersprachen. Bei Go müssen Sie nicht erst überlegen, auf

welche Weise Sie ein bestimmtes Problem am besten lösen – es gibt immer nur eine korrekte Vorgehensweise. Dadurch bleibt Ihre Codebasis viel übersichtlicher. Go glänzt bei nebenläufiger Programmierung. Durch sogenannte Goroutinen ist es äußerst einfach, mehrere Funktionen parallel auszuführen.

Go bietet derzeit keine Unterstützung für generische Datentypen (bei denen der tatsächliche Datentyp erst bei Verwendung angegeben werden muss), doch dies könnte sich künftig ändern, da die Sprache weiterentwickelt wird. All das hat Sie noch nicht überzeugt? Dann habe ich ein weiteres Argument, das Sie motivieren könnte, die Programmierung mit Go zu lernen: Stack Overflow, eine Internetplattform mit Fragen und Antworten rund um das Thema Programmierung, führt jährliche Gehaltsumfragen unter Softwareentwicklern durch. Ergebnissen aus dem Jahr 2021 zufolge (siehe Stack Overflow Developer Survey 2021, https://insights.stackoverflow.com/survey/2021) landen GoEntwickler unter den ersten zehn. Obwohl es Go schon eine ganze Weile gibt (nämlich seit 2009), findet die Sprache erst jetzt immer mehr Zustimmung in der Softwareentwicklungsbranche, vor allem dank Cloud-Computing und Microservices. Mittlerweile kommt Go bei zahlreichen großen Unternehmen wie Dailymotion, Dropbox, Google und Uber zum Einsatz. Die Anwendungsszenarien sind vielfältig: Cloud-Services: Mit Go und der Google Cloud Platform (GCP) können Sie skalierbare Apps erstellen. Netzwerkanwendungen: Durch die Unterstützung für Goroutinen lassen sich mit Go verteilte Serveranwendungen und Programmierschnittstellen (APIs) entwickeln.

Webservices: Auch skalierbare und effiziente Webservices sind mit Go kein Problem. Befehlszeilenbasierte Anwendungen: Da Go auf mehreren Plattformen ausführbar ist, können Sie dieselbe Codebasis gezielt für verschiedene Plattformen kompilieren (zum Beispiel für macOS und Windows).

Installieren von Go auf Ihrem Computer Bestimmt sind Sie neugierig, wie Sie nun mit Go etwas auf Ihrem Computer programmieren können. Legen wir also los! Als Erstes müssen Sie Go installieren. Am einfachsten geht dies über die Installationsseite auf der offiziellen Go-Website: https://golang.org/doc/install. Die Website erkennt automatisch Ihr gerade genutztes Betriebssystem und bietet Ihnen die passende Installationsdatei zum Herunterladen an (siehe Abbildung 1.1).

Abbildung 1.1: Die Go-Installationsdatei steht zum Herunterladen bereit.

Die Programmbeispiele in diesem Buch wurden mit Version 1.15 von Go geschrieben und getestet. Wenn Sie dieses Buch in den Händen halten, gibt es aber bestimmt schon eine neuere GoVersion. Damit Sie trotzdem alle Beispiele problemlos ausprobieren können, sollten Sie sich dieselbe Version herunterladen, die ich auch genutzt habe. Diese finden Sie hier: macOS: https://golang.org/dl/go1.15.8.darwinamd64.pkg

Windows: https://golang.org/dl/go1.15.8.windowsamd64.msi

Wenn Sie alle verfügbaren Installationsdateien für die unterstützten Plattformen (Linux, macOS und Windows) oder sogar den Quellcode von Go sehen möchten, öffnen Sie folgende Seite in Ihrem Browser: https://golang.org/dl/. Nachdem Sie die Go-Installationsdatei heruntergeladen haben, führen Sie sie per Doppelklick aus, um den Installationsvorgang zu starten. Es öffnet sich ein Dialogfenster, in dem Sie der EndbenutzerLizenzvereinbarung zustimmen müssen und dann den gewünschten Speicherort für die Go-Dateien angeben können. Unter Windows wird standardmäßig der Ordner Programme beziehungsweise Programme (x86) vorgeschlagen. Damit Sie die Beispiele aus diesem Buch leicht nachvollziehen können, ändern Sie diese Einstellung und speichern Sie die Dateien stattdessen unter C:\Go. Alle anderen Standardeinstellungen können Sie beibehalten. Klicken Sie zum Schluss auf die Schaltfläche INSTALL. Go wird nun innerhalb weniger Sekunden installiert. Nach Abschluss des Vorgangs erscheint ein Bestätigungsfenster (siehe Abbildung 1.2).

Abbildung 1.2: Der Go-Installationsvorgang ist abgeschlossen.

In den folgenden Abschnitten zeige ich Ihnen, wie Sie unter macOS und Windows überprüfen können, ob Go korrekt installiert wurde.

macOS Unter macOS wird die Go-Distribution standardmäßig im Verzeichnis /usr/local/go installiert. Außerdem fügt das Installationsprogramm automatisch das Verzeichnis /usr/local/go/bin zur PATHUmgebungsvariablen hinzu. Dies lässt sich leicht überprüfen. Öffnen Sie dazu die Terminal-App (die Sie im Ordner Programme/Dienstprogramme finden) und geben Sie folgenden Befehl ein: $ echo $PATH

Sie sehen nun eine Ausgabe ähnlich der folgenden, nur dass statt weimenglee Ihr eigener Benutzername erscheint (der neu hinzugefügte

Go-Pfad ist fett hervorgehoben): /Users/weimenglee/opt/anaconda3/bin:/Volumes/SSD/opt/anaco

nda3/condabin:/Users/weimenglee/flutter/bin:/Users/weimeng

lee/go/bin:/Users/weimenglee/.nvm/versions/node/v9.2.0/bin

:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/g

o/bin:/usr/local/share/dotnet:~/.dotnet/tools:/Library/App

le/usr/bin:/Library/Frameworks/Mono.framework/Versions/Cur

rent/Commands

Starten Sie die Terminal-App neu, nachdem Sie Go installiert haben, damit die geänderten Einstellungen korrekt übernommen werden. Um zu testen, ob bei der Installation alles geklappt hat, geben Sie folgenden Befehl im Terminal-Fenster ein: $ go version

Ihnen sollte nun die auf Ihrem System installierte Go-Version angezeigt werden: go version go1.11.5 darwin/amd64

Windows Unter Windows wird die Go-Distribution im Verzeichnis C:\Go installiert (vorausgesetzt, Sie haben die Standardeinstellung geändert, wie zuvor beschrieben). Außerdem fügt das Installationsprogramm automatisch das Verzeichnis Go\bin zur PATH-Umgebungsvariablen hinzu. Auch dies lässt sich leicht überprüfen. Öffnen Sie dazu die Eingabeaufforderung (indem Sie zum Beispiel die Tastenkombination + drücken und dann im Dialogfenster cmd eingeben) und geben Sie folgenden Befehl ein: C:\Users\Wei-Meng Lee>path

Sie sehen nun eine Ausgabe ähnlich der folgenden, nur dass statt weimenglee Ihr eigener Benutzername erscheint (der neu hinzugefügte

Go-Pfad ist fett hervorgehoben): PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\

Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WIND

OWS\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program

Files\Microsoft SQL Server\130\Tools\Binn\;C:\Go\bin;

C:\Program Files\Git\cmd;C:\Program Files\Graphviz

2.44.1\bin;C:\Program Files\CMake\bin;C:\Program

Files\Docker\Docker\resources\bin;C:\ProgramData\DockerDes

ktop\version-bin;C:\Program Files\MySQL\MySQL Shell

8.0\bin\;C:\Users\Wei-Meng Lee\AppData\Local\

Microsoft\WindowsApps;;C:\Users\Wei-Meng Lee\

AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\Wei-

Meng Lee\.dotnet\tools;C:\Users\Wei-Meng Lee\go\bin

Starten Sie die Eingabeaufforderung neu, nachdem Sie Go installiert haben, damit die geänderten Einstellungen korrekt übernommen werden. Um zu testen, ob bei der Installation alles geklappt hat, geben Sie folgenden Befehl in der Eingabeaufforderung ein: C:\Users\Wei-Meng Lee>go version

Ihnen sollte nun die auf Ihrem System installierte Go-Version angezeigt werden: go version go1.15.2 windows/amd64

Verwenden einer integrierten Entwicklungsumgebung (IDE) mit Go Um Anwendungen mit Go zu entwickeln, benötigen Sie eigentlich nur einen Texteditor (zum Beispiel TextEdit unter macOS oder den

klassischen Editor unter Windows). Die Profis in der Softwareentwicklung bevorzugen aber häufig integrierte Entwicklungsumgebungen (Integrated Development Environments, IDEs), mit denen sich der Programmcode besser organisieren und auf Fehler überprüfen lässt. Mit Go harmonieren zum Beispiel folgende IDEs: Visual Studio Code (https://code.visualstudio.com): Visual Studio Code aus dem Hause Microsoft ist eine IDE par excellence (und mein persönlicher Favorit). Das Tool umfasst alle üblichen Editorfunktionen und unterstützt fast jede erdenkliche Programmiersprache. Besonders nützlich ist die IntelliSenseFunktion, die Ihre Programmbefehle automatisch vervollständigt, während Sie sie eingeben. Visual Studio Code bietet außerdem einen Debugger, eine interaktive Konsole sowie integrierte GitUnterstützung. Und das Beste: Visual Studio Code ist kostenlos erhältlich und erfreut sich unter Go-Entwicklern hoher Beliebtheit, sodass es zahlreiche Plug-ins gibt, mit denen Sie die Funktionalität sogar noch erweitern können. GoLand (www.jetbrains.com/de-de/go/): GoLand ist eine plattformübergreifende IDE des multinationalen Softwareanbieters JetBrains. Unter anderem bietet diese IDE Unterstützung bei der Befehlseingabe, einen Debugger und einen integrierten Terminal. GoLand ist ein kommerzielles Produkt, kann aber als Testversion 30 Tage lang kostenlos genutzt werden. Go Playground (https://play.golang.org): Beim Go Playground handelt es sich eigentlich nicht um eine IDE, sondern um einen Webservice, der über die Server der offiziellen Go-Website läuft und – wie der Name schon sagt – als »Spielplatz« dient, auf dem Sie kurze Go-Programmzeilen im Browser testen können. Das eingegebene Go-Programm wird kompiliert, verlinkt und innerhalb der Testumgebung ausgeführt, sodass Sie sehen, ob die Ausgabe des Programms Ihren Erwartungen entspricht.

Für die Go-Programmbeispiele und Erklärungen in diesem Buch nutze ich Visual Studio Code. Diese IDE steht unter https://code.visualstudio.com/download zum Herunterladen bereit. Nachdem Sie Visual Studio Code heruntergeladen und installiert haben, starten Sie die Anwendung. Es öffnet sich ein Begrüßungsfenster, in dem standardmäßig alles auf Englisch angezeigt wird. Sofern Sie ein deutsches Betriebssystem nutzen, erscheint aber in der unteren rechten Ecke automatisch ein Hinweis auf das deutsche Sprachpaket. Um dies zu installieren, klicken Sie auf die Schaltfläche INSTALLIEREN UND NEU STARTEN (siehe Abbildung 1.3). Das Sprachpaket wird automatisch installiert und Visual Studio Code neu gestartet. Bei Bedarf können Sie nun auch die Darstellungsoptionen anpassen. Im dunklen Standarddesign präsentiert sich Visual Studio Code wie in Abbildung 1.4 zu sehen.

Abbildung 1.3: Visual Studio Code wird zum ersten Mal gestartet.

Abbildung 1.4: Visual Studio Code ist einsatzbereit.

Damit Visual Studio Code die Syntax von Go erkennt und verarbeiten kann, müssen Sie eine Erweiterung installieren. Führen Sie dazu folgende Schritte aus: 1. Klicken Sie in Visual Studio Code in der Aktivitätsleiste am linken Rand auf das Symbol ERWEITERUNGEN (siehe Abbildung 1.5).

Abbildung 1.5: Das Symbol ERWEITERUNGEN ganz unten in der Aktivitätsleiste

2. Geben Sie in der Seitenleiste im Suchfeld das Stichwort Go ein. In den Suchergebnissen sehen Sie diverse verfügbare GoErweiterungen (siehe Abbildung 1.6).

Abbildung 1.6: Für Visual Studio Code gibt es zahlreiche Go-Erweiterungen.

3. Klicken Sie neben der ersten Erweiterung (»Rich Go language support for Visual Studio Code«) auf die Schaltfläche INSTALLIEREN. Das war's schon! Nun können Sie mit dem Programmieren loslegen.

Ihr erstes Go-Programm Um Ihr erstes eigenes Programm in Go zu schreiben, erstellen Sie zunächst in Visual Studio Code eine neue Datei. Klicken Sie dazu in der Menüleiste auf DATEI | NEUE DATEI. Geben Sie dann folgende Befehle ein (siehe Abbildung 1.7): package main



import "fmt"



func main() {

fmt.Println("Hallo Welt!")

}

Haben Sie alles eingetippt, drücken Sie + (macOS) oder + (Windows), um diese Datei zu speichern. Wählen Sie als

Dateinamen main.go. Wenn Sie zum ersten Mal ein Go-Programm in Visual Studio Code schreiben, öffnet sich unter Umständen ein Hinweisfenster, in dem Sie zusätzliche Plug-ins für Go herunterladen können. Ich empfehle Ihnen, die vorgeschlagenen Plug-ins alle zu installieren.

Abbildung 1.7: Zur Einführung in die Programmierung mit Go schreiben Sie ein typisches »Hallo Welt«-Programm.

Legen Sie zum Speichern der Programmdateien für dieses Buch am besten neue Ordner an und nutzen Sie die jeweilige Kapitelnummer als Ordnername. Die Datei main.go speichern Sie also in einem Ordner namens Kapitel 1 in Ihrem Benutzerverzeichnis. Auf einem Mac sieht das wie folgt aus: ~/Kapitel 1

|__main.go

Und unter Windows: C:\Benutzer\IhrName\Kapitel 1

|__main.go

Sobald die Datei gespeichert wurde, erscheinen Ihre eingegebenen GoBefehle in farblicher Codierung: hellblau für bestimmte Schlüsselwörter wie package, import und func, orange für Zeichenketten wie Hallo Welt! oder fmt und gelb für Funktionen wie main() und Println().

Kompilieren und Ausführen Ihres Programms Nachdem Sie ein Programm gespeichert haben, müssen Sie es kompilieren. Erst dann kann es ausgeführt werden. Um Ihr Programm direkt in Visual Studio Code auszuführen, klicken Sie in der Menüleiste auf TERMINAL | NEUES TERMINAL. Es öffnet sich ein Kommandozeilenfenster im unteren Bereich von Visual Studio Code (siehe Abbildung 1.8).

Abbildung 1.8: Die Kommandozeile kann direkt in Visual Studio Code aufgerufen werden.

Wechseln Sie nun zum Verzeichnis Kapitel 1. Unter macOS geben Sie dazu folgenden Befehl ein: $ cd ~/"Kapitel 1"

Und unter Windows geben Sie diesen Befehl ein: $ cd "C:\users\IhrName\Kapitel 1"

Jetzt können Sie die Datei main.go mit folgendem Befehl kompilieren: $ go build main.go

Beim Kompilieren wird aus dem Programmcode der Datei main.go eine ausführbare Datei erzeugt und automatisch im Ordner Kapitel 1 gespeichert. Um diese Datei namens main unter macOS auszuführen, geben Sie folgenden Befehl ein: $ ./main

Hallo Welt!

Wird die Zeichenkette Hallo Welt! ausgegeben? Dann herzlichen Glückwunsch! Sie haben erfolgreich Ihr erstes Programm mit Go geschrieben. Unter Windows erzeugt der build-Befehl aus Ihrem Code eine ausführbare Anwendung namens main.exe. Um sie auszuführen, geben Sie folgenden Befehl ein: C:\users\IhrName\Kapitel 1>main.exe

Hallo Welt!

Da man den geschriebenen Programmcode oft direkt nach dem Kompilieren testen möchte, gibt es den Befehl run, mit dem Sie das Kompilieren und Ausführen in einem Rutsch erledigen: $ go run main.go

Funktionsweise eines Go-Programms Ihr erstes Go-Programm hat hoffentlich funktioniert. Aber wie eigentlich? Schauen wir uns den Code einmal Zeile für Zeile an. Die erste Zeile legt den Namen des Pakets (package) für dieses Programm fest: package main

Go-Programme werden in Paketen organisiert. Ein Paket ist eine Sammlung aus Quelldateien, die sich alle im selben Verzeichnis befinden. In diesem Beispiel verweist main auf das Paket, das Sie im Verzeichnis Kapitel 1 gespeichert haben. Wenn Sie weitere Quelldateien (.go-Dateien) hinzufügen, werden sie alle diesem mainPaket zugeordnet (mehr dazu in späteren Kapiteln). Pakete müssen nicht zwingend den Namen main erhalten. Bei der Namenswahl sind Ihnen fast keine Grenzen gesetzt. Allerdings hat der Paketname main eine besondere Bedeutung: Alle Pakete mit diesem Namen enthalten eine Funktion namens main(), die als Einstiegspunkt für Ihr Programm dient. Auch der Dateiname muss nicht unbedingt mit dem Namen des enthaltenen Pakets übereinstimmen. Ich hätte meine Datei statt main.go auch hund.go nennen können – das Programm hätte trotzdem funktioniert (nur mit dem Unterschied, dass auch die ausführbare Anwendung automatisch den Namen hund statt main erhalten hätte). Die nächste Codezeile importiert ein Paket namens fmt: import "fmt"

Dieses Paket umfasst diverse Funktionen, mit denen Sie Ausgaben formatieren und an die Konsole senden können, sowie Funktionen zum Erfassen von Benutzereingaben. Falls Ihnen einige Begriffe aus dem Programmierjargon noch nicht geläufig sind: Eine Funktion ist ein Block aus Codezeilen, die eine bestimmte Aufgabe erfüllen. Weitere Details zu GoFunktionen bietet Kapitel 5. Der nächste Codeblock stellt den Einstiegspunkt Ihres Programms dar: func main() {



}

Da der Paketname main lautet, wird Ihr Programm bei der Ausführung zuerst diese main()-Funktion durchlaufen. Die letzte Zeile Ihres Programmcodes ruft die Println()-Funktion aus dem Paket fmt auf, um die Zeichenkette Hallo Welt! in der Konsole auszugeben: fmt.Println("Hallo Welt!")

Go-Dateistrukturen Sie wissen nun, wie ein einfaches Go-Programm funktioniert. Aber wie werden die einzelnen Go-Dateien gruppiert und organisiert? Wie im vorigen Abschnitt erwähnt, gehören alle Dateien innerhalb desselben Verzeichnisses auch zum selben Paket. Zur Veranschaulichung fügen wir deshalb jetzt dem Verzeichnis Kapitel 1 eine neue Datei hinzu, der wir den Namen show_time.go geben. (Wie Sie eine neue Datei erstellen und speichern, wurde im Abschnitt Ihr erstes Go-Programm erklärt.) Im Verzeichnis Kapitel 1 befinden sich nun also folgende Dateien: Kapitel 1

|__main.go

|__show_time.go

Tragen Sie folgende Codezeilen in die Datei show_time.go ein: package main



import (

"fmt"

"time"

)



func displayTime() {

fmt.Println(time.Now())

}

Wie Sie anhand der ersten Zeile sehen, gehört diese Datei zum Paket main. Wenn Sie mehr als ein Paket importieren möchten, müssen die

Paketnamen von Klammern umschlossen sein. In diesem Beispiel werden die Pakete time und fmt importiert. Danach folgt eine Funktion namens displayTime(), die mithilfe der Funktion Now() des timePakets die aktuelle Uhrzeit inklusive Datum ausgibt. Da die displayTime()-Funktion zum main-Paket gehört, kann sie auch in main.go aufgerufen werden: package main import "fmt" func main() { fmt.Println("Hallo Welt!") displayTime() }

Funktionen, die im selben Paket definiert sind, können aufgerufen werden, ohne dass Sie das Paket explizit importieren müssen. Da nun zwei Dateien zum Paket main gehören, müssen Sie beim Kompilieren keinen Dateinamen mehr angeben. Stattdessen führen Sie den Befehl build innerhalb des Verzeichnisses Kapitel 1 aus: $ go build

Wenn Sie nun in das Verzeichnis Kapitel 1 schauen, befindet sich dort eine neue Datei namens  Kapitel_1 (Kapitel_1.exe unter Windows). Um diese Datei unter macOS auszuführen, geben Sie Folgendes im Terminal ein: $ ./Kapitel_1

Unter Windows verwenden Sie folgenden Befehl: C:\users\IhrName\Kapitel 1>Kapitel_1

Sie sollten nun eine Ausgabe ähnlich der folgenden sehen: Hallo Welt!

2020-10-01 12:01:13.412568 +0800 +08 m=+0.000365532

Kompilieren von Programmen für mehrere Betriebssysteme Bei der Installation von Go werden automatisch mehrere GoUmgebungsvariablen eingerichtet, damit Ihre Go-Programme korrekt funktionieren. Insbesondere erkennt das Installationsprogramm bestimmte Werte der Host-Architektur und des genutzten Betriebssystems, die für die Umgebungsvariablen GOHOSTARCH beziehungsweise GOHOSTOS nötig sind. Die Werte dieser zwei Variablen geben die Zielplattform an, für die Ihre Programme kompiliert werden. Wenn Sie sich diese Werte der Go-Umgebungsvariablen anzeigen lassen möchten, nutzen Sie den Befehl env: $ go env

GOARCH="amd64"

GOBIN=""

GOCACHE="/Users/weimenglee/Library/Caches/go-build"

GOEXE=""

GOFLAGS=""

GOHOSTARCH="amd64"

GOHOSTOS="darwin"

GOOS="darwin"





PKG_CONFIG="pkg-config"

Um Ihr Programm für ein anderes Betriebssystem zu kompilieren, müssen Sie zwei weitere Umgebungsvariablen anpassen: GOOS und GOARCH. Diese beiden Variablen konfigurieren das Ziel-Betriebssystem anhand der in Tabelle 1.1 gezeigten Werte. Betriebssystem GOOS GOARCH

Betriebssystem GOOS GOARCH macOS

darwin

amd64

Linux

linux

amd64

Windows

windows amd64

Tabelle 1.1: Umgebungsvariablen für verschiedene Betriebssysteme

Um ein Programm für macOS zu kompilieren, nutzen Sie die folgenden Befehle und Optionen: $ GOOS=darwin GOARCH=amd64 go build -o Kapitel_1-mac

Wenn Go in naher Zukunft nativ auf Apple Silicon portiert wird, wäre der Wert von GOARCH entsprechend arm64. Um ein Programm für Windows OS zu kompilieren, sind folgende Befehle und Optionen nötig: $ cd ~/"Kapitel 1"

$ GOOS=windows GOARCH=amd64 go build -o Kapitel_1-windows.exe

Über die Option -o (kurz für Output) können Sie einen Namen für die ausführbare Datei angeben. Der vorgenannte Befehl kompiliert das Paket im Verzeichnis Kapitel 1 für Windows und speichert die ausführbare Datei als Kapitel_1windows.exe. Um ein Programm für Linux zu kompilieren, nutzen Sie folgende Befehle und Optionen: $ GOOS=linux GOARCH=amd64 go build -o Kapitel_1-linux

Falls Sie mit Go auf dem Raspberry Pi arbeiten, nutzen Sie für GOARCH den Wert arm64.

Wenn auf Ihrem Computer macOS oder Linux läuft, können Sie die für die jeweilige Plattform erstellten ausführbaren Dateien mit dem fileBefehl überprüfen: $ file Kapitel_1-mac

Kapitel_1-mac: Mach-O 64-bit executable x86_64



$ file Kapitel_1-windows.exe

Kapitel_1-windows.exe: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows



$ file Kapitel_1-linux

Kapitel_1-linux: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=bSETwZgNDR5vlulRHnzw/KNpENRt9Hipd8Nu7HGDg/v38ZPzDs35y Mw33hUxoz/Y_cNfU8fID2cCtz36hCq, not stripped

Vergleich von Go mit anderen Programmiersprachen Beim Erlernen einer neuen Programmiersprache ist es oft hilfreich, einen Vergleich mit anderen Programmiersprachen anzustellen, die Sie vielleicht schon kennen. Im Idealfall helfen Ihnen Ihre vorhandenen Kenntnisse auch bei der neuen Sprache. In diesem Abschnitt vergleiche ich Go mit zwei branchenweit besonders häufig verwendeten Programmiersprachen, nämlich mit Java und Python. Gelegentlich ist auch ein Vergleich mit C sinnvoll, da Go syntaktische Ähnlichkeiten zu dieser Sprache aufweist. Zudem wird Go oft nachgesagt, es vereine die Geschwindigkeit von C mit der Produktivität von Python.

Wenn Sie noch keine dieser Programmiersprachen in Ihrem Repertoire haben, ist das nicht schlimm. Alle hier erwähnten Funktionen werden in den weiteren Kapiteln dieses Buches ausführlich vorgestellt.

Syntax In Sachen Syntax weist Go mehr Ähnlichkeiten mit den Programmiersprachen C und Java auf, bei denen Codeblöcke in geschweifte Klammern gesetzt werden. Python hingegen rückt die Programmzeilen ein, um verschiedene Codeblöcke auch visuell voneinander zu trennen. Ebenso wie Python stellt Go Funktionen in den Mittelpunkt, während sich bei Java alles um Klassen dreht und sogar Funktionen in Klassen eingeschlossen werden müssen. Im Gegensatz zu Python und Java bietet Go keine Unterstützung für die objektorientierte Programmierung (OOP) und Vererbung. Dafür gibt es in Go zur Strukturierung sogenannte Interfaces und Structs, die genau wie Klassen funktionieren. Wie Java nutzt auch Go die statische Typisierung. Python ist eine dynamisch typisierte Sprache.

Kompilierung Während Python und Java in Bytecode kompiliert werden, der dann übersetzt und auf einer virtuellen Maschine ausgeführt wird, liefert Go beim Kompilieren direkt Maschinencode. Aus diesem Grund ist Go besonders leistungsfähig. Genau wie Python und Java unterstützt auch Go die automatische Speicherbereinigung (Garbage Collection). Bei diesem Vorgang zur Speicherverwaltung sucht der Garbage Collector nach Objekten, die von einem Programm nicht mehr benötigt werden, um den dadurch belegten Speicherplatz wieder freizugeben.

Python verschlingt eine ganze Menge Arbeitsspeicher. Java ist auch nicht viel besser, da Speicherressourcen dynamisch angefordert werden. Im Gegensatz dazu können Sie den Arbeitsspeicherbedarf bei Go besser steuern.

Nebenläufigkeit Parallelisierung und Nebenläufigkeit sind in Go integriert – deswegen lassen sich Multithreading-Anwendungen sehr einfach programmieren. Sowohl Java als auch Python unterstützen die Nebenläufigkeit durch Threading, allerdings nicht so effizient wie Go. Tatsächlich ist die Nebenläufigkeit eines der wichtigsten Argumente, die für Go sprechen.

Bibliotheken Alle drei Programmiersprachen bieten umfassende Unterstützung für Bibliotheken, und zwar sowohl für Standard- als auch für DrittanbieterBibliotheken. Besonders letztere entscheiden oft darüber, ob sich eine Programmiersprache dauerhaft etablieren kann. Aus diesem Grund ist vor allem Python seit einigen Jahren enorm beliebt – dank der Unterstützung für Drittanbieter-Bibliotheken zur Datenanalyse erhält auch die Allgemeinheit Zugang zu maschinellem Lernen und Deep Learning. In dieser Hinsicht hängt Go zwar etwas hinterher, da es die Sprache ja noch nicht so lange gibt, doch die Anzahl an verfügbaren Bibliotheken für Go nimmt stetig zu.

Kapitel 2

Datentypen IN DIESEM KAPITEL Variablen und Konstanten deklarieren Ungenutzte Variablen entfernen Wie man Zeichenketten modifiziert Werte in andere Datentypen konvertieren

In diesem Kapitel beschäftigen wir uns mit einem Kernthema der Programmierung, nämlich mit dem Deklarieren von Variablen und Konstanten in Go. Außerdem lernen Sie, wie Sie Zeichenketten manipulieren und Werte in andere Datentypen konvertieren können. Bei der Arbeit mit Go werden Ihnen vier verschiedene Datentypen begegnen: Einfache Datentypen: Beispiele sind Zeichenketten (Strings), Zahlen und boolesche Werte. Zusammengesetzte Datentypen: Beispiele sind Arrays und Structs. Referenztypen: Beispiele sind Zeiger (Pointer), Slices, Funktionen und Kanäle. Schnittstellen: Eine Schnittstelle (Interface) ist eine Sammlung von Methodensignaturen. Dieses Kapitel stellt Ihnen die einfachen Datentypen in Go näher vor. (Die anderen Datentypen werden in nachfolgenden Kapiteln behandelt).

Deklarieren von Variablen In der Programmierung bezeichnet der Begriff Variable ein Konstrukt zum Speichern bestimmter Werte. Diese Werte können sich im Laufe des Programms ändern. In Go lassen sich Variablen auf unterschiedliche Weise deklarieren und initialisieren, wie Sie in den folgenden Abschnitten sehen werden.

Verwenden des var-Schlüsselworts: implizite Typisierung Die erste Möglichkeit zum Deklarieren einer Variablen besteht darin, dem Variablennamen das Schlüsselwort var voranzustellen und dann einen Wert zuzuweisen: package main



import "fmt"



func main() {

var num1 = 5 fmt.Println(num1)

// impliziter Datentyp

// 5

}

Text nach doppelten Schrägstrichen (//) wird von Go als Kommentar interpretiert und beim Kompilieren ignoriert. Gewöhnen Sie sich am besten an, Ihren Code mit erklärenden Kommentaren zu versehen. So lässt sich später besser nachvollziehen, wie Ihr Programm aufgebaut ist und funktioniert. In obigem Beispiel ist num1 eine Variable vom Typ int. Dieser Typ wird für Ganzzahlen genutzt. Da Sie der Variablen den Wert 5 zugewiesen haben, kann Go den Datentyp entsprechend ableiten.

Wenn Sie in Go eine Variable deklarieren, aber im Programm gar nicht nutzen (zum Beispiel zur Ausgabe des Wertes), meldet der Compiler einen Fehler. Solange Sie den Fehler nicht korrigieren, kann Ihr Programm nicht kompiliert werden. Aus diesem Grund wird num1 im Beispiel mithilfe der Println()-Funktion ausgegeben. Eine Variable lässt sich auch außerhalb einer Funktion deklarieren, wie folgendes Beispiel zeigt: package main



import "fmt"



var num1 = 5

// impliziter Datentyp



func main() {

fmt.Println(num1) // 5

}

Variablen, die Sie außerhalb von Funktionen deklarieren, können von allen Funktionen genutzt werden.

Angeben des Datentyps: explizite Typisierung Beim Deklarieren von Variablen können Sie den Datentyp auch selbst spezifizieren: package main



import "fmt"



func main() {

var num1 = 5 var num2 int

fmt.Println(num1)

// impliziter Datentyp

// expliziter Datentyp

fmt.Println(num2)

}

In diesem Beispiel wurde für num2 explizit der Datentyp int festgelegt. Wenn Sie den Wert dieser Variablen ausgeben lassen, ist er 0. Das liegt daran, dass eine deklarierte Variable ohne Initialisierung automatisch auf den Nullwert des jeweiligen Datentyps gesetzt wird. Die Nullwerte für die verschiedenen Datentypen lauten: var num3 float32

// Gleitkommazahl-Variable

var name string

// Zeichenketten-Variable

var gewitter bool

// boolesche Variable



fmt.Println(num3) fmt.Println(name)

// 0

// "" (leere Zeichenkette)

fmt.Println(gewitter) // false

Sie können den Wert einer Variablen auch gleichzeitig explizit deklarieren und initialisieren: var anteile float32 = 4.5

// als float32 deklariert und

// dann initialisiert

Verwenden des Operators zur Kurzdeklaration von Variablen Der Operator zur Kurzdeklaration von Variablen (:=) stellt eine weitere Möglichkeit dar, wie Sie Variablen deklarieren und initialisieren können: vorname := "Wei-Meng"

Hier wird die Variable vorname mit dem Wert "Wei-Meng" initialisiert und dadurch als string deklariert – ohne das Schlüsselwort var. Sie können sogar mehrere Variablen (auch unterschiedlichen Typs) auf diese Weise mit nur einem Befehl deklarieren und initialisieren: vorname, nachname, alter := "Wei-Meng", "Lee", 25

Mit dem Schlüsselwort var funktioniert dies übrigens auch:

var vorname, nachname string = "Wei-Meng", "Lee"

Allerdings müssen die Variablen in dem Fall alle denselben Typ haben. Folgender Befehl ist somit nicht erlaubt: var vorname, nachname string, age int = "Wei-Meng",

"Lee", 25

Wenn Sie aber den Datentyp weglassen, funktioniert es: var vorname, nachname, alter = "Wei-Meng", "Lee", 25

Alternativ (und übersichtlicher) können Sie die Variablen wie folgt deklarieren: var (

Vorname

string = "Wei-Meng"

nachname string = "Lee"

alter int = 25

)

Den Operator := dürfen Sie nicht zur Kurzdeklaration und Initialisierung von Variablen außerhalb von Funktionen nutzen. Folgender Code ist also unzulässig: import (

"fmt"

)



num1 := 5

// Fehler; Kurzdeklaration

// außerhalb der Funktion



func main() {



fmt.Println("Hallo Welt!")

}

Mit dem Operator := können Sie Variablen nur innerhalb von Funktionen deklarieren und initialisieren.

Deklarieren von Konstanten Genau wie Variablen dienen auch Konstanten zum Speichern von Werten. Doch im Unterschied zu Variablen bleiben die Werte von Konstanten nach der Initialisierung immer gleich. Deklariert werden Konstanten in Go auf dieselbe Weise wie Variablen, nur dass das Schlüsselwort var durch das Schlüsselwort const ersetzt wird: package main



import "fmt"



const verlag = "Wiley"



func main() {

fmt.Println(verlag)

}

Das const-Schlüsselwort dürfen Sie überall dort verwenden, wo auch var genutzt werden darf.

Entfernen von ungenutzten Variablen Wenn Sie schon mal selbst programmiert haben, kennen Sie bestimmt folgende Situation: Sie deklarieren zu Beginn einige Variablen, schreiben dann Ihr Programm – und nutzen dann aber gar nicht alle Variablen. Schauen Sie sich folgendes Beispiel an: package main



import (

"fmt"

)



func main() {

var num1 = 5

fmt.Println("Hallo Welt!")

}

Die Variable num1 wird deklariert und mit dem Wert 5 initialisiert. Im Programm wird sie aber nirgendwo tatsächlich genutzt. In so einem Fall liefert der Compiler eine Fehlermeldung (num1 declared but not used), sobald Sie versuchen, das Programm auszuführen. Im FAQAbschnitt auf der Go-Website steht dazu sinngemäß: Das Vorhandensein einer ungenutzten Variablen kann auf einen Bug hindeuten. Ungenutzte Importe verlangsamen den Kompilierungsvorgang. Je mehr ungenutzte Importe Ihr Programmcode umfasst, desto langsamer läuft alles ab. Aus diesem Grund ist in Go beides nicht zulässig. Wie in dieser Erläuterung erwähnt, gibt der Compiler einen ähnlichen Fehler aus, wenn Sie ein Paket importieren, dann aber gar nicht nutzen. Interessanterweise beschwert sich der Compiler jedoch nicht, wenn Sie eine Variable außerhalb einer Funktion deklarieren und dann nicht nutzen. Das folgende Beispiel würde der Compiler problemlos akzeptieren: package main



import (

"fmt"

)



var num1 = 5



func main() {

fmt.Println("Hallo Welt!")

}

Alle Variablen, die Sie innerhalb von Funktionen definiert haben, müssen Sie im Programm auch tatsächlich verwenden. Sonst gibt es eine Fehlermeldung. Sollten Sie aus irgendeinem Grund unbedingt eine ungenutzte Variable innerhalb einer Funktion benötigen, bietet Go eine Behelfslösung. Weisen Sie die Variable einfach einem »leeren« Bezeichner (_) zu: var num1 = 5

_ = num1

// Jetzt ist der Compiler zufrieden!

Verwenden von Strings Ein String, also eine Zeichenkette, ist in Go eine nur lesbare Slice aus Bytes. Was genau Slices sind, wird in Kapitel 6 erklärt. Für den Moment genügt es, wenn Sie sich einen String wie eine Gruppierung mehrerer Bytes vorstellen. In einem der vorigen Beispiele kam bereits ein String vor: vorname string = "Wei-Meng"

Ein String kann spezielle Zeichenkombinationen enthalten (zum Beispiel \n oder \t), wie folgender Befehl zeigt: adresse := "The White House\n1600 Pennsylvania Avenue

NW\nWashington, DC 20500"

Wenn die Variable adresse mit der Println()-Funktion ausgegeben wird, sieht diese Ausgabe so aus:

The White House

1600 Pennsylvania Avenue NW

Washington, DC 20500

Go unterstützt auch Raw-Strings. Solche Strings werden durch umschließende rückwärts geneigte Hochkommas (``) markiert, die in der Informatik als Backticks bekannt sind. Raw-Strings können sich über mehrere Zeilen erstrecken und es gelten keine speziellen Zeichenkombinationen. Hier ein Beispiel: Zitat := `"Wer noch nie einen Fehler

gemacht hat, hat sich noch nie

an etwas Neuem versucht."

--Albert Einstein`



fmt.Println(zitat)

Die Ausgabe dieses Codeblocks ist: "Wer noch nie einen Fehler

gemacht hat, hat sich noch nie

an etwas Neuem versucht."

--Albert Einstein

Bei Bedarf lassen sich Unicode-Zeichen in Strings aufnehmen, wie folgendes Beispiel zeigt: str1 := "你好, 世界" str2 := "こんにちは世界"

// Chinesisch

// Japanisch

Anstelle der Zeichen können Sie auch den Code für jedes Zeichen in Ihrem String eingeben: str3 := "\u4f60\u597d\uff0c\u4e16\u754c" // 你好,世界

Wenn Sie chinesische Schriftzeichen in die Unicode-Darstellung konvertieren möchten, können Sie dies unter www.chineseconverter.com/de/convert/unicode tun.

Jedes chinesische oder japanische Schriftzeichen benötigt drei Bytes. Die Funktion len() liefert die Länge der Strings: fmt.Println(len(str1)) fmt.Println(len(str2)) fmt.Println(len(str3))

// 15 = 5 Zeichen * 3 Bytes

// 21 = 7 Zeichen * 3 Bytes

// 15 = 5 Zeichen * 3 Bytes

Die Anzahl der einzelnen Zeichen (Runen) in einem String können Sie mit der Funktion RuneCountInString() zählen: fmt.Println(utf8.RuneCountInString(str1)) // 5

fmt.Println(utf8.RuneCountInString(str2)) // 7

fmt.Println(utf8.RuneCountInString(str3)) // 5

Der Begriff Rune bezeichnet ursprünglich ein Schriftzeichen in der Sprache der Germanen.

Konvertieren von Datentypen In der Programmierung spricht man von Typumwandlung, wenn ein bestimmter Wert von einem Datentyp in einen anderen konvertiert wird. Angenommen, Sie haben einen String mit dem Wert "45". Da es sich um einen String und nicht um einen numerischen Datentyp handelt, können Sie mit dieser 45 keine mathematischen Operationen durchführen. Dazu müsste der String zuerst in einen Integer-Datentyp umgewandelt werden. Und weil Go eine stark typisierte Sprache ist, müssen Sie alle Typumwandlungen explizit selbst vornehmen. Bevor wir dies an Beispielen üben, schauen wir uns an, wie Sie denn überhaupt den Typ einer Variablen herausfinden.

Herausfinden des Datentyps einer Variablen Beim Erstellen Ihrer Variablen können Sie den Typ auch implizit angeben (siehe Verwenden des var-Schlüsselworts: implizite Typisierung). Daher kann es vorkommen, dass Sie den Datentyp einer Variablen überprüfen möchten. Schauen Sie sich folgendes Beispiel an:

vorname, nachname, alter := "Wei-Meng", "Lee", 25

Die Datentypen liegen auf der Hand: vorname und nachname sind vom Typ string und alter ist vom Typ int. Aber wie sieht es mit folgendem Befehl aus? start := time.Now()

// Time-Paket muss importiert werden

Welchen Datentyp hat start? Hier wird's schon kniffliger. Es gibt zwei Methoden, wie Sie den Datentyp einer Variablen herausfinden: Sie nutzen das Verb %T der Println()-Funktion zur Ausgabe des Typs. Der Befehl sieht so aus: fmt.Printf("%T\n", start)

// time.Time

Der gesuchte Datentyp ist also time.Time. Unter https://golang.org/pkg/fmt/ finden Sie eine Übersicht aller Verben des Pakets fmt zum Ausgeben formatierter Inhalte in Go. Sie nutzen das reflect-Paket. Mithilfe des reflect-Pakets können Sie ebenfalls den Datentyp einer Variablen herausfinden (vor allem bei Verwendung von Interfaces – mehr dazu in Kapitel 10). Für das obige Beispiel finden wir mit der Funktion TypeOf() den Datentyp der Variablen heraus, während die Funktionen ValueOf() und Kind() die Datenstruktur einer Variablen liefern: fmt.Println(reflect.TypeOf(start))

// time.Time

fmt.Println(reflect.ValueOf(start).Kind()) // struct

Umwandeln des Datentyps einer Variablen Viele Programme machen es erforderlich, den Wert einer Variablen in einen anderen Datentyp zu konvertieren. Dazu folgendes Beispiel: var alter int

fmt.Print("Bitte geben Sie Ihr Alter ein: ")

fmt.Scanf("%d", &alter)

fmt.Println("Sie haben eingegeben:", alter)

In diesem Codeblock wird zunächst die Variable alter vom Typ int (Ganzzahl) deklariert. Dann erfasst die Funktion Scanf() eine Benutzereingabe in der Konsole und zwar ebenfalls im Ganzzahlformat (erkennbar am Verb %d). Wenn Sie das Programm ausführen und eine Ganzzahl eingeben, funktioniert alles wie erwartet: $ go run main.go

Bitte geben Sie Ihr Alter ein: 45

Sie haben eingegeben: 45

Wenn Sie aber stattdessen einen String eingeben, passiert Folgendes: $ go run main.go

Bitte geben Sie Ihr Alter ein: fünfundvierzig

Sie haben eingegeben: 0

$ ünfundvierzig

bash: ünfundvierzig: command not found

Und wenn Sie eine Kombination aus einer numerischen Angabe und einem String eingeben, sieht das Ergebnis wie folgt aus: $ go run main.go

Bitte geben Sie Ihr Alter ein: 44-einhalb

Sie haben eingegeben: 44

$ einhalb

bash: einhalb: command not found

Den Grund für diese unterschiedlichen Ergebnisse liefert uns die Scanf()-Funktion. Diese Funktion erfasst die Benutzereingabe im Standardeingabegerät (Konsole) und speichert aufeinanderfolgende, durch Leerzeichen getrennte Werte in aufeinanderfolgenden Argumenten, wie durch die angegebenen Formatverben festgelegt. In diesem Beispiel sucht die Funktion also nach einem numerischen Wert und sobald sie einen findet, wird der nächste Befehl im Codeblock ausgeführt. Deshalb wird bei der Eingabe von fünfundvierzig für die Variable alter der Nullwert ausgegeben (da die Benutzereingabe keinen

numerischen Wert enthielt), während im zweiten Fall die Ausgabe nur aus den ersten beiden Ziffern (44) besteht (da der Rest der Benutzereingabe kein numerisches Format darstellt). Zu beachten ist auch, dass alle verbleibenden Werte, die nicht den Vorgaben entsprechen, zur Fortführung des Programms genutzt und wie eingegebene Befehle behandelt werden (folglich wird im Beispiel ein Fehler ausgegeben, da es sich nicht um gültige Befehle handelt). Damit dieses Programmbeispiel besser funktioniert, sollten Sie der Eingabevariablen den string-Typ zuweisen und die Benutzereingabe wie folgt erfassen: var eingabe string

fmt.Print("Bitte geben Sie Ihr Alter ein: ")

fmt.Scanf("%s", &eingabe)

Das &-Zeichen repräsentiert die Speicheradresse der Variablen. In diesem Beispiel liest die Funktion Scanf() die Benutzereingabe und weist diesen Wert dann der Speicheradresse von eingabe zu. Danach können Sie versuchen, mit der Atoi()-Funktion des strconvPakets den String in einen Ganzzahlwert umzuwandeln: alter, fehl := strconv.Atoi(eingabe) // string zu int

// konvertieren

Atoi steht für ASCII to integer. Umgekehrt steht Itoa für Integer to ASCII. Die Atoi()-Funktion liefert zwei Werte: das Ergebnis der Umwandlung und den Fehler (sofern einer aufgetreten ist). Wenn es keinen Fehler gegeben hat, enthält die Variable fehl den Wert nil. Sie müssen also prüfen, ob der Wert von fehl ungleich nil ist: if fehl != nil { fmt.Println(fehl)

// ein Fehler ist aufgetreten

} else {

fmt.Println("Ihr Alter ist:", alter)

}

Um Strings in andere Typen umzuwandeln, beispielsweise in boolesche Werte, Gleitkommazahlen oder Ganzzahlwerte, gibt es mehrere ParseFunktionen: b, fehl := strconv.ParseBool("t")

fmt.Println(b) // true

fmt.Println(fehl) //

fmt.Printf("%T\n", b) // bool



f, fehl := strconv.ParseFloat("3.1415", 64)

fmt.Println(f) // 3.1415

fmt.Println(fehl) //

fmt.Printf("%T\n", f) // float64



i, fehl :=

strconv.ParseInt("-18.56", 10, 64) // Basis

fmt.Println(i) fmt.Println(fehl) fmt.Printf("%T\n", i)

// 10, 64 Bit

// 0

// strconv.ParseInt: parsing

// "-18.56": invalid syntax

// int64



u1, fehl := strconv.ParseUint("18", 10, 64)

fmt.Println(u1) fmt.Println(fehl) fmt.Printf("%T\n", u1)

// 18

//

// uint64



u2, fehl := strconv.ParseUint("-18", 10, 64)

fmt.Println(u2) // 0

fmt.Println(fehl) // strconv.ParseUint: parsing

fmt.Printf("%T\n", u2)

// "-18": invalid syntax

// uint64

Um zwischen verschiedenen numerischen Datentypen wie int und float zu konvertieren, können Sie ganz einfach die Funktionen int(), float32() und float64() verwenden: num1 num2 num3 num4

:= := := :=

5

float32(num1)

float64(num2)

float32(num3)

num5 := int(num4)



fmt.Printf("%T\n", fmt.Printf("%T\n", fmt.Printf("%T\n", fmt.Printf("%T\n", fmt.Printf("%T\n",

num1) num2) num3) num4) num5)

// // // // //

int

float32

float64

float32

int

Die darstellbaren Wertebereiche für die verschiedenen Datentypen finden Sie unter https://golang.org/ref/spec#Numeric_types. (Eine inoffizielle deutsche Übersetzung der Seite gibt es unter https://bitloeffel.de/DOC/golang/go_spec_de.html#Numeric _types.)

Interpolieren von Strings Eine weitere typische Aufgabe bei der Programmierung besteht darin, die Werte mehrerer Variablen in einem einzigen String auszugeben. Nehmen wir folgendes Beispiel: nummer := 5

name := "Karsten"

Nun möchten Sie einen String bilden, der das Ergebnis in dieser Form anzeigt: Karsten, Ihre Warteschlangennummer ist 5. Die einzelnen Elemente können Sie jedoch nicht einfach so zusammensetzen: s := name + ", Ihre Warteschlangennummer ist " + nummer

Das wäre nicht zulässig, denn nummer ist ein Ganzzahlwert und Werte vom Typ string und integer dürfen nicht direkt verkettet werden. Das macht aber nix. Sie können zum Beispiel einfach die integer-Variable in den string-Typ umwandeln und dann beide Strings problemlos aneinanderfügen: s := name + ", Ihre Warteschlangennummer ist " +

strconv.Itoa(nummer)

Allerdings wäre das keine besonders elegante Lösung. Je mehr Variablen unterschiedlichen Typs Sie verketten möchten, desto unübersichtlicher wird es. Eine besser Lösung bietet die Sprintf()-Funktion des fmt-Pakets: s := fmt.Sprintf("%s, Ihre Warteschlangennummer ist %d",

name, nummer)

Die Sprintf()-Funktion formatiert einen String gemäß den angegebenen Formatverben (wie %d und %s).

Kapitel 3

Entscheidungsfindung IN DIESEM KAPITEL Entscheidungen mit der if/else-Anweisung Mehrere Bedingungen mit der switch-Anweisung auswerten

Damit ein Programm wirklich nützlich ist, muss es möglich sein, bestimmte Programmschritte in Abhängigkeit der Werte von Variablen und Konstanten auszuführen. Für derartige Entscheidungsprozesse bietet Go verschiedene Konstrukte: if/else-Anweisungen switch-Anweisungen select-Anweisungen

Das dritte Konstrukt – die select-Anweisung – wird für die Kanalkommunikation genutzt. Kapitel 12 widmet sich Kanälen und der select-Anweisung im Detail. In diesem Kapitel erfahren Sie nun, wie if/else- und switchAnweisungen in einem Programm die einzelnen Schritte während der Ausführung beeinflussen können.

Entscheidungen mittels if/else Als Erstes schauen wir uns die if/else-Anweisung an. Die beiden Wörtchen aus dem Englischen bedeuten schlicht »wenn« und »anderenfalls«. Dementsprechend einfach ist das Grundprinzip: »Wenn eine bestimmte Bedingung erfüllt ist, passiert x; anderenfalls passiert y.«

In den nächsten Abschnitten erkläre ich Ihnen, wie Sie diese if/elseAnweisung nutzen können. Wir beginnen mit Grundbausteinen der Entscheidungsfindung, nämlich mit logischen Operatoren und Vergleichsoperatoren.

Grundbausteine der if/else-Anweisung: logische und vergleichende Operatoren Um zu verstehen, wie die if/else-Anweisung funktioniert, ist ein kurzer theoretischer Exkurs nötig. In Go kann eine boolesche Variable (Datentyp bool) einen von zwei Werten annehmen: wahr (true) oder falsch (false). Deswegen spricht man auch von Wahrheitswerten. Auf diesem eigentlich banalen Konzept baut die ganze Programmierung auf. Mithilfe von Wahrheitswerten werden Vergleiche angestellt und die Abläufe von Programmen gesteuert. Ohne boolesche Variablen gäbe es keine Programme! Um einen booleschen Wert zu erhalten, nutzen Sie normalerweise einen Vergleichsoperator. Ein simples Beispiel: num := 6

bedingung := num % 2 == 0

In diesem Codeausschnitt wird mit dem Modulo-Operator (%) der Rest einer Division durch den Wert 2 geprüft. Ist der Rest gleich 0, handelt es sich bei num um eine gerade Zahl. Das folgende Codesegment stellt einen logischen Ausdruck dar: num % 2 == 0

Das Ergebnis ist ein boolescher Wert, und zwar entweder true (wenn num eine gerade Zahl ist) oder false (wenn num eine ungerade Zahl ist). Tabelle 3.1 enthält alle von Go unterstützten Vergleichsoperatoren. Operator Beschreibung

Beispiel

==

gleich

num == 0

!=

ungleich

num != 0

Operator Beschreibung

Beispiel


= 0

num > 0

Tabelle 3.1: Vergleichsoperatoren in Go

In den folgenden Beispielen nutzt die erste Zeile (num := 6) immer den Operator zur Kurzdeklaration (:=), wie in Kapitel 2 erklärt, um der Variablen num den Wert 6 zuzuweisen. Der erste Codeausschnitt nutzt den Operator == mit der Bedeutung »gleich«. Da 6 aber nicht gleich 0 ist, wird als Ergebnis false angezeigt. num := 6

fmt.Println(num == 0)

//

false

Der nächste Ausschnitt nutzt den Operator != mit der Bedeutung »ungleich«. Da 6 ungleich 0 ist, wird als Ergebnis true angezeigt. num := 6

fmt.Println(num != 0)

//

true

Der nun folgende Code nutzt den Operator < mit der Bedeutung »kleiner als«. Da 6 nicht kleiner als 0 ist, wird als Ergebnis false angezeigt. num := 6

fmt.Println(num < 0)

//

false

Es folgt ein Beispiel für den Operator 0)

//

true

Und das letzte Beispiel schließlich nutzt den Operator >= mit der Bedeutung »größer als oder gleich«. Da 6 größer als 0 ist, wird als Ergebnis true angezeigt. num := 6

fmt.Println(num>= 0)

//

true

Um logische Ausdrücke zu kombinieren, benötigen Sie einen logischen Operator. Tabelle 3.2 enthält die drei von Go unterstützten logischen Operatoren. Operator Beschreibung

Beispiel

&&

Logisches UND. Beide Operanden müssen wahr sein, damit die Bedingung als true ausgewertet wird.

x && y

||

Logisches ODER. Mindestens einer der beiden Operanden muss wahr sein, damit die Bedingung als true ausgewertet wird.

x || y

!

Logisches NICHT. Ersetzt einen booleschen Wert durch sein Gegenteil – true wird false und false wird true.

!x

Tabelle 3.2: Logische Operatoren in Go

Die folgenden Beispiele zeigen logische Operatoren in Aktion. Der erste Codeausschnitt prüft, ob eine Zahl größer als 2 und kleiner als 9 ist: num := 6

bedingung := num>2 && num 9 || num 9 || num = len(orig) {

return append(orig, wert), nil

}



orig = append(orig[:index+1], orig[index:]…)

orig[index] = wert

return orig, nil

}

Beachten Sie die Ellipse (…) am Ende der append()-Funktion. Es handelt sich bei append() um eine variadische Funktion – der zweite Parameter nimmt eine sich ändernde Anzahl von Argumenten entgegen. Wenn Sie also die append()-Funktion aufrufen und eine Slice als zweites Argument übergeben wollen, müssen Sie diese zuerst mithilfe der …Notation entpacken, bevor Sie die Slice an die append()-Funktion übergeben können. Die Funktion lässt sich nun testen: t := []int{1, 2, 3, 4, 5}

t, fehl := einfuegen(t, 2, 9)

if fehl == nil {

fmt.Println(t)

// 1 2 9 3 4 5]

} else {

fmt.Println(fehl)

}

Entfernen eines Elements aus einer Slice Beim Entfernen eines Elements gehen Sie ähnlich vor wie beim Hinzufügen eines Elements, nur dass Sie es jetzt etwas einfacher haben. Angenommen, Sie möchten das Element an der durch index angegebenen Position (2 im Beispiel) aus der Slice entfernen (siehe Abbildung 6.17). Dann gehen Sie wie folgt vor: 1. Erstellen Sie eine Slice mit allen Elementen ab [:index] sowie eine Slice mit allen Elementen ab [index+1:]. 2. Hängen Sie die ab [index+1:] erfassten Elemente an die ab [:index] erfassten Elemente an.

Abbildung 6.17: Ein Element wird aus einer Slice entfernt.

Die vollständige loeschen()-Funktion zum Entfernen eines Elements aus einer Slice lautet: func loeschen(orig []int, index int) ([]int, error) {

if index < 0 || index>= len(orig) {

return nil, errors.New("Index außerhalb des Bereichs")

}

orig = append(orig[:index], orig[index+1:]…)

return orig, nil

}

So können Sie die loeschen()-Funktion testen: t := []int{1, 2, 3, 4, 5}

t, fehl := loeschen(t, 2)

if fehl == nil {

fmt.Println(t) } else {

fmt.Println(fehl)

}

// [1 2 4 5]

Kapitel 7

Logische Datenorganisation mit Structs IN DIESEM KAPITEL Structs für Sammlungen aus Datenelementen definieren Structs in Go erzeugen … … und kopieren Methoden in Structs

In Kapitel 6 wird erklärt, wie Sie Arrays und Slices erzeugen, um darin Datenelemente zu gruppieren. In diesem Kapitel stelle ich Ihnen eine weitere Möglichkeit vor, wie Sie Ihre Daten darstellen und organisieren können, nämlich mit Structs. Eine Struct (kurz für Structure) ist ein benutzerdefinierter Typ, mit dem sich zusammengehörige Daten in einer einzigen logischen Einheit gruppieren lassen. Nachfolgend erkläre ich Ihnen, wie Sie eine solche Struktur definieren, initialisieren, kopieren, durch Methoden erweitern und mit anderen Structs vergleichen.

Definieren von Structs für Sammlungen aus Datenelementen Nehmen wir an, Sie möchten die Koordinaten eines Punktes in einem zweidimensionalen Raum speichern. Die x- und die y-Koordinate lassen sich ganz einfach in zwei Variablen hinterlegen: pt1X := 3.1

pt1Y := 5.7

Um einen weiteren Punkt zu speichern, bräuchten Sie auch ein weiteres Variablenpaar: pt2X := 5.6

pt2Y := 3,8

Sie nutzen zwei separate Variablen, x und y, um die Koordinaten eines Punktes zu speichern. Da diese Koordinaten zusammengehören, wäre es doch praktisch, wenn man sie in einer einzigen Variablen hinterlegen könnte. Wie sieht es nun aus, wenn Sie einen Punkt in einem dreidimensionalen Raum beschreiben möchten? In dem Fall brauchen Sie eine dritte Variable zum Speichern der z-Koordinate: pt1X := 3.1

pt1Y := 5.7

pt1Z := 4.2

Wie Sie sich denken können, wird es umso unübersichtlicher, je mehr Punkte und Koordinaten Sie speichern müssen. Ein logischer Ansatz besteht deshalb darin, diese Koordinaten als Einheit in einer einzigen Variablen zu speichern. Und genau dafür eignen sich Structs. Das folgende Programmbeispiel definiert eine Struktur namens punkt mit drei Variablen, die bei Structs als Felder bezeichnet werden: package main



import "fmt"



type punkt struct {

x float32

y float32

z float32

}



func main() {

}

Die Felder innerhalb einer Struktur müssen nicht vom selben Typ sein. Um eine Variable vom Typ punkt zu erstellen, können Sie das varSchlüsselwort genauso verwenden, wie Sie es zum Beispiel bei den Typen int oder string tun würden: var pt1 punkt

Jedes Feld dieser Struktur kann dann individuell initialisiert werden: func main() {

var pt1 punkt

pt1.x = 3.1

pt1.y = 5.7

pt1.z = 4.2

}

Auch die Werte der Felder können Sie individuell abfragen: fmt.Println(pt1.x)

fmt.Println(pt1.y)

fmt.Println(pt1.z)

Ebenfalls möglich ist es, eine Struktur mit einem Struct-Literal zu erzeugen, das heißt durch Angabe der Werte der Felder: pt2 := punkt{x: 5.6, y: 3.8, z: 6.9}

Hier brauchen Sie die Feldnamen nicht anzugeben. Werte werden ihrer Reihenfolge entsprechend den Feldern zugeordnet. Es müssen allerdings für alle Felder Werte spezifiziert werden: pt2 := punkt{5.6, 3.8, 6.9}

Wenn sich das Struct-Literal auf mehrere Zeilen erstreckt, muss nach dem letzten Feld ein Komma folgen: pt2 := punkt{

x: 5.6,

y: 3.8,

z: 6.9,

//