CAP 03 · LEC 02·Control de flujo

Bucles `for`: clásico, `while`-style y `range`

Go solo tiene una palabra clave para bucles: `for`. Con ella cubres el bucle clásico C-style, el `while` de otros lenguajes, los bucles infinitos y la iteración con `range`.

● PRINCIPIANTE6 min lecturapor Fernando Herrera · actualizado mayo de 2026
¿Encontraste un error o algo que mejorar?Editá esta lección en GitHub →

for clásico (estilo C)

El for clásico tiene tres componentes separados por ;: inicialización, condición y post. Igual que en C/Java, pero sin paréntesis alrededor.

package main import "fmt" func main() { for i := 0; i < 5; i++ { fmt.Print(i, " ") } fmt.Println() // Suma de 1 a 100 sum := 0 for i := 1; i <= 100; i++ { sum += i } fmt.Println("sum:", sum) // Recorrer hacia atrás for i := 5; i > 0; i-- { fmt.Print(i, " ") } fmt.Println() }
Salida0 1 2 3 4 sum: 5050 5 4 3 2 1

for como while

Si omites la inicialización y el post, te queda solo la condición — equivalente al while de otros lenguajes. Go no tiene while ni do-while: todo es for.

package main import "fmt" func main() { n := 1 for n < 100 { n *= 2 } fmt.Println("primer pow2 >= 100:", n) // Leer hasta una condición balance := 1000 day := 0 for balance > 0 { balance -= 75 day++ } fmt.Printf("balance agotado en %d días ", day) }
Salidaprimer pow2 >= 100: 128 balance agotado en 14 días

for infinito + break y continue

Sin condición alguna, for {} es un bucle infinito. Se sale con break, return o un panic. continue salta a la siguiente iteración.

package main import "fmt" func main() { i := 0 for { i++ if i%2 == 0 { continue } if i > 9 { break } fmt.Print(i, " ") } fmt.Println() // Equivale al patrón "loop con guarda interna" count := 0 for { if count >= 3 { break } fmt.Println("tick", count) count++ } }
Salida1 3 5 7 9 tick 0 tick 1 tick 2

break y continue con etiquetas

Cuando tienes bucles anidados y necesitas salir del bucle exterior (o saltar a su siguiente iteración) usa labels: un identificador seguido de : antes del for.

package main import "fmt" func main() { matrix := [][]int{ {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, } target := 5 outer: for i, row := range matrix { for j, v := range row { if v == target { fmt.Printf("encontrado %d en [%d][%d] ", v, i, j) break outer // sale de ambos bucles } } } // continue con label: salta a la siguiente fila rows: for _, row := range matrix { for _, v := range row { if v%2 == 0 { continue rows // descarta la fila completa al primer par } fmt.Print(v, " ") } } fmt.Println() }
Salidaencontrado 5 en [1][1] 1 7

for range: slices, maps, strings y channels

range produce uno o dos valores según lo que itere. Convención: descarta los que no uses con _.

package main import "fmt" func main() { // Slice: índice y valor fruits := []string{"manzana", "pera", "uva"} for i, v := range fruits { fmt.Printf("%d -> %s ", i, v) } // Solo el índice for i := range fruits { fmt.Print(i, " ") } fmt.Println() // Solo el valor: descarta el índice con _ total := 0 for _, n := range []int{10, 20, 30} { total += n } fmt.Println("total:", total) // Map: clave y valor (orden NO garantizado) scores := map[string]int{"ana": 90, "luis": 75} for k, v := range scores { fmt.Printf("%s=%d ", k, v) } fmt.Println() }
Salida0 -> manzana 1 -> pera 2 -> uva 0 1 2 total: 60 ana=90 luis=75

range sobre strings y channels

Iterar un string con range produce runes (puntos de código Unicode), no bytes. El índice es el offset en bytes, así que puede saltar valores en caracteres multibyte. Iterar un channel consume valores hasta que se cierra.

package main import "fmt" func main() { // range sobre string: (byteIndex, rune) for i, r := range "héllo" { fmt.Printf("%d: %c (%d) ", i, r, r) } // range sobre channel: lee hasta close() ch := make(chan int, 3) ch <- 1 ch <- 2 ch <- 3 close(ch) for v := range ch { fmt.Print(v, " ") } fmt.Println() }
Salida0: h (104) 1: é (233) 3: l (108) 4: l (108) 5: o (111) 1 2 3
El índice 2 se salta

é ocupa 2 bytes en UTF-8, por eso el índice pasa de 1 a 3. Si necesitas contar caracteres reales, itera con range (cuenta runes) o usa utf8.RuneCountInString.