Curso Go #3: Control de Flujo — if, switch y Bucles
Introduccion: controlar el flujo de tu programa en Go
Bienvenido a la Parte 3 del curso de Go para principiantes. En los articulos anteriores aprendiste a declarar variables y trabajar con tipos de datos. Ahora vamos a aprender algo fundamental: como hacer que tu programa tome decisiones y repita acciones.

Go tiene un enfoque minimalista para el control de flujo. A diferencia de otros lenguajes, Go solo tiene un tipo de bucle (el for), y su if tiene una caracteristica unica: puede incluir una sentencia de inicializacion. Estas decisiones de diseno hacen que el codigo Go sea mas limpio y predecible.
Al terminar este articulo seras capaz de escribir programas que reaccionen a diferentes condiciones, seleccionen entre multiples opciones con switch y repitan tareas con distintas variantes del bucle for.
Condicional if/else con sentencia de inicializacion
El if en Go funciona de manera similar a otros lenguajes, pero tiene una caracteristica que lo hace especial: puedes incluir una sentencia corta de inicializacion antes de la condicion.
1package main
2
3import "fmt"
4
5func main() {
6 edad := 20
7
8 // if basico
9 if edad >= 18 {
10 fmt.Println("Eres mayor de edad")
11 } else {
12 fmt.Println("Eres menor de edad")
13 }
14
15 // if con sentencia de inicializacion
16 if nota := 85; nota >= 90 {
17 fmt.Println("Excelente")
18 } else if nota >= 70 {
19 fmt.Println("Aprobado")
20 } else {
21 fmt.Println("Reprobado")
22 }
23 // nota no existe fuera del if
24}
if (como nota en el ejemplo) solo existe dentro del bloque if/else. Esto ayuda a mantener el scope lo mas reducido posible, que es una buena practica en Go.
A diferencia de C o Java, en Go no se usan parentesis alrededor de la condicion, pero las llaves son obligatorias incluso para una sola linea de codigo.
1// Esto NO compila en Go
2if edad >= 18
3 fmt.Println("Mayor de edad")
4
5// Esto SI es correcto
6if edad >= 18 {
7 fmt.Println("Mayor de edad")
8}
Operadores de comparacion y logicos
Para construir condiciones necesitas operadores de comparacion y logicos. Go soporta los siguientes:
| Operador | Significado | Ejemplo |
|---|---|---|
== | Igual a | 5 == 5 es true |
!= | Diferente de | 5 != 3 es true |
> | Mayor que | 10 > 7 es true |
< | Menor que | 3 < 8 es true |
>= | Mayor o igual | 5 >= 5 es true |
<= | Menor o igual | 4 <= 3 es false |
Los operadores logicos permiten combinar varias condiciones:
| Operador | Significado | Ejemplo |
|---|---|---|
&& | AND logico | true && false es false |
|| | OR logico | true || false es true |
! | NOT logico | !true es false |
1package main
2
3import "fmt"
4
5func main() {
6 edad := 25
7 tieneCredencial := true
8
9 if edad >= 18 && tieneCredencial {
10 fmt.Println("Puedes entrar al evento")
11 }
12
13 temperatura := 35
14 if temperatura < 0 || temperatura > 40 {
15 fmt.Println("Clima extremo, quedate en casa")
16 }
17}
Switch: seleccion multiple elegante
El switch en Go es mas poderoso y flexible que en muchos otros lenguajes. Tiene tres variantes principales.
Switch con expresion: evalua una variable contra multiples valores.
1package main
2
3import "fmt"
4
5func main() {
6 dia := "martes"
7
8 switch dia {
9 case "lunes":
10 fmt.Println("Inicio de semana")
11 case "martes", "miercoles", "jueves":
12 fmt.Println("Entre semana")
13 case "viernes":
14 fmt.Println("Casi fin de semana")
15 case "sabado", "domingo":
16 fmt.Println("Fin de semana")
17 default:
18 fmt.Println("Dia no valido")
19 }
20}
case tiene un break implicito. No necesitas escribir break al final de cada caso como en C o Java. Si quieres que la ejecucion continue al siguiente caso, usa la palabra clave fallthrough.
Switch sin condicion: reemplaza cadenas largas de if/else if. Es muy legible.
1package main
2
3import "fmt"
4
5func clasificarNota(nota int) string {
6 switch {
7 case nota >= 90:
8 return "Excelente"
9 case nota >= 80:
10 return "Muy bien"
11 case nota >= 70:
12 return "Aprobado"
13 case nota >= 60:
14 return "Suficiente"
15 default:
16 return "Reprobado"
17 }
18}
19
20func main() {
21 fmt.Println(clasificarNota(85)) // Muy bien
22 fmt.Println(clasificarNota(55)) // Reprobado
23}
Fallthrough: fuerza la ejecucion del siguiente caso sin evaluar su condicion.
1package main
2
3import "fmt"
4
5func main() {
6 numero := 5
7
8 switch {
9 case numero > 0:
10 fmt.Println("Positivo")
11 fallthrough
12 case numero > -10:
13 fmt.Println("Mayor que -10")
14 }
15 // Imprime: Positivo
16 // Mayor que -10
17}
fallthrough con precaucion. Es poco comun en Go y puede hacer que el codigo sea dificil de entender. La mayoria de los programadores Go prefieren evitarlo a menos que sea estrictamente necesario.
El bucle for: el unico bucle en Go
Go tiene un solo tipo de bucle: el for. Pero es tan versatil que cubre todos los casos que en otros lenguajes se manejan con while, do-while o foreach.
For clasico con inicializacion, condicion e incremento:
1package main
2
3import "fmt"
4
5func main() {
6 // For clasico (como en C/Java)
7 for i := 0; i < 5; i++ {
8 fmt.Println("Iteracion:", i)
9 }
10}
For estilo while — solo con condicion:
1package main
2
3import "fmt"
4
5func main() {
6 contador := 10
7
8 for contador > 0 {
9 fmt.Println("Cuenta regresiva:", contador)
10 contador--
11 }
12 fmt.Println("Despegue!")
13}
For infinito — sin condicion (se sale con break):
1package main
2
3import (
4 "bufio"
5 "fmt"
6 "os"
7 "strings"
8)
9
10func main() {
11 scanner := bufio.NewScanner(os.Stdin)
12
13 for {
14 fmt.Print("Escribe algo (o 'salir' para terminar): ")
15 scanner.Scan()
16 texto := scanner.Text()
17
18 if strings.ToLower(texto) == "salir" {
19 fmt.Println("Adios!")
20 break
21 }
22 fmt.Println("Escribiste:", texto)
23 }
24}
For range — para recorrer slices, arrays, maps y strings:
1package main
2
3import "fmt"
4
5func main() {
6 frutas := []string{"manzana", "platano", "naranja", "uva"}
7
8 // Con indice y valor
9 for indice, fruta := range frutas {
10 fmt.Printf("Posicion %d: %s
11", indice, fruta)
12 }
13
14 // Solo el valor (se ignora el indice con _)
15 for _, fruta := range frutas {
16 fmt.Println("Fruta:", fruta)
17 }
18
19 // Solo el indice
20 for i := range frutas {
21 fmt.Println("Indice:", i)
22 }
23}
Break, continue y etiquetas
Go ofrece break y continue para controlar el flujo dentro de los bucles, igual que otros lenguajes. Pero ademas soporta etiquetas (labels) para controlar bucles anidados.
1package main
2
3import "fmt"
4
5func main() {
6 // continue: salta a la siguiente iteracion
7 for i := 1; i <= 10; i++ {
8 if i%2 == 0 {
9 continue // Salta los numeros pares
10 }
11 fmt.Println("Impar:", i)
12 }
13
14 fmt.Println("---")
15
16 // break: sale del bucle
17 for i := 1; i <= 100; i++ {
18 if i > 5 {
19 break
20 }
21 fmt.Println("Numero:", i)
22 }
23}
Las etiquetas son utiles cuando tienes bucles anidados y quieres salir del bucle exterior desde el interior:
1package main
2
3import "fmt"
4
5func main() {
6exterior:
7 for i := 0; i < 5; i++ {
8 for j := 0; j < 5; j++ {
9 if i+j == 4 {
10 fmt.Printf("Saliendo en i=%d, j=%d
11", i, j)
12 break exterior // Sale del bucle exterior
13 }
14 fmt.Printf("i=%d, j=%d
15", i, j)
16 }
17 }
18 fmt.Println("Fin del programa")
19}
for al que hacen referencia. Se usan principalmente para salir de bucles anidados, algo que en otros lenguajes requiere variables de control auxiliares o funciones separadas.
Ejemplos practicos
Vamos a combinar todo lo aprendido en tres ejemplos clasicos de programacion.
FizzBuzz: imprime los numeros del 1 al 30. Si el numero es divisible entre 3, imprime "Fizz". Si es divisible entre 5, imprime "Buzz". Si es divisible entre ambos, imprime "FizzBuzz".
1package main
2
3import "fmt"
4
5func main() {
6 for i := 1; i <= 30; i++ {
7 switch {
8 case i%15 == 0:
9 fmt.Println("FizzBuzz")
10 case i%3 == 0:
11 fmt.Println("Fizz")
12 case i%5 == 0:
13 fmt.Println("Buzz")
14 default:
15 fmt.Println(i)
16 }
17 }
18}
Suma de elementos en un slice:
1package main
2
3import "fmt"
4
5func main() {
6 numeros := []int{10, 25, 33, 47, 52, 68, 71, 89}
7 suma := 0
8 mayor := numeros[0]
9
10 for _, n := range numeros {
11 suma += n
12 if n > mayor {
13 mayor = n
14 }
15 }
16
17 promedio := float64(suma) / float64(len(numeros))
18 fmt.Printf("Suma: %d
19", suma)
20 fmt.Printf("Promedio: %.2f
21", promedio)
22 fmt.Printf("Mayor: %d
23", mayor)
24}
Juego de adivinar un numero:
1package main
2
3import (
4 "fmt"
5 "math/rand"
6 "time"
7)
8
9func main() {
10 rand.Seed(time.Now().UnixNano())
11 secreto := rand.Intn(100) + 1
12 intentos := 0
13
14 fmt.Println("=== Adivina el Numero ===")
15 fmt.Println("He pensado un numero entre 1 y 100.")
16
17 for {
18 var respuesta int
19 fmt.Print("Tu respuesta: ")
20 _, err := fmt.Scan(&respuesta)
21 if err != nil {
22 fmt.Println("Por favor escribe un numero valido.")
23 continue
24 }
25
26 intentos++
27
28 switch {
29 case respuesta < secreto:
30 fmt.Println("Demasiado bajo. Intenta de nuevo.")
31 case respuesta > secreto:
32 fmt.Println("Demasiado alto. Intenta de nuevo.")
33 default:
34 fmt.Printf("Correcto! El numero era %d
35", secreto)
36 fmt.Printf("Lo lograste en %d intentos.
37", intentos)
38
39 switch {
40 case intentos <= 5:
41 fmt.Println("Increible, eres un genio!")
42 case intentos <= 10:
43 fmt.Println("Muy bien hecho!")
44 default:
45 fmt.Println("Lo lograste, pero puedes mejorar.")
46 }
47 return
48 }
49 }
50}
for infinito, switch sin condicion, continue para manejar errores de entrada y return para terminar la funcion cuando el usuario adivina. Es un buen ejercicio para practicar todo lo aprendido en este articulo.
Resumen y proximo articulo
En este articulo aprendiste las herramientas para controlar el flujo de ejecucion en Go:
- if/else con sentencia de inicializacion: toma decisiones con variables de scope limitado
- Operadores de comparacion y logicos: construye condiciones complejas con
==,!=,&&,|| - switch: seleccion multiple elegante, con o sin expresion, y
fallthroughopcional - for clasico: el unico bucle en Go, con inicializacion, condicion e incremento
- for estilo while: solo con condicion para repetir mientras se cumpla algo
- for infinito: se sale con
breakoreturn - for range: recorre slices, arrays, maps y strings de forma idiomatica
- break, continue y etiquetas: controlan la ejecucion en bucles simples y anidados
En el proximo articulo (Parte 4) aprenderemos sobre funciones y manejo de errores: como organizar tu codigo en funciones reutilizables, aprovechar los retornos multiples de Go y dominar el patron if err != nil.
Comments
Sign in to leave a comment
No comments yet. Be the first!