Go-ban a for range egy kódblokkot ismétel meg egy range-kifejezés értékein.
A range-kifejezés dönti el, hogy az egyes iterációk egy vagy két értéket adnak-e vissza.
A range egy szeleten sorrendben adja vissza az egyes elemek indexét és értékét:
vals := []int{10, 20, 30}
for i, v := range vals {
fmt.Println(i, v)
}
// 0 10
// 1 20
// 2 30
A range egy mapen minden kulcsot és értéket visszaad, a bejárás sorrendje azonban nem garantált.
A Go szándékosan véletlenszerűvé teszi a map bejárásának sorrendjét, így ugyanaz a program minden futtatáskor más kimenetet adhat.
hash := map[int]int{9: 10, 99: 20, 999: 30}
for k, v := range hash {
fmt.Println(k, v)
}
// 99 20
// 999 30
// 9 10
A range egy stringen a bájtindexet és az egyes runékat (Unicode-kódpontokat) adja vissza.
A következő példában a 子 három bájtot foglal el, ezért a 猫 a 3 bájtindexnél kezdődik, nem az 1-nél.
for i, r := range "子猫" {
fmt.Println(i, r, string(r))
}
// 0 23376 子
// 3 29483 猫
Ha inkább rune-indexekre van szükséged, alakítsd át a stringet runék szeletévé:
for i, r := range []rune("子猫") {
fmt.Println(i, r, string(r))
}
// 0 23376 子
// 1 29483 猫
A range közvetlenül egy egész számon is végighaladhat, és 0-tól az adott számig ad értékeket, de magát a számot már nem foglalja bele.
A nulla és a negatív értékek érvényesek, de egyetlen iterációt sem eredményeznek.
for n := range 3 {
fmt.Println(n)
}
// 0
// 1
// 2
A range fogadhat iter.Seq[V] vagy iter.Seq2[K, V] típusú iterátort.
Az iterátor egy olyan függvény, amely egy értéksorozat elemeit egyenként állítja elő.
Ezután a range végig tud haladni ezeken az értékeken.
text := "The quick brown fox"
for word := range strings.FieldsSeq(text) {
fmt.Println(word)
}
// The
// quick
// brown
// fox
names := []string{"Alice", "Bob", "Vera"}
for i, v := range slices.All(names) {
fmt.Println(i, ":", v)
}
// 0 : Alice
// 1 : Bob
// 2 : Vera
Végül a range fogadhatja a csatornán keresztül küldött értékeket egészen addig, amíg a csatornát másutt le nem zárják.
A csatornákról a tanterv későbbi részében lesz szó részletesebben.
Go-ban egy fel nem használt változó hibát okoz fordításkor.
vals := []int{10, 20, 30}
for i, v := range vals {
fmt.Println(v)
}
// Go build failed: declared and not used: i
Ha csak az értékre van szükséged, akkor az indexet vagy a kulcsot rendeld _-hoz, hogy figyelmen kívül hagyd.
vals := []int{10, 20, 30}
for _, v := range vals {
fmt.Println(v)
}
// 10
// 20
// 30
Ha csak az indexre van szükséged, teljesen elhagyhatod az értéket:
vals := []int{10, 20, 30}
for i := range vals {
fmt.Println(i)
}
// 0
// 1
// 2
Ha sem az indexre, sem az értékre nincs szükséged, mindkettő elhagyható:
vals := []int{10, 20, 30}
count := 0
for range vals {
count++
}
// count == 3