Schleifen
Go kennt nur einen einzigen Befehl für Schleifen: for
. Dieser Befehl kommt
in zwei unterschiedlichen Formen vor, einmal in der Form, wie sie aus
Programmiersprachen wie C bekannt sind, und einmal als Iterator, wie sie auch
in Programmiersprachen wie Ruby vorkommen (dort: each_with_index()
).
Standardform
In der einfachsten Form ist die for
-Schleife eine »Endlosschleife«, deren Inhalt immer
wieder ausgeführt wird:
Wenn du das Programm laufen lässt, musst du es abbrechen, da die Schleife keine Abbruchbedingung hat. Obige Schleife ist dasselbe wie
for true {
fmt.Println("Hallo schöne Welt")
}
was wiederum dasselbe ist wie for ; true ; { ... }
. Die allgemeine Form der Schleife sieht so aus:
for ‹init› ; ‹bedingung› ; ‹post› { ... }
Wobei ‹bedingung›
ein boolescher Ausdruck ist (der also true
oder false
ergeben muss). ‹init›
und ‹post›
sind einfache Anweisungen. ‹init›
wird
einmal vor Schleifenbeginn ausgeführt, ‹post›
nach jeder Iteration am Ende
des Blocks. Was sich sehr theoretisch anhört hat die praktische Form wie:
package main
import "fmt"
func main() {
for i := 0; i < 10; i++ {
fmt.Println(i, "Hallo schöne Welt")
}
}
Versuche zu überlegen, was das Programm ausgibt, bevor du es ausprobierst!
Hier wird i := 0
einmal zu Beginn der Schleife ausgeführt, die Schleife
solange durchlaufen wie die Bedingung i < 10
wahr ergibt und am Ende des
Blocks wird mit i++
i um eins erhöht. Ein wichtiger Hinweis: Die in ‹init›
definierten Variablen sind nur innerhalb der Schleife sichtbar.
for ... := range
Die zweite Form der for
-Schleife iteriert über einen der Datentypen, die
eine Menge an Elementen beinhalten kann (Array, Slice, String, Map und
Channel). Diese Schleife hat folgenden Aufbau:
for k, v := range ‹objekt› {
...
}
Die Variablen k
und v
haben je nach Typ des Objekts eine unterschiedliche
Bedeutung. Bei einem Feld (Slice oder Array) ist die erste Variable der Index,
bei einer Map ist das der Schlüssel. v
ist bei den drei Strukturen der Wert,
der unter k
angesprochen wird.
package main
import "fmt"
func main() {
alter := map[string]int{
"Andreas": 23,
"Marie": 37,
"Peter": 27,
"Karina": 27,
}
for k, v := range alter {
fmt.Println(k, "ist", v, "Jahre alt.")
}
}
Hier wird die Map, die in der Variable alter
gespeichert ist, ohne eine
bestimmte Reihenfolge durchlaufen und nacheinander der Variablen k
den Namen
und v
das Alter zugeordnet (und ausgegeben).
Ausbruch aus der Schleife (break
)
Man kann aus einer Schleife ausbrechen. Der Befehl dazu heißt break
und
wird wie folgt benutzt:
package main
import "fmt"
func main() {
zähler := 0
for {
if zähler == 4 {
break
}
fmt.Println("Hallo schöne Welt")
zähler++
}
}
break
unterbricht die innerste for Schleife (im Übrigen auch select
und
switch
Anweisungen, dazu später mehr). Wenn man mehrere for-Schleifen
geschachtelt hat, kann man sich mit Sprungmarken (Labels) helfen:
package main
import "fmt"
func main() {
Hauptschleife:
for j := 0; j < 10; j++ {
for k := 0; k < 10; k++ {
fmt.Println(j, k, "Hallo schöne Welt")
if k == 4 {
break Hauptschleife
}
}
}
}
Probiere das Programm einmal ohne die Sprungmarke Hauptschleife
aus und einmal mit. Was passiert?
Hier sind zwei Schleifen ineinander geschachtelt. Das break
in der innersten
Schleife würde ohne Sprungmarke lediglich bewirken, dass die innere Schleife
nach fünf Durchläufen abgebrochen wird, die äußere Schleife aber weiter zehn
Mal durchläuft. Mit Sprungmarke wird auch die äußere Schleife nach der fünften
Iteration abgebrochen und mit dem Programmcode fortgeführt, der nach der
Schleife steht.