Ce face range
range se folosește doar în for și dă, la fiecare pas, una sau două valori. Pentru slice-uri și array-uri: poziția și elementul. Pentru map-uri: cheia și valoarea. Pentru texte: poziția în octeți și litera (rune), decodată din UTF-8. Pentru canale: valoarea primită, până când canalul este închis.
Dacă nu ai nevoie de o valoare, o înlocuiești cu _: for _, v := range s. Dacă vrei doar poziția sau cheia, scrii o singură variabilă: for i := range s. Din Go 1.22, for i := range 5 numără de la 0 la 4, iar din Go 1.23 poți parcurge funcții iterator (iter.Seq), de exemplu maps.Keys(m).
Ordinea parcurgerii unui map este aleatorie și diferă de la o rulare la alta. Dacă ai nevoie de o ordine fixă, sortează cheile (slices.Sorted(maps.Keys(m))) și parcurge-le pe ele.
Ce returnează
Nu returnează nimic; dă valori variabilelor buclei la fiecare iterație.
Exemple
Exemplul 1: Slice, text și număr
La text, poziția sare cu 2 la „ș”, pentru că litera ocupă 2 octeți în UTF-8.
package main
import "fmt"
func main() {
note := []int{9, 7, 10}
suma := 0
for _, n := range note {
suma += n
}
fmt.Println("suma notelor:", suma)
for i, litera := range "Iași" {
fmt.Printf("poziția %d: %c\n", i, litera)
}
for i := range 3 {
fmt.Print(i, " ")
}
fmt.Println()
}
Rezultat
suma notelor: 26
poziția 0: I
poziția 1: a
poziția 2: ș
poziția 4: i
0 1 2
Exemplul 2: Map parcurs în ordine sortată
slices.Sorted(maps.Keys(m)) dă cheile sortate, deci rezultatul este același la fiecare rulare.
package main
import (
"fmt"
"maps"
"slices"
)
func main() {
populatie := map[string]int{
"Iași": 271692,
"Cluj": 286598,
"Constanța": 263688,
}
for _, oras := range slices.Sorted(maps.Keys(populatie)) {
fmt.Printf("%-10s %d\n", oras, populatie[oras])
}
}
Rezultat
Cluj 286598
Constanța 263688
Iași 271692
Exemplul 3: range peste un canal
Bucla primește valori până când canalul este închis cu close.
package main
import "fmt"
func main() {
comenzi := make(chan string, 3)
comenzi <- "pizza"
comenzi <- "ciorbă"
comenzi <- "papanași"
close(comenzi)
for c := range comenzi {
fmt.Println("pregătesc:", c)
}
fmt.Println("gata, canalul este închis")
}
Rezultat
pregătesc: pizza
pregătesc: ciorbă
pregătesc: papanași
gata, canalul este închis
Greșeli frecvente
- Bazarea pe ordinea dintr-un map: ea diferă la fiecare rulare. Sortează cheile înainte.
for x := range screzând căxeste valoarea: cu o singură variabilă primești poziția (la slice) sau cheia (la map).rangepeste un canal care nu este închis niciodată: bucla așteaptă la nesfârșit, iar programul se oprește cuall goroutines are asleep - deadlock!.
Comenzi înrudite
for: Singura buclă din Go: forma clasică, forma „while”, bucla infinită și parcurgerea cu range.for range peste funcții (iteratori): Din Go 1.23, for range parcurge funcții iterator: funcții care trimit pe rând valorile prin yield.map și map-uri: Tabel cheie-valoare (dicționar): căutare rapidă după cheie, adăugare, ștergere și verificare cu v, ok.string-uri, rune și byte: Textul în Go este UTF-8: len dă octeți, range dă rune (caractere), byte este un octet, rune un caracter.chan și canale (channels): Canalele (chan) transmit valori între goroutine în siguranță și le sincronizează; se creează cu make.