for în Go

Singura buclă din Go: forma clasică, forma „while”, bucla infinită și parcurgerea cu range.

Sintaxă
for i := 0; i < n; i++ { ... }   // clasic
for conditie { ... }              // ca while
for { ... }                       // infinit
for i := range 10 { ... }         // 0..9 (Go 1.22)
for i, v := range colectie { ... }

Ce face for

Go are o singură instrucțiune de buclă: for. Forma clasică are trei părți separate prin ;: inițializarea (i := 0), condiția (i < n) și pasul (i++). Ca la if, nu se pun paranteze, dar acoladele sunt obligatorii.

Dacă păstrezi doar condiția, for se comportă ca while din alte limbaje. Fără nicio condiție, for { } este o buclă infinită, din care ieși cu break sau return. Cu range parcurgi slice-uri, map-uri, texte, canale, numere întregi (din Go 1.22) și funcții iterator (din Go 1.23).

Din Go 1.22, fiecare iterație are propria copie a variabilei buclei (i, v). Funcțiile anonime create în buclă nu mai văd toate aceeași variabilă, cum se întâmpla în versiunile vechi.

Parametri

Parametru Descriere
inițializare Se execută o dată, înainte de buclă. De obicei i := 0.
condiție Se verifică înaintea fiecărei iterații; bucla se oprește când devine falsă.
pas Se execută după fiecare iterație: i++, i += 2, i--.

Exemple

Exemplul 1: Cele trei forme ale lui for

Clasică, „while” și infinită cu break.

package main

import "fmt"

func main() {
    // clasic: de la 1 la 5
    suma := 0
    for i := 1; i <= 5; i++ {
        suma += i
    }
    fmt.Println("1+2+3+4+5 =", suma)

    // ca while: dublăm până trecem de 100
    n := 3
    for n < 100 {
        n *= 2
    }
    fmt.Println("primul dublu peste 100:", n)

    // infinit, oprit cu break
    zile := 0
    economii := 0
    for {
        zile++
        economii += 15
        if economii >= 100 {
            break
        }
    }
    fmt.Printf("după %d zile Ana are %d lei\n", zile, economii)
}

Rezultat

1+2+3+4+5 = 15
primul dublu peste 100: 192
după 7 zile Ana are 105 lei

Exemplul 2: range peste un slice și peste un număr

range dă poziția și valoarea. range 3 (Go 1.22) numără 0, 1, 2.

package main

import "fmt"

func main() {
    orase := []string{"Iași", "Cluj", "Timișoara"}
    for i, oras := range orase {
        fmt.Println(i, oras)
    }

    for i := range 3 {
        fmt.Print("pasul ", i, "; ")
    }
    fmt.Println()
}

Rezultat

0 Iași
1 Cluj
2 Timișoara
pasul 0; pasul 1; pasul 2;

Exemplul 3: Bucle imbricate: tabla înmulțirii

O buclă în altă buclă; %3d aliniază numerele pe 3 caractere.

package main

import "fmt"

func main() {
    for i := 1; i <= 4; i++ {
        for j := 1; j <= 4; j++ {
            fmt.Printf("%3d", i*j)
        }
        fmt.Println()
    }
}

Rezultat

  1  2  3  4
  2  4  6  8
  3  6  9 12
  4  8 12 16

Greșeli frecvente

  • Căutarea lui while sau do-while: nu există, totul se scrie cu for.
  • for i := 0; i < len(s); i++ pe un text: parcurge octeți, nu litere. Pentru litere cu diacritice folosește for _, r := range s.
  • Modificarea lui v în for _, v := range s nu schimbă slice-ul: v este o copie. Scrie s[i] = ....

Comenzi înrudite

  • range: Parcurge într-un for elementele unui slice, array, map, text, canal, număr sau iterator.
  • break: Oprește imediat cea mai apropiată buclă for, switch sau select; cu etichetă oprește o buclă exterioară.
  • continue: Sare peste restul iterației curente și trece la următoarea iterație a buclei for.
  • 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.