Files
Lino 1b13aaed60 Update 02.2.md
fix typo
2019-02-07 11:28:56 +01:00

459 lines
21 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2.2 Grundlagen von Go
In diesem Abschnit werden wir lernen, wie man Konstanten und Variablen mit grundlegenden Datentypen definiert, sowie ein paar weitere Fähigkeiten aus der Go-Programmierung.
## Variablen definieren
Es gibt syntaktisch viele Wege, eine Variable in Go zu definieren.
Das Schlüsselwort `var` ist die simpelste Form, eine Variable zu erstellen. Bedenke, dass in Go der Datentyp **hinter** dem Variablennamen steht.
// Definiere eine Variable mit dem Namen “variableName” vom Typ "type"
var variableName type
Definiere mehrere Variablen.
// Definiere drei Variablen vom Typ "type"
var vname1, vname2, vname3 type
Definiere eine Variable mit einem Startwert.
// Definiere eine Variable mit dem Namen “variableName” vom Typ "type" und dem Wert "value"
var variableName type = value
Definiere mehrere Variablen mit einem Startwert.
/*
Definiere drei Variablen vom Typ "type" und gib ihnen drei Startwerte.
vname1 ist gleich v1, vname2 ist gleich v2, vname3 ist gleich v3
*/
var vname1, vname2, vname3 type = v1, v2, v3
Findest Du es nicht auch ein wenig mühsehlig, Variablen auf diesem Weg zu definieren? Keine Sorge, denn das Team hinter Go hat auch so gedacht. Daher kannst Du Variablen Startwerte geben, ohne explizit den Datentyp zu definieren. Der Code würde dann so aussehen:
/*
Definiere drei Variablen vom Typ "type" und gib ihnen drei Ausgangswerte.
vname1 ist gleich v1, vname2 ist gleich v2, vname3 ist gleich v3
*/
var vname1, vname2, vname3 = v1, v2, v3
Schön, ich weiß das dies immer noch nicht einfach genug für Dich ist. Mal schauen, wie wir das lösen können.
/*
Definiere drei Variablen ohne den Typ "type", ohne das Schlüsselwort "var" und gib ihnen Startwerte.
vname1 ist gleich v1vname2 ist gleich v2vname3 ist gleich v3
*/
vname1, vname2, vname3 := v1, v2, v3
So sieht es schon viel besser aus. Nutze `:=`, um `var` und `type` zu ersetzen. Es handelt sich hierbei um eine Kurzschreibweise. Aber warte, es gibt einen kleinen Haken: diese Form der Definition kann nur innerhalb von Fuktionen genutzt werden. Der Compiler wird sonst eine Fehlermeldung ausgeben, wenn Du es trotzdem außerhalb der `{}` einer Funktion versuchst. Daher nutzen wir meist das Schlüsselwort `var` um globale Variablen zu definieren oder die Funktion `var()`.
`_` (Unterstrich) ist ein besonderer Variablenname. Jeder übergebene Wert wird ignoriert. Übergeben wir zum Beispiel `35` an `b`, so verwerfen wir `34`. ( ***Dieses Beispiel soll nur die Funktionsweise aufzeigen. Es mag, wie in diesem Fall, nutzlos erscheinen, aber wir werden es oft gebrauchen, wenn wir Rückgabewerte von Funktionen erhalten.*** )
_, b := 34, 35
Wenn Du Variablen in Deinem Programm definierst, aber keine Verwendung finden, wird der Compiler eine Fehlermeldung ausgeben. Versuche den unten stehenden Code zu kompilieren und schaue, was passiert.
package main
func main() {
var i int
}
## Konstanten
Konstanten sind Werte, die während der Kompilierung festgelegt werden und während der Laufzeit nicht veränderbar sind. In Go kannst Du Konstanten als Wert Nummern, Booleans oder Strings geben.
Definiere eine Konstante wie folgt.
const constantName = value
// Du kannst auch den Datentyp hinzufügen, wenn nötig
const Pi float32 = 3.1415926
Mehr Beispiele.
const Pi = 3.1415926
const i = 10000
const MaxThread = 10
const prefix = "astaxie_"
## Grundlegende Datentypen
### Boolean
In Go nutzen wir `bool`, um Booleans (Wahrheitswerte) auszudrücken, die entweder den Zustand `true` oder `false` annehmen können, wobei `false` der Standardwert ist. ( ***Du kannst übrigens Nummern zu Booleans und umgekehrt konvertieren!*** )
// Beispielcode
var isActive bool // Globale Variable
var enabled, disabled = true, false // Der Datentyp wird ausgelassen
func test() {
var available bool // Lokale Variable
valid := false // Kurzschreibweise einer Definition
available = true // Eine Variable deklarieren
}
### Numerische Datentypen
Der Datentyp Integer (ganze Zahlen) kann sowohl den positiven, als auch den negativen Zahlenraum umfassen, was durch ein Vorzeichen kenntlich gemacht wird. Go besitzt `int` und `uint`, welche den selben Wertebereich haben. Dessen Größe hängt aber vom Betriebssystem ab. Es werden 32-Bit unter 32-Bit Betriebssystemen verwendet und 64-Bit unter 64-Bit Betriebssystemen. Go umfasst außerdem Datentypen mit einer spezifischen Länge: `rune`, `int8`, `int16`, `int32`, `int64`, `byte`, `uint8`, `uint16`, `uint32` und `uint64`. Bedenke, dass `rune` ein Alias für `int32` ist und `byte` dem `uint8` gleicht.
Eine wichtige Sache, die Du wissen solltest, ist, dass Du verschiedene Datentypen nicht vermischen kannst, da es sonst zu Fehlern bei der Kompilierung kommt.
var a int8
var b int32
c := a + b
Obwohl int32 einen größeren Wertebereich als int8 abdeckt, und beide vom Typ `int` sind, kannst Du sie nicht miteinander kombinieren. ( ***c wird hier der Typ `int` zugewiesen*** )
Floats (Gleitkommazahlen) haben entweder den Datentyp `float32` oder `float64`, aber es gibt keinen Datentyp namens `float`. `float64` wird standardmäßig verwendet, sollte die Kurzschreibweise für eine Variablendekleration genutzt werden.
War das schon alles? Nein! Go unterstützt auch komplexe Zahlen. `complex128` (bestehend aus 64-Bit für den realen Anteil und weiteren 64-Bit für den imaginären Teil) ist der Standarddatentyp. Solltest Du einen kleineren Wertebereich benötigen, kannst `complex64` als Datentyp verwenden (mit 32-Bit für den realen, und nochmals 32-Bit für den imaginären Teil). Die Schreibweise lautet `RE+IMi`, wo `RE` für den realen Teil steht, und `IM` den Imaginären Part repräsentiert. Das `i` am Ende ist die imaginäre Zahl. Hier ist ein Beispiel für eine komplexe Zahl.
var c complex64 = 5+5i
// Ausgabe: (5+5i)
fmt.Printf("Der Wert ist: %v", c)
### Strings
Wir sprachen vorhin darüber, das Go eine native UTF-8 Unterstützung mit sich bringt. Strings (Zeichenketten) werden durch Anführungszeichen `""` gekennzeichet, oder durch Backticks (rückwärts geneigtes Hochkomma) ``` `` ```.
// Beispielcode
var frenchHello string // Grundlegende Schreibweise zur Definition eines Strings
var emptyString string = "" // Definiert einen leeren String
func test() {
no, yes, maybe := "no", "yes", "maybe" // Kurzschreibweise
japaneseHello := "Ohaiou"
frenchHello = "Bonjour" // Grundlegende Deklaration
}
Es ist unmöglich, die Zeichen eines Strings anhand ihres Index zu verändern. Du wirst eine Fehlermeldung erhalten, solltest Du dies ausprobieren.
var s string = "Hallo"
s[0] = 'c'
Aber was ist, wenn ich wirklich nur ein Zeichen in einem String ändern möchte? Probieren wir es mit mit diesem Codebeispiel.
s := "hello"
c := []byte(s) // Konvertiere den String zum Typ []byte
c[0] = 'c'
s2 := string(c) // Wandle den Wert in eine String zurück
fmt.Printf("%s\n", s2)
Nutze den `+` Operator, um zwei Strings zu verknüpfen.
s := "Hallo"
m := " Welt"
a := s + m
fmt.Printf("%s\n", a)
oder auch
s := "Hallo"
s = "c" + s[1:] // Du kannst die Werte mit Hilfe des Index nicht verändern, aber sie abfragen
fmt.Printf("%s\n", s)
Was ist, wenn ein String über mehrere Zeilen verlaufen soll?
m := `Hallo
Welt`
`\`` wird die Zeichen in einem String escapen (d.h. mit `\` dessen Ausführung verhindern).
### Fehlermeldungen
Go besitzt mit `error` einen eigenen Datentyp, um mit Fehlermeldungen umzugehen. Zudem gibt es auch ein Paket mit dem Namen `errors`, um weitere Möglichkeiten bereitzustellen, Fehlermeldungen zu verarbeiten.
err := errors.New("emit macho dwarf: elf header corrupted")
if err != nil {
fmt.Print(err)
}
### Grundeliegende Datenstrukturen
Die folgende Grafik enstammt dem Artikel [Datenstrukturen in Go](http://research.swtch.com/godata) (auf englisch) aus [Russ Coxs Blog](http://research.swtch.com/). Wie Du sehen kannst, nutzt Go Abschnitte des Arbeitsspeichers, um Daten zu speichern.
![](images/2.2.basic.png?raw=true)
Abbildung 2.1 Gos grundlegende Datenstrukturen
## Einige Fähigkeiten
### Gruppierte Definition
Wenn Du mehrere Konstanten und Variablen deklarieren oder Pakete importieren möchtest, kannst Du dies auch gruppiert durchführen.
Übliche Vorgehensweise.
import "fmt"
import "os"
const i = 100
const pi = 3.1415
const prefix = "Go_"
var i int
var pi float32
var prefix string
Gruppierter Ansatz.
import(
"fmt"
"os"
)
const(
i = 100
pi = 3.1415
prefix = "Go_"
)
var(
i int
pi float32
prefix string
)
Wird innerhalb von `constant()` einer Konstanten das Schlüsselwort `iota` als Wert zugewiesen, hat sie den Wert `0`. Werden den folgenden Konstanten keine expliziten Werte zugewiesen, wird der letzte zugeweise Wert von `iota` um 1 erhöht und der folgenden Konstante zugewiesen. Dieses Verhalten beleuchten wir im folgenden Absatz.
### Aufzählen mit iota
Go besitzt das Schlüselwort `iota`, um eine Aufzählung zu starten. Der Startwert ist `0` und wird jeweils um `1` erhöht.
const(
x = iota // x == 0
y = iota // y == 1
z = iota // z == 2
w // Folgt dem Namen der Konstante keine Deklaration, so wird die zuletzt erfolgte verwendet. w = iota wird somit implizit auf iota gesetzt. Daher gilt w == 3. Folglich kannst Du bei x und y "= iota" einfach auslassen.
)
const v = iota // Sobald iota erneut auf `const` trifft, wird erneut mit `0` gestartet, also gilt v = 0.
const (
e, f, g = iota, iota, iota // e, f und g haben den selben Wert 0, da sie in der selben Zeile stehen.
)
### Einige Regeln
Der Grund, warum Go so prägnant ist, liegt im vorhersehbaren Verhalten der Programmiersprache.
- Jede Variable, die mit einem großgeschriebenen Buchstaben anfängt, kann exportiert werden. Andernfalls ist sie privat.
- Die selbe Regel gilt auch für Funktionen und Konstanten. Schlüsselwörter wie `public` oder `private` existieren in Go nicht.
## Array, Slice, Map
### Array
Ein `array` ist eine Aneinanderreihung von Daten, die wie folgt definiert wird:
var arr [n]Datentyp
wobei in `[n]Datentyp` das `n` die Länge des Arrays angibt. `Datentyp` ist selbsterklärend der Datentyp der Elemente (bzw. der aneinandergereihten Daten). Wie in anderen Programmiersprachen nutzen wir `[]`, um Daten im Array zu speichern oder um sie auszulesen.
var arr [10]int // Ein Array vom Typ [10]int
arr[0] = 42 // Der erste Index des Arrays ist 0
arr[1] = 13 // Einem Element wird ein Wert zugewiesen
fmt.Printf("Das erste Element ist %d\n", arr[0]) // Beim Auslesen des Wertes wird 42 zurückgegeben
fmt.Printf("Das letzte Element ist %d\n", arr[9]) // Es gibt den Standardwert des 10. Elements zurück, was in diesem Fall 0 ist.
Da die Länge ein Teil des Array-Typs ist, sind `[3]int` und `[4]int` verschieden, sodass wir die Länge eines Arrays nicht ändern können. Nutzt Du Arrays als Argument in einer Funktion, dann wird eine Kopie des Arrays übergeben, statt einem Zeiger (bzw. ein Verweis) auf das Original. Möchtest Du stattdessen den Zeiger übergeben, dann musst Du einen `slice` verwenden. Darauf gehen wir aber später nochmals ein.
Es ist möglich, `:=` zu nutzen, um ein Array zu deklarieren.
a := [3]int{1, 2, 3} // Deklariere ein Array vom Typ int mit drei Elementen
b := [10]int{1, 2, 3} // Deklariere ein int-Array mit zehn Elementen, bei dem die ersten Drei einen Wert zugewiesen bekommen. Der Rest erhält den Standardwert 0.
c := [...]int{4, 5, 6} // Nutze `…` statt der Längenangabe. Go wird die Länge dann selbst bestimmen.
Vielleicht möchtest Du auch Arrays als Element in einem Array nutzen. Schauen wir mal, wie das geht.
// Deklariere ein zweidimensionales Array mit zwei Elementen, welche jeweils vier Elemente besitzen.
doubleArray := [2][4]int{[4]int{1, 2, 3, 4}, [4]int{5, 6, 7, 8}}
// Die Dekleration kann auch ein wenig kompakter geschrieben werden.
{% raw %} easyArray := [2][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}} {% endraw %}
Arrays sind grundlegende Datenstrukturen in Go.
![](images/2.2.array.png?raw=true)
Abbildung 2.2 Die Zuordnung in einem mehrdimensionalen Array
### Slice
In vielen Situationen ist ein Array als Datentyp keine gute Wahl, wenn wir während der Deklaration dessen Länge noch nicht wissen. Daher brauchen wir so etwas wie ein "dynamisches Array" mit einer variabler Länge. Diese werden in Go `slice` genannt.
`slice` ist nicht wirklich ein `dynamisches Array`. Es ist vielmehr ein Zeiger auf ein darunterliegendes `array` mit einer ähnlichen Deklaration, dass aber keine Länge benötigt.
// Man deklariert ein Slice wie ein Array, lässt jedoch die Länge weg.
var fslice []int
Nun deklarieren wir ein `slice` und vergeben Startwerte.
slice := []byte {'a', 'b', 'c', 'd'}
`slice` kann existierende Slices oder Arrays verändern. `slice` nutzt `array[i:j]` zum "Herrausschneiden" von Elementen. `i` gibt den Index des Startpunkts an und kopiert alle Elemente bis zum Index `j`. Beachte, dass `array[j]` nicht in dem Ausschnitt enthalten ist, da das Slice eine Länge von `j-i` hat.
// Deklariere ein Array mit der Länge 10 von vom Typ byte
var ar = [10]byte {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
// Erstelle zwei Slices vom Typ []byte
var a, b []byte
// 'a' verweist auf die Elemente zwischen Index 3 und 5 im Array ar.
a = ar[2:5]
// 'a' besitzt nun die Elemente ar[2],ar[3] und ar[4]
// 'b' ist ein weiterer Ausschnitt (Slice) vom Array ar
b = ar[3:5]
// 'b' besitzt nun die Elemente ar[3] und ar[4]
Beachte die Unterscheide bei der Deklaration von `slice` und `array`. Wir nutzen `[…]`, um Go die Länge automatisch herausfinden zu lassen, aber nutzen `[]` lediglich zur Deklaration von Slices.
Ihre zugrundeliegenden Datentypen.
![](images/2.2.slice.png?raw=true)
Abbildung 2.3 Der Zusammenhang zwischen Slices und Arrays
Slices haben bestimmte Anwendungsgebiete.
- Ein `slice` beginnt mit dem Index 0, `ar[:n]` gleicht `ar[0:n]`.
- Der zweite Index gibt die Länge vom Slice an, wenn er ausgelassen wird. `ar[n:]` gleicht `ar[n:len(ar)]`.
- Du kannst auch `ar[:]` nutzen, um einen gesamtes Array zu kopieren, wie in den ersten beiden Punkten erklärt.
Mehr Beispiele zu `slice`
// Deklariere ein Array
var array = [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
// Deklariere zwei Slices
var aSlice, bSlice []byte
// Einige gewöhnliche Anwendungsfälle
aSlice = array[:3] // ist das Gleiche wie aSlice = array[0:3]. aSlice hat die Elemente a,b,c
aSlice = array[5:] // ist das Gleiche wie aSlice = array[5:10]. aSlice hat die Elemente f,g,h,i,j
aSlice = array[:] // ist das Gleiche wie aSlice = array[0:10]. aSlice beinhaltet alle Elemente
// Ein Slice vom Slice
aSlice = array[3:7] // aSlice hat die Elemente d,e,f,gAnfang=4Kapazität=7
bSlice = aSlice[1:3] // bSlice beinhaltet aSlice[1], aSlice[2], also hat es die Elemente e,f
bSlice = aSlice[:3] // bSlice beinhaltet aSlice[0], aSlice[1], aSlice[2], also hat es die Elemente d,e,f
bSlice = aSlice[0:5] // Der Slice ist nun länger, sodass bSlice d,e,f,g,h beinhaltet
bSlice = aSlice[:] // bSlice hat nun die gleiche Elemente wie aSlice, also d,e,f,g
`slice` ist ein Datentyp mit einem Zeiger, sodass Änderungen am Slice auch andere Variablen verändern, die wiederum selbt auf den Slice verweisen. Wie im oberigen Fall von `aSlice` und `bSlice`: veränderst Du den Wert eines Elements in `aSlice`, wird sich dieser auch im `bSlice` ändern.
`slice` ist ähnlich wie ein Struct und besteht aus drei Komponenten:
- Ein Zeiger, der auf den Beginn des `slice` bzw. zugrundeliegenden Array verweist.
- Die Länge definiert den Ausschnitt des zugrundeliegenden Arrays.
- Kapazität definiert die max. Größe des zugrundeliegenden Arrays.
Array_a := [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
Slice_a := Array_a[2:5]
Die zugrundeliegenden Datenstrukturen vom vorherigen Code sehen wie folgt aus:
![](images/2.2.slice2.png?raw=true)
Abbildung 2.4 Arrayelemente eines Slice
Es existieren eingebaute Funktionen, um mit Slices zu arbeiten.
- `len` gibt die Länge eines `slice` bzw. Ausschnitts zurück.
- `cap` gibt die max. Länge (Kapazität) eines `slice` zurück.
- `append` erweitert den `slice` um ein oder mehrere Elemente, und gibt einen `slice` zurück.
- `copy` erstellt eine Kopie eines Slices, und gibt die Anzahl der kopierten Elemente zurück.
Achtung: `append` wird das Array, aus das `slice` verweist verändern, sowie andere Slices, die auf das selbe Array verweisen. Sollte de Kapazität des zugrundeliegenden Arrays nicht ausreichen (`(cap-len) == 0`), dann gibt `append` ein neues Array zurück. Dies hat aber keine Auswirkungen auf andere Slices, die auf das alte Array verwiesen.
### Map
`map` verhält sich wie ein Dictionary in Python. Nutze das Schema `map[SchlüsselTyp]WerteTyp`, um es zu deklarieren.
Schauen wir uns ein wenig Code an. Die 'set'- und 'get'-Werte in `map` sind der von `slice` sehr ähnlich. In einem Slice kann der Datentyp des Index nur ein `int` sein. In einer `map` kann es sich jedoch um einen `int`, `string` oder um jeden anderen Datentyp handeln. Du kannst auch `==` und `!=` verwenden, um Werte mit einander zu vergleichen.
// Nutze 'string' als Datentyp für den Schlüssel, 'int' als Datentyp für den Wert und `make` zum Erstellen.
var numbers map[string] int
// Ein alternativer Weg zum Deklarieren
nummern := make(map[string]int)
nummern["eins"] = 1 // Weise ein Wert durch einen Schlüssel zu
nummern["zehn"] = 10
nummern["drei"] = 3
fmt.Println("Die dritte Nummer lautet: ", nummern["drei"]) // Lese den Wert aus
// Ausgabe: Die dritte Nummer lautet: 3
Einige Anmerkungen zur Nutzung von maps.
- `map` ist ungeordnet. Jedesmal, wenn Du eine `map` ausgeben willst, erhälst Du ein anderes Ergebnis. Dadurch ist es unmöglich, Werte über den `index` abzufragen. Nutze dafür den entsprechenden `Schlüssel`.
- `map` hat keine feste Länge. Dieser Datentyp ist wie `slice` lediglich ein Verweis.
- `len` funktioniert bei `map` auch. Es werden die Anzahl der `Schlüssel` zurückgegeben.
- Es ist ziemlich einfach, der Wert in einer `map` zu ändern. Nutze `nummern["eins"]=11`, um den `Schlüssel` eins den Wert `11` zuzuweisen.
Du kannst das Schema `Schlüssel:Wert` nutzen, um eine `map` mit Startwerten zu erstellen. `map` hat auch eingebaute Funktionen, um die Existenz eines `key` zu überprüfen.
Benutze `delete`, um ein Element in `map` zu löschen.
// Erstelle eine map
bewertung := map[string]float32 {"C":5, "Go":4.5, "Python":4.5, "C++":2 }
// Map hat zwei Rückgabewerte. Der zweite Rückgabewert 'ok' wird, wenn der Schlüssel nicht existiertaus false gesetzt. Andernfalls wird true zurückgegeben.
csharpBewertung, ok := bewertung["C#"]
if ok {
fmt.Println("C# ist in der map hat die Bewertung ", csharpBewertung)
} else {
fmt.Println("Es konnte keine Bewertung für C# in der map gefunden werden.")
}
delete(bewertung, "C") // Lösche das Element mit dem Schlüssel "c"
Wie ich bereits sagte, ist `map` lediglich ein Verweis. Verweisen zwei `map`s auf die gleiche, zugrundeliegende Datenstruktur, wird eine Änderung Auswirkungen auf beide `map`s haben.
m := make(map[string]string)
m["Hallo"] = "Bonjour"
m1 := m
m1["Hallo"] = "Salut" // Nun ist der Wert von m["hello"] Salut
### make, new
`make` reserviert Speicher für die eingebauten Datentypen, wie `map`, `slice`, und `channel`, wo hingegen `new` für selbstdefinierte Datentype (durch `type` definiert) Speicher zuweist.
`new(T)` ordnet dem Datentyp `T` Speicherplatz zu und initialisiert diesen mit den Standardwerten des jeweiligen Datentyps (z.B. `false` für einen `bool`). Anschließend wird die Adresse des Speicherortes in des Datentyps `*T` zurückgegeben. Nach der Definition von Go ist dies ein Zeiger, welcher auf die Standardwerte der Initilisierung von `T` verweist.
`new` gibt Zeiger als Wert zurück.
Die eingebaute Funktion `make(T, args)` hat einen anderen Zweck als `new(T)`. `make` kann für `slice`, `map`, und `channel` genutzt werden und gibt den Datentyp `T` mit seinem definierten Startwert zurück. Der Grund liegt darin, dass das ein Objekt vom zugrundeliegenden Datentyp erst erstellt wird, bevor auf diesen verwiesen werden kann. Dies ist bei diesen drei Datentypen der Fall. Zum Beispiel beinhaltet `slice` einen Zeiger, der auf das zugrundeliegende Array, die Länge und die Kapazität verweist. Vor der Initialisierung der Daten beinhaltet `slice` jedoch nur `nil`. Daher vergibt `make` den Datentypen `slice`, `map` und `channel` geeignetere Werte.
`make` gibt dabei die angesprochenen Standardwerte der entsprechenden Datentypen zurück (z.B. `false` für einen `bool`).
Die folgende Grafik verdeutlicht den Unterschied zwischen `new` und `make`.
![](images/2.2.makenew.png?raw=true)
Abbildung 2.5 Wie make und new Datenstrukturen Speicherplatz zuweisen
Standardwerte besitzen einen Wert. Dies sind die gebräuchlichsten Anwendungsfälle. Hier eine kleine Liste von Standardwerten.
int 0
int8 0
int32 0
int64 0
uint 0x0
rune 0 // rune ist ein Alias für int32
byte 0x0 // byte ist ein Alias für uint8
float32 0 // Die Größe beträgt 4 Byte
float64 0 // Die Größe beträgt 8 Byte
bool false
string ""
## Links
- [Inhaltsverzeichnis](preface.md)
- Vorheriger Abschnitt: ["Hallo Go"](02.1.md)
- Nächster Abschnitt: [Kontrollstrukturen und Funktionen](02.3.md)