In Go kannst du mit for und einem Index über einen slice iterieren, oder du verwendest range.
Mit range kannst du auch über eine map iterieren.
Jede Iteration gibt zwei Werte zurück: den Index/Schlüssel und eine Kopie des Elements an diesem Index bzw. Schlüssel.
Ein Kinderspiel: Schleifen über einen Slice, in der erwarteten Reihenfolge.
xi := []int{10, 20, 30}
for i, x := range xi {
fmt.Println(i, x)
}
// outputs:
// 0, 10
// 1, 20
// 2, 30
Beim Iterieren über eine Map taucht ein neues Problem auf. Die Reihenfolge ist jetzt zufällig.
hash := map[int]int{9: 10, 99: 20, 999: 30}
for k, v := range hash {
fmt.Println(k, v)
}
// outputs, for example:
// 99 20
// 999 30
// 9 10
Es mag so aussehen, als wäre die obige Ausgabe falsch, denn man würde erwarten, dass das erste Schlüssel/Wert-Paar bei der Deklaration der Map 9 10 als erstes ausgegeben wird und nicht als letztes.
Allerdings sind Maps von Natur aus ungeordnet, es gibt kein erstes oder letztes Schlüssel/Wert-Paar.
Deshalb ist die Reihenfolge beim Iterieren über die Einträge einer Map zufällig und folgt keinem bestimmten Muster.
Das bedeutet, dass die obige Ausgabe möglich ist, aber von dem abweichen kann, was du bekommst, wenn du das selbst ausprobierst.
Mehr dazu erfährst du unter Go Language Spec: range clause.
In Go führt eine unbenutzte Variable zur Build-Zeit zu einem Fehler. Manchmal brauchst du nur den Wert, wie im ersten Beispiel:
xi := []int{10, 20, 30}
for i, x := range xi {
fmt.Println(x)
}
// Go build failed: i declared but not used
Du kannst das i durch _ ersetzen, was dem Compiler mitteilt, dass wir diesen Wert nicht verwenden:
xi := []int{10, 20, 30}
for _, x := range xi {
fmt.Println(x)
}
// outputs:
// 10
// 20
// 30
Wenn du nur den Index ausgeben möchtest, kannst du das x durch _ ersetzen
oder die Deklaration einfach weglassen:
xi := []int{10, 20, 30}
// for i, _ := range xi {
for i := range xi {
fmt.Println(i)
}
// outputs:
// 0
// 1
// 2
Eine Typdefinition erzeugt einen neuen benannten Typ, der sich von jedem anderen Typ unterscheidet, selbst von einem mit demselben zugrunde liegenden Typ.
type File []bool
File bezeichnet hier eine einzelne vertikale Spalte auf einem Schachbrett, die üblicherweise mit A bis H beschriftet ist.
Jedes Feld in dieser Spalte wird durch einen booleschen Wert dargestellt, der angibt, ob es besetzt ist oder nicht.
Nachdem File nun definiert ist, können wir es in anderen Definitionen verwenden:
type Chessboard map[string]File
board := Chessboard{
"A": File{true, false, true},
"B": File{false, true, false},
}
Chessboard ordnet Spaltenbezeichner den File-Werten zu.
Ein File ist jeweils ein Slice von booleschen Werten, das die Felder einer Schachspalte repräsentiert.
Ohne diese Typdefinitionen wäre board ein map[string][]bool, was es schwerer verständlich machen würde, was wir darstellen.
Als Schachfan möchtest du deine eigene Version des Spiels schreiben. Klar, es gibt online schon reichlich Schach-Implementierungen, aber deine wird einzigartig!
Jedes Feld des Schachbretts wird durch ein Paar aus Buchstabe und Zahl angegeben:
A B C D E F G H
8 # _ _ _ # _ _ # 8
7 _ _ _ _ _ _ _ _ 7
6 _ _ _ _ # _ _ # 6
5 _ # _ _ _ _ _ # 5
4 _ _ _ _ _ _ # # 4
3 # _ # _ _ _ _ # 3
2 _ _ _ _ _ _ _ # 2
1 # _ _ _ _ _ _ # 1
A B C D E F G H
Implementiere die Funktion CountInFile(board Chessboard, file string) int.
Sie soll die Gesamtzahl der besetzten Felder zählen, indem sie über eine Map iteriert.
Gib eine Ganzzahl zurück.
Gib eine Anzahl von null (0) zurück, wenn die angegebene Linie nicht in der Map gefunden werden kann.
CountInFile(board, "A")
// => 3
Implementiere die Funktion CountInRank(board Chessboard, rank int) int.
Sie soll die Gesamtzahl der besetzten Felder zählen, indem sie über die angegebene Reihe iteriert.
Gib eine Ganzzahl zurück.
Gib eine Anzahl von null (0) zurück, wenn die angegebene Reihe ungültig ist (nicht zwischen 1 und 8, einschließlich).
CountInRank(board, 2)
// => 1
Implementiere die Funktion CountAll(board Chessboard) int.
Sie soll zählen, wie viele Felder auf dem Schachbrett vorhanden sind, und gibt eine Ganzzahl zurück.
Da du den Inhalt der Felder nicht überprüfen musst, kannst du range verwenden und dabei sowohl index als auch value weglassen.
CountAll(board)
// => 64
Implementiere die Funktion CountOccupied(board Chessboard) int.
Sie soll zählen, wie viele Felder auf dem Schachbrett besetzt sind.
Gib eine Ganzzahl zurück.
CountOccupied(board)
// => 15
Melde dich bei Exercism an, um Go mit 34 Konzepte166 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.