Go 1: Variablen, Datentypen und formatierte Ausgabe
Beim Programmieren in Go sind vorab einige wichtige Sachen zu berücksichtigen:
- Go ist eine stark typisierte Programmiersprache. Variablen haben einen bestimmen Datentyp, und können nur Werte dieses einen Typs annehmen. - Bezeichner (von Variablen, Konstanten, Typen usw.) beginnen mit einem Buchstaben oder einem Unterstrich (Underscore,
_), worauf weitere Buchstaben, Ziffern und Underscores folgen können. Es wird zwischen Gross- und Kleinschreibung unterschieden. Man verwendetCamelCase(und nichtsnake_caseoderkebab-case). - Werden Variablen deklariert aber nirgends verwendet, kann das Programm nicht kompiliert werden. Damit soll sichergestellt werden, dass sich keine unnötigen Variablen in den Code einschleichen. Für diesen ersten Teil ist es also nötig, die deklarierten Variablen im Verlauf des Programms einmal zu verwenden, etwa indem man sie mit
fmt.Println()ausgibt:fmt.Println(a, b, c), falls man die Variablena,bundcdeklariert hat.
Variablen
Variablen (Spec) werden mit dem Schlüsselwort var deklariert:
var [Bezeichner] [Datentyp]Im Gegensatz zu vielen anderen Programmiersprachen wird zuerst der Bezeichner und erst dann der Datentyp angegeben!
Beispiele:
var result int
var caption string
var isReady boolEine neu deklarierte Variable wird mit dem Nullwert (zero value) des jeweiligen Datentyps initialisiert, z.B. 0 bei Ganzzahlen, false bei Wahrheitswerten, oder "" bei Zeichenketten.
Es ist auch möglich, bei der Deklaration einen Wert anzugeben:
var [Bezeichner] [Datentyp] = [Wert]Beispiele:
var result int = 5
var caption string = "Hello"
var isReady bool = trueGibt man einen Wert an, kann der Compiler den Datentyp anhand dieses Werts festlegen. Der Datentyp kann dann auch weggelassen werden:
var result = 5
var caption = "Hello"
var isReady = trueDie Deklaration kann mit folgender Kurzschreibweise und dem Operator := weiter vereinfacht werden:
result := 5
isReady := true
caption := "Hello"Es ist auch möglich, mehrere Variablen in einer Zeile zu deklarieren und zu initialisieren:
var a, b, c = 1, "Hey", false
d, e, f := 2, "Ho", trueKonstanten
Konstanten (Spec) lassen sich mit dem Schlüsselwort const definieren:
const [Bezeichner] [Datentyp] = [Wert]Da sich Konstanten im weiteren Programmverlauf nicht ändern können, muss der Wert gleich bei der Deklaration angegeben werden. Der Datentyp ist wiederum optional, da er vom Compiler erraten werden kann. Beispiele:
const g float32 = 9.81
const pi float64 = 3.14159265359
const name = "Brandon"Konstanten stehen nur für Ausdrücke zur Verfügung, die zur Kompilierzeit ermittelt werden können.
Datentypen
In Go stehen u.a. die folgenden (primitiven) Datentypen (Spec) zur Verfügung:
- Zahlen
- Ganzzahlen (integer)
- vorzeichenbehaftet (signed):
int,int8,int16,int32,int64 - ohne Vorzeichen (unsigned):
uint,uint8,uint16,uint32,uint64byteist ein Alias füruint8
- Die Zahl steht jeweils für die Anzahl verwendeter Bits.
- Bei
intunduintverwendet der Compiler die native Anzahl Bytes der Architektur (z.B. 64 Bits beiamd64)
- vorzeichenbehaftet (signed):
- Gleitkommazahlen:
float32undfloat64
- Ganzzahlen (integer)
- Wahrheitswerte (boolean):
boolmit den Wertentrueundfalse - Zeichen:
rune(ein Unicode-Zeichen und Alias fürint32) - Zeichenketten:
string
Eine rune wird mit dem Wert '0' initialisiert, ein string mit der leeren Zeichenkette "". Ein string besteht aus runes.
Beispiel:
var rooms uint8 = 7
var amount uint64 = 10_000_000
var result int64 = 1e9
var g float32 = 9.81
var pi float64 = 3.141592653589793
var ready bool = false
var ellipsis rune = '…'
var meal string = "Smørrebrød"
var author string = "Достоевский"
fmt.Println(rooms, amount, result, g, pi, ready, ellipsis, meal, author)Ausgabe:
7 10000000 1000000000 9.81 3.141592653589793 false 8230 Smørrebrød Достоевский
_kann als Tausendertrennzeichen verwendet werden.- Die Exponentialschreibweise
1e9bedeutet: 1 * 10^9 (eine Milliarde bzw. eine Eins mit neun Nullen). - In Go können Unicode-Zeichen verwendet werden. Eine
runeist ein sogenannter Unicode Code Point; einstringbesteht aus mehrerenrunes.
Formatierte Ausgabe
Das Package fmt (Doc) stellt Funktionen zur formatierten Ausgabe von Werten zur Verfügung. Die Funktionen mit dem Suffix f (z.B. Printf) erwarten als erstes Argument einen Format-String; als weitere Argumente werden die auszugebenden Ausdrücke erwartet.
Beispiel:
var x byte = 129
fmt.Printf("%d %o %b\n", x, x, x)
var y int = 0xdeadbeef
fmt.Printf("%d %x %X\n", y, y, y)
var z float64 = 10.0 / 3.0
fmt.Printf("%.5f %10.5f %1.1f\n", z, z, z)
var ready bool = false
fmt.Printf("%t %v\n", ready, ready)
var ellipsis rune = '…'
fmt.Printf("%d %c %U\n", ellipsis, ellipsis, ellipsis)
var name string = "Достоевский"
fmt.Printf("%s %q %v\n", name, name, name)Ausgabe:
129 201 10000001
3735928559 deadbeef DEADBEEF
3.33333 3.33333 3.3
false false
8230 … U+2026
Достоевский "Достоевский" Достоевский
- Ganzzahlen können dezimal (
%d), oktal (%o), binär (%b) oder hexadezimal (%xbzw.%X) ausgegeben werden. - Bei Gleitkommazahlen kann die Länge links und rechts vom Komma separat spezifiziert werden (
%X.Yf). - Booleans können mit
%talstrueoderfalseausgegeben werden. - Eine
runekann als dezimaler Wert, als Zeichen oder in Unicode-Notation (Code Point) ausgegeben werden. - Mithilfe von
%qkann ein Wert in Go-Syntax ausgegeben werden. - Mit
%vlassen sich alle Werte ausgeben.
Standardausgabe, Standardfehler
Bei Unix-artigen Betriebssystemen erfolgt der Dateizugriff über sogenannte File Handles, welche von einer Zahl repräsentiert werden. Jedes Programm, auch wenn es keine Dateien öffnet, verfügt über die folgende File Handles:
0(os.Stdin): Standardeingabe1(os.Stdout): Standardausgabe2(os.Stderr): Standardfehler
Funktionen im fmt-Modul mit dem Präfix F erwarten als ersten Parameter einen File Handle:
fmt.Fprintln(os.Stdout, "Hello, Output!")
fmt.Fprintln(os.Stderr, "Hello, Error!")Standardausgabe und -fehler erfolgen normalerweise aufs Terminalfenster, sodass man die Ausgaben auf diese Handles nicht ohne Weiteres unterscheiden kann:
$ go run main.go
Hello, Output!
Hello, Error!
Eine Unix-Shell erlaubt jedoch die Umleitung via > (stdout) und 2> (stderr):
$ go run main.go >out.txt
Hello, Error!
$ cat out.txt
Hello, Output!
$ go run main.go 2>err.txt
Hello, Output!
$ cat err.txt
Hello, Error!
Will man beide Ausgaben in die gleiche Datei umleiten, steht der Operator 2>&1 zur Verfügung:
$ go run main.go >out.txt 2>&1
$ cat out.txt
Hello, Output!
Hello, Error!
Dieser Mechanismus wird gebraucht, um verschiedenartige Ausgaben des gleichen Programms an verschiedene Stellen zu schreiben. Beispielsweise soll der Anwender die Standardausgabe direkt sehen; Fehlermeldungen sollen jedoch nur in der Standardfehlerausgabe erscheinen.
Ausgabe in einen String
Die Funktionen mit dem Präfix S schreiben den formatierten Wert nicht auf die Standardausgabe, sondern geben einen String zurück:
result := fmt.Sprintf("%.3f", 10.0/3.0)
fmt.Printf("10 divided by 3 is %s\n", result)Ausgabe:
10 divided by 3 is 3.333
Kommentare
Kommentare beginnend mit // erstrecken sich bis zum Zeilenende.
Mehrzeilige Kommentare beginnen mit /* und enden mit */.
Beispiel:
var g float32 = 9.81 // approximation of the gravity constant
/* these variables are used
for some intermediary
computations to be used
later in the program. */
var a, b, c int