Add German translation of chapter 2
This commit is contained in:
412
de/02.2.md
412
de/02.2.md
@@ -1,57 +1,58 @@
|
||||
# 2.2 Go foundation
|
||||
# 2.2 Grundlagen von Go
|
||||
|
||||
In this section, we are going to teach you how to define constants, variables with elementary types and some skills in Go programming.
|
||||
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.
|
||||
|
||||
## Define variables
|
||||
## Variablen definieren
|
||||
|
||||
There are many forms of syntax that can be used to define variables in Go.
|
||||
Es gibt syntaktisch viele Wege, eine Variable in Go zu definieren.
|
||||
|
||||
The keyword `var` is the basic form to define variables, notice that Go puts the variable type `after` the variable name.
|
||||
Das Schlüsselwort `var` ist die simpelste Form, eine Variable zu erstellen. Bedenke, dass in Go der Datentyp **hinter** dem Variablennamen steht.
|
||||
|
||||
// define a variable with name “variableName” and type "type"
|
||||
// Definiere eine Variable mit dem Namen “variableName” vom Typ "type"
|
||||
var variableName type
|
||||
|
||||
Define multiple variables.
|
||||
Definiere mehrere Variablen.
|
||||
|
||||
// define three variables which types are "type"
|
||||
// Definiere drei Variablen vom Typ "type"
|
||||
var vname1, vname2, vname3 type
|
||||
|
||||
Define a variable with initial value.
|
||||
Definiere eine Variable mit einem Startwert.
|
||||
|
||||
// define a variable with name “variableName”, type "type" and value "value"
|
||||
// Definiere eine Variable mit dem Namen “variableName” vom Typ "type" und dem Wert "value"
|
||||
var variableName type = value
|
||||
|
||||
Define multiple variables with initial values.
|
||||
Definiere mehrere Variablen mit einem Startwert.
|
||||
|
||||
/*
|
||||
Define three variables with type "type", and initialize their values.
|
||||
vname1 is v1, vname2 is v2, vname3 is v3
|
||||
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
|
||||
|
||||
Do you think that it's too tedious to define variables use the way above? Don't worry, because the Go team has also found this to be a problem. Therefore if you want to define variables with initial values, we can just omit the variable type, so the code will look like this instead:
|
||||
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:
|
||||
|
||||
/*
|
||||
Define three variables without type "type", and initialize their values.
|
||||
vname1 is v1,vname2 is v2,vname3 is v3
|
||||
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
|
||||
|
||||
Well, I know this is still not simple enough for you. Let's see how we fix it.
|
||||
Schön, ich weiß das dies immer noch nicht einfach genug für Dich ist. Mal schauen, wie wir das lösen können.
|
||||
|
||||
/*
|
||||
Define three variables without type "type" and without keyword "var", and initialize their values.
|
||||
vname1 is v1,vname2 is v2,vname3 is v3
|
||||
Definiere drei Variablen ohne den Typ "type", ohne das Schlüsselwort "var" und gib ihnen Startwerte.
|
||||
vname1 ist gleich v1,vname2 ist gleich v2,vname3 ist gleich v3
|
||||
*/
|
||||
vname1, vname2, vname3 := v1, v2, v3
|
||||
|
||||
Now it looks much better. Use `:=` to replace `var` and `type`, this is called a brief statement. But wait, it has one limitation: this form can only be used inside of functions. You will get compile errors if you try to use it outside of function bodies. Therefore, we usually use `var` to define global variables and we can use this brief statement in `var()`.
|
||||
|
||||
`_` (blank) is a special variable name. Any value that is given to it will be ignored. For example, we give `35` to `b`, and discard `34`.( ***This example just show you how it works. It looks useless here because we often use this symbol when we get function return values.*** )
|
||||
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
|
||||
|
||||
If you don't use variables that you've defined in your program, the compiler will give you compilation errors. Try to compile the following code and see what happens.
|
||||
|
||||
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
|
||||
|
||||
@@ -59,43 +60,43 @@ If you don't use variables that you've defined in your program, the compiler wil
|
||||
var i int
|
||||
}
|
||||
|
||||
## Constants
|
||||
## Konstanten
|
||||
|
||||
So-called constants are the values that are determined during compile time and you cannot change them during runtime. In Go, you can use number, boolean or string as types of constants.
|
||||
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.
|
||||
|
||||
Define constants as follows.
|
||||
Definiere eine Konstante wie folgt.
|
||||
|
||||
const constantName = value
|
||||
// you can assign type of constants if it's necessary
|
||||
// Du kannst auch den Datentyp hinzufügen, wenn nötig
|
||||
const Pi float32 = 3.1415926
|
||||
|
||||
More examples.
|
||||
Mehr Beispiele.
|
||||
|
||||
const Pi = 3.1415926
|
||||
const i = 10000
|
||||
const MaxThread = 10
|
||||
const prefix = "astaxie_"
|
||||
|
||||
## Elementary types
|
||||
## Grundlegende Datentypen
|
||||
|
||||
### Boolean
|
||||
|
||||
In Go, we use `bool` to define a variable as boolean type, the value can only be `true` or `false`, and `false` will be the default value. ( ***You cannot convert variables' type between number and 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!*** )
|
||||
|
||||
// sample code
|
||||
var isActive bool // global variable
|
||||
var enabled, disabled = true, false // omit type of variables
|
||||
// Beispielcode
|
||||
var isActive bool // Globale Variable
|
||||
var enabled, disabled = true, false // Der Datentyp wird ausgelassen
|
||||
func test() {
|
||||
var available bool // local variable
|
||||
valid := false // brief statement of variable
|
||||
available = true // assign value to variable
|
||||
var available bool // Lokale Variable
|
||||
valid := false // Kurzschreibweise einer Definition
|
||||
available = true // Eine Variable deklarieren
|
||||
}
|
||||
|
||||
### Numerical types
|
||||
### Numerische Datentypen
|
||||
|
||||
Integer types include both signed and unsigned integer types. Go has `int` and `uint` at the same time, they have same length, but specific length depends on your operating system. They use 32-bit in 32-bit operating systems, and 64-bit in 64-bit operating systems. Go also has types that have specific length including `rune`, `int8`, `int16`, `int32`, `int64`, `byte`, `uint8`, `uint16`, `uint32`, `uint64`. Note that `rune` is alias of `int32` and `byte` is alias of `uint8`.
|
||||
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.
|
||||
|
||||
One important thing you should know that you cannot assign values between these types, this operation will cause compile errors.
|
||||
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
|
||||
|
||||
@@ -103,86 +104,90 @@ One important thing you should know that you cannot assign values between these
|
||||
|
||||
c := a + b
|
||||
|
||||
Although int32 has a longer length than int8, and has the same type as int, you cannot assign values between them. ( ***c will be asserted as type `int` here*** )
|
||||
|
||||
Float types have the `float32` and `float64` types and no type called `float`. The latter one is the default type if using brief statement.
|
||||
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*** )
|
||||
|
||||
That's all? No! Go supports complex numbers as well. `complex128` (with a 64-bit real and 64-bit imaginary part) is the default type, if you need a smaller type, there is one called `complex64` (with a 32-bit real and 32-bit imaginary part). Its form is `RE+IMi`, where `RE` is real part and `IM` is imaginary part, the last `i` is imaginary number. There is a example of complex number.
|
||||
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
|
||||
//output: (5+5i)
|
||||
fmt.Printf("Value is: %v", c)
|
||||
// Ausgabe: (5+5i)
|
||||
fmt.Printf("Der Wert ist: %v", c)
|
||||
|
||||
### String
|
||||
### Strings
|
||||
|
||||
We just talked about how Go uses the UTF-8 character set. Strings are represented by double quotes `""` or backticks ``` `` ```.
|
||||
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) ``` `` ```.
|
||||
|
||||
// sample code
|
||||
var frenchHello string // basic form to define string
|
||||
var emptyString string = "" // define a string with empty string
|
||||
// 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" // brief statement
|
||||
no, yes, maybe := "no", "yes", "maybe" // Kurzschreibweise
|
||||
japaneseHello := "Ohaiou"
|
||||
frenchHello = "Bonjour" // basic form of assign values
|
||||
frenchHello = "Bonjour" // Grundlegende Deklaration
|
||||
}
|
||||
|
||||
It's impossible to change string values by index. You will get errors when you compile following code.
|
||||
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 = "hello"
|
||||
var s string = "Hallo"
|
||||
s[0] = 'c'
|
||||
|
||||
What if I really want to change just one character in a string? Try following code.
|
||||
|
||||
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) // convert string to []byte type
|
||||
c := []byte(s) // Konvertiere den String zum Typ []byte
|
||||
c[0] = 'c'
|
||||
s2 := string(c) // convert back to string type
|
||||
s2 := string(c) // Wandle den Wert in eine String zurück
|
||||
fmt.Printf("%s\n", s2)
|
||||
|
||||
You use the `+` operator to combine two strings.
|
||||
|
||||
s := "hello,"
|
||||
m := " world"
|
||||
Nutze den `+` Operator, um zwei Strings zu verknüpfen.
|
||||
|
||||
s := "Hallo"
|
||||
m := " Welt"
|
||||
a := s + m
|
||||
fmt.Printf("%s\n", a)
|
||||
|
||||
and also.
|
||||
|
||||
s := "hello"
|
||||
s = "c" + s[1:] // you cannot change string values by index, but you can get values instead.
|
||||
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)
|
||||
|
||||
What if I want to have a multiple-line string?
|
||||
|
||||
m := `hello
|
||||
world`
|
||||
|
||||
`` ` will not escape any characters in a string.
|
||||
Was ist, wenn ein String über mehrere Zeilen verlaufen soll?
|
||||
|
||||
### Error types
|
||||
m := `Hallo
|
||||
Welt`
|
||||
|
||||
`\`` wird die Zeichen in einem String escapen (d.h. mit `\` dessen Ausführung verhindern).
|
||||
|
||||
Go has one `error` type for purpose of dealing with error messages. There is also a package called `errors` to handle errors.
|
||||
### 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)
|
||||
}
|
||||
|
||||
### Underlying data structure
|
||||
### Grundeliegende Datenstrukturen
|
||||
|
||||
The following picture comes from an article about [Go data structure](http://research.swtch.com/godata) in [Russ Cox Blog](http://research.swtch.com/). As you can see, Go utilizes blocks of memory to store data.
|
||||
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.
|
||||
|
||||

|
||||
|
||||
Figure 2.1 Go underlying data structure
|
||||
Abbildung 2.1 Gos grundlegende Datenstrukturen
|
||||
|
||||
## Some skills
|
||||
## Einige Fähigkeiten
|
||||
|
||||
### Define by group
|
||||
### Gruppierte Definition
|
||||
|
||||
If you want to define multiple constants, variables or import packages, you can use the group form.
|
||||
Wenn Du mehrere Konstanten und Variablen deklarieren oder Pakete importieren möchtest, kannst Du dies auch gruppiert durchführen.
|
||||
|
||||
Basic form.
|
||||
Übliche Vorgehensweise.
|
||||
|
||||
import "fmt"
|
||||
import "os"
|
||||
@@ -195,7 +200,7 @@ Basic form.
|
||||
var pi float32
|
||||
var prefix string
|
||||
|
||||
Group form.
|
||||
Gruppierter Ansatz.
|
||||
|
||||
import(
|
||||
"fmt"
|
||||
@@ -213,242 +218,241 @@ Group form.
|
||||
pi float32
|
||||
prefix string
|
||||
)
|
||||
|
||||
Unless you assign the value of constant is `iota`, the first value of constant in the group `const()` will be `0`. If following constants don't assign values explicitly, their values will be the same as the last one. If the value of last constant is `iota`, the values of following constants which are not assigned are `iota` also.
|
||||
|
||||
### iota enumerate
|
||||
Wird innerhalb von `constant()` einer Konstanten das Schlüsselwort `iota` als Wert zugewiesen, hat sie den Wert `0`. Werden den folgenden Konstanten keinee expliziten Werte zugewiesen, wird der letzte zugeweise Wert von `iota` um 1 erhöht und und der folgenden Konstante zugewiesen. Dieses Verhalten beleuchten wir im folgenden Absatz.
|
||||
|
||||
Go has one keyword called `iota`, this keyword is to make `enum`, it begins with `0`, increased by `1`.
|
||||
### 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 // If there is no expression after the constants name, it uses the last expression, so it's saying w = iota implicitly. Therefore w == 3, and y and x both can omit "= iota" as well.
|
||||
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 // once iota meets keyword `const`, it resets to `0`, so v = 0.
|
||||
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=0,f=0,g=0 values of iota are same in one line.
|
||||
e, f, g = iota, iota, iota // e, f und g haben den selben Wert 0, da sie in der selben Zeile stehen.
|
||||
)
|
||||
|
||||
### Some rules
|
||||
### Einige Regeln
|
||||
|
||||
The reason that Go is concise because it has some default behaviors.
|
||||
Der Grund, warum Go so prägnant ist, liegt im vorhersehbaren Verhalten der Programmiersprache.
|
||||
|
||||
- Any variable that begins with a capital letter means it will be exported, private otherwise.
|
||||
- The same rule applies for functions and constants, no `public` or `private` keyword exists in Go.
|
||||
- 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, Slice, Map
|
||||
|
||||
### array
|
||||
### Array
|
||||
|
||||
`array` is an array obviously, we define a one as follows.
|
||||
Ein `array` ist eine Aneinanderreihung von Daten, die wie folgt definiert wird:
|
||||
|
||||
var arr [n]type
|
||||
|
||||
in `[n]type`, `n` is the length of the array, `type` is the type of its elements. Like other languages, we use `[]` to get or set element values within arrays.
|
||||
var arr [n]Datentyp
|
||||
|
||||
var arr [10]int // an array of type [10]int
|
||||
arr[0] = 42 // array is 0-based
|
||||
arr[1] = 13 // assign value to element
|
||||
fmt.Printf("The first element is %d\n", arr[0]) // get element value, it returns 42
|
||||
fmt.Printf("The last element is %d\n", arr[9]) //it returns default value of 10th element in this array, which is 0 in this case.
|
||||
|
||||
Because length is a part of the array type, `[3]int` and `[4]int` are different types, so we cannot change the length of arrays. When you use arrays as arguments, functions get their copies instead of references! If you want to use references, you may want to use `slice`. We'll talk about later.
|
||||
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.
|
||||
|
||||
It's possible to use `:=` when you define arrays.
|
||||
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.
|
||||
|
||||
a := [3]int{1, 2, 3} // define an int array with 3 elements
|
||||
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.
|
||||
|
||||
b := [10]int{1, 2, 3} // define a int array with 10 elements, of which the first three are assigned. The rest of them use the default value 0.
|
||||
Es ist möglich, `:=` zu nutzen, um ein Array zu deklarieren.
|
||||
|
||||
c := [...]int{4, 5, 6} // use `…` to replace the length parameter and Go will calculate it for you.
|
||||
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.
|
||||
|
||||
You may want to use arrays as arrays' elements. Let's see how to do this.
|
||||
Vielleicht möchtest Du auch Arrays als Element in einem Array nutzen. Schauen wir mal, wie das geht.
|
||||
|
||||
// define a two-dimensional array with 2 elements, and each element has 4 elements.
|
||||
// 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}}
|
||||
|
||||
// The declaration can be written more concisely as follows.
|
||||
|
||||
// Die Dekleration kann auch ein wenig kompakter geschrieben werden.
|
||||
easyArray := [2][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}}
|
||||
|
||||
Array underlying data structure.
|
||||
|
||||
Arrays sind grundlegende Datenstrukturen in Go.
|
||||
|
||||

|
||||
|
||||
Figure 2.2 Multidimensional array mapping relationship
|
||||
Abbildung 2.2 Die Zuordnung in einem mehrdimensionalen Array
|
||||
|
||||
### slice
|
||||
### Slice
|
||||
|
||||
In many situations, the array type is not a good choice -for instance when we don't know how long the array will be when we define it. Thus, we need a "dynamic array". This is called `slice` in Go.
|
||||
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` is not really a `dynamic array`. It's a reference type. `slice` points to an underlying `array` whose declaration is similar to `array`, but doesn't need length.
|
||||
`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.
|
||||
|
||||
// just like defining an array, but this time, we exclude the length.
|
||||
// Man deklariert ein Slice wie ein Array, lässt jedoch die Länge weg.
|
||||
var fslice []int
|
||||
|
||||
Then we define a `slice`, and initialize its data.
|
||||
Nun deklarieren wir ein `slice` und vergeben Startwerte.
|
||||
|
||||
slice := []byte {'a', 'b', 'c', 'd'}
|
||||
|
||||
`slice` can redefine existing slices or arrays. `slice` uses `array[i:j]` to slice, where `i` is the start index and `j` is end index, but notice that `array[j]` will not be sliced since the length of the slice is `j-i`.
|
||||
|
||||
// define an array with 10 elements whose types are bytes
|
||||
`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'}
|
||||
|
||||
// define two slices with type []byte
|
||||
// Erstelle zwei Slices vom Typ []byte
|
||||
var a, b []byte
|
||||
|
||||
// 'a' points to elements from 3rd to 5th in array ar.
|
||||
// 'a' verweist auf die Elemente zwischen Index 3 und 5 im Array ar.
|
||||
a = ar[2:5]
|
||||
// now 'a' has elements ar[2],ar[3] and ar[4]
|
||||
|
||||
// 'b' is another slice of array ar
|
||||
b = ar[3:5]
|
||||
// now 'b' has elements ar[3] and ar[4]
|
||||
// 'a' besitzt nun die Elemente ar[2],ar[3] und ar[4]
|
||||
|
||||
Notice the differences between `slice` and `array` when you define them. We use `[…]` to let Go calculate length but use `[]` to define slice only.
|
||||
// 'b' ist ein weiterer Ausschnitt (Slice) vom Array ar
|
||||
b = ar[3:5]
|
||||
// 'b' besitzt nun die Elemente ar[3] und ar[4]
|
||||
|
||||
Their underlying data structure.
|
||||
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.
|
||||
|
||||

|
||||
|
||||
Figure 2.3 Correspondence between slice and array
|
||||
Abbildung 2.3 Der Zusammenhang zwischen Slices und Arrays
|
||||
|
||||
slice has some convenient operations.
|
||||
Slices haben bestimmte Anwendungsgebiete.
|
||||
|
||||
- `slice` is 0-based, `ar[:n]` equals to `ar[0:n]`
|
||||
- The second index will be the length of `slice` if omitted, `ar[n:]` equals to `ar[n:len(ar)]`.
|
||||
- You can use `ar[:]` to slice whole array, reasons are explained in first two statements.
|
||||
- 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.
|
||||
|
||||
More examples pertaining to `slice`
|
||||
Mehr Beispiele zu `slice`
|
||||
|
||||
// define an array
|
||||
// Deklariere ein Array
|
||||
var array = [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
|
||||
// define two slices
|
||||
// Deklariere zwei Slices
|
||||
var aSlice, bSlice []byte
|
||||
|
||||
// some convenient operations
|
||||
aSlice = array[:3] // equals to aSlice = array[0:3] aSlice has elements a,b,c
|
||||
aSlice = array[5:] // equals to aSlice = array[5:10] aSlice has elements f,g,h,i,j
|
||||
aSlice = array[:] // equals to aSlice = array[0:10] aSlice has all elements
|
||||
// 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
|
||||
|
||||
// slice from slice
|
||||
aSlice = array[3:7] // aSlice has elements d,e,f,g,len=4,cap=7
|
||||
bSlice = aSlice[1:3] // bSlice contains aSlice[1], aSlice[2], so it has elements e,f
|
||||
bSlice = aSlice[:3] // bSlice contains aSlice[0], aSlice[1], aSlice[2], so it has d,e,f
|
||||
bSlice = aSlice[0:5] // slice could be expanded in range of cap, now bSlice contains d,e,f,g,h
|
||||
bSlice = aSlice[:] // bSlice has same elements as aSlice does, which are d,e,f,g
|
||||
// Ein Slice vom Slice
|
||||
aSlice = array[3:7] // aSlice hat die Elemente d,e,f,g,Anfang=4,Kapazitä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` is a reference type, so any changes will affect other variables pointing to the same slice or array. For instance, in the case of `aSlice` and `bSlice` above, if you change the value of an element in `aSlice`, `bSlice` will be changed as well.
|
||||
`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` is like a struct by definition and it contains 3 parts.
|
||||
`slice` ist ähnlich wie ein Struct und besteht aus drei Komponenten:
|
||||
|
||||
- A pointer that points to where `slice` starts.
|
||||
- The length of `slice`.
|
||||
- Capacity, the length from start index to end index of `slice`.
|
||||
- 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]
|
||||
|
||||
The underlying data structure of the code above as follows.
|
||||
Die zugrundeliegenden Datenstrukturen vom vorherigen Code sehen wie folgt aus:
|
||||
|
||||

|
||||
|
||||
Figure 2.4 Array information of slice
|
||||
Abbildung 2.4 Arrayelemente eines Slice
|
||||
|
||||
There are some built-in functions for slice.
|
||||
Es existieren eingebaute Funktionen, um mit Slices zu arbeiten.
|
||||
|
||||
- `len` gets the length of `slice`.
|
||||
- `cap` gets the maximum length of `slice`
|
||||
- `append` appends one or more elements to `slice`, and returns `slice` .
|
||||
- `copy` copies elements from one slice to the other, and returns the number of elements that were copied.
|
||||
- `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.
|
||||
|
||||
Attention: `append` will change the array that `slice` points to, and affect other slices that point to the same array. Also, if there is not enough length for the slice (`(cap-len) == 0`), `append` returns a new array for this slice. When this happens, other slices pointing to the old array will not be affected.
|
||||
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
|
||||
|
||||
`map` behaves like a dictionary in Python. Use the form `map[keyType]valueType` to define it.
|
||||
`map` verhält sich wie ein Dictionary in Python. Nutze das Schema `map[SchlüsselTyp]WerteTyp`, um es zu deklarieren.
|
||||
|
||||
Let's see some code. The 'set' and 'get' values in `map` are similar to `slice`, however the index in `slice` can only be of type 'int' while `map` can use much more than that: for example `int`, `string`, or whatever you want. Also, they are all able to use `==` and `!=` to compare values.
|
||||
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.
|
||||
|
||||
// use string as the key type, int as the value type, and `make` initialize it.
|
||||
// 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
|
||||
// another way to define map
|
||||
numbers := make(map[string]int)
|
||||
numbers["one"] = 1 // assign value by key
|
||||
numbers["ten"] = 10
|
||||
numbers["three"] = 3
|
||||
// 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("The third number is: ", numbers["three"]) // get values
|
||||
// It prints: The third number is: 3
|
||||
fmt.Println("Die dritte Nummer lautet: ", nummern["drei"]) // Lese den Wert aus
|
||||
// Ausgabe: Die dritte Nummer lautet: 3
|
||||
|
||||
Some notes when you use map.
|
||||
Einige Anmerkungen zur Nutzung von maps.
|
||||
|
||||
- `map` is disorderly. Everytime you print `map` you will get different results. It's impossible to get values by `index` -you have to use `key`.
|
||||
- `map` doesn't have a fixed length. It's a reference type just like `slice`.
|
||||
- `len` works for `map` also. It returns how many `key`s that map has.
|
||||
- It's quite easy to change the value through `map`. Simply use `numbers["one"]=11` to change the value of `key` one to `11`.
|
||||
- `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` one den Wert `11` zuzuweisen.
|
||||
|
||||
You can use form `key:val` to initialize map's values, and `map` has built-in methods to check if the `key` exists.
|
||||
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.
|
||||
|
||||
Use `delete` to delete an element in `map`.
|
||||
Benutze `delete`, um ein Element in `map` zu löschen.
|
||||
|
||||
// Initialize a map
|
||||
rating := map[string]float32 {"C":5, "Go":4.5, "Python":4.5, "C++":2 }
|
||||
// map has two return values. For the second return value, if the key doesn't exist,'ok' returns false. It returns true otherwise.
|
||||
csharpRating, ok := rating["C#"]
|
||||
// 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 existiert,aus false gesetzt. Andernfalls wird true zurückgegeben.
|
||||
csharpBewertung, ok := bewertung["C#"]
|
||||
if ok {
|
||||
fmt.Println("C# is in the map and its rating is ", csharpRating)
|
||||
fmt.Println("C# ist in der map hat die Bewertung ", csharpBewertung)
|
||||
} else {
|
||||
fmt.Println("We have no rating associated with C# in the map")
|
||||
fmt.Println("Es konnte keine Bewertung für C# in der map gefunden werden.")
|
||||
}
|
||||
|
||||
delete(rating, "C") // delete element with key "c"
|
||||
delete(bewertung, "C") // Lösche das Element mit dem Schlüssel "c"
|
||||
|
||||
As I said above, `map` is a reference type. If two `map`s point to same underlying data, any change will affect both of them.
|
||||
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["Hello"] = "Bonjour"
|
||||
m["Hallo"] = "Bonjour"
|
||||
m1 := m
|
||||
m1["Hello"] = "Salut" // now the value of m["hello"] is Salut
|
||||
|
||||
m1["Hallo"] = "Salut" // Nun ist der Wert von m["hello"] Salut
|
||||
|
||||
### make, new
|
||||
|
||||
`make` does memory allocation for built-in models, such as `map`, `slice`, and `channel`, while `new` is for types' memory allocation.
|
||||
`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)` allocates zero-value to type `T`'s memory, returns its memory address, which is the value of type `*T`. By Go's definition, it returns a pointer which points to type `T`'s zero-value.
|
||||
`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` returns pointers.
|
||||
`new` gibt Zeiger als Wert zurück.
|
||||
|
||||
The built-in function `make(T, args)` has different purposes than `new(T)`. `make` can be used for `slice`, `map`, and `channel`, and returns a type `T` with an initial value. The reason for doing this is because the underlying data of these three types must be initialized before they point to them. For example, a `slice` contains a pointer that points to the underlying `array`, length and capacity. Before these data are initialized, `slice` is `nil`, so for `slice`, `map` and `channel`, `make` initializes their underlying data and assigns some suitable values.
|
||||
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` returns non-zero values.
|
||||
`make` gibt dabei die angesprochenen Standardwerte der entsprechenden Datentypen zurück (z.B. `false` für einen `bool`).
|
||||
|
||||
The following picture shows how `new` and `make` are different.
|
||||
Die folgende Grafik verdeutlicht den Unterschied zwischen `new` und `make`.
|
||||
|
||||

|
||||
|
||||
Figure 2.5 Underlying memory allocation of make and new
|
||||
Abbildung 2.5 Wie make und new Datenstrukturen Speicherplatz zuweisen
|
||||
|
||||
Zero-value does not mean empty value. It's the value that variables default to in most cases. Here is a list of some zero-values.
|
||||
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 // the actual type of rune is int32
|
||||
byte 0x0 // the actual type of byte is uint8
|
||||
float32 0 // length is 4 byte
|
||||
float64 0 //length is 8 byte
|
||||
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
|
||||
|
||||
- [Directory](preface.md)
|
||||
- Previous section: ["Hello, Go"](02.1.md)
|
||||
- Next section: [Control statements and functions](02.3.md)
|
||||
- [Inhaltsverzeichnis](preface.md)
|
||||
- Vorheriger Abschnitt: ["Hallo Go"](02.1.md)
|
||||
- Nächster Abschnitt: [Kontrollstrukturen und Funktionen](02.3.md)
|
||||
Reference in New Issue
Block a user