Cristhian Villegas
Backend9 min read1 views

Curso Go #3: Control de Flujo — if, switch y Bucles

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.

Logo de Go

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.

go
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}
Importante: La variable declarada en la sentencia de inicializacion del 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.

go
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:

OperadorSignificadoEjemplo
==Igual a5 == 5 es true
!=Diferente de5 != 3 es true
>Mayor que10 > 7 es true
<Menor que3 < 8 es true
>=Mayor o igual5 >= 5 es true
<=Menor o igual4 <= 3 es false

Los operadores logicos permiten combinar varias condiciones:

OperadorSignificadoEjemplo
&&AND logicotrue && false es false
||OR logicotrue || false es true
!NOT logico!true es false
go
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.

go
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}
Tip: En Go, cada 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.

go
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.

go
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}
Cuidado: Usa 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:

go
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:

go
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):

go
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:

go
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.

go
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:

go
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}
Nota: Las etiquetas en Go deben ir justo antes del 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".

go
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:

go
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:

go
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}
Tip: Este ejemplo combina 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 fallthrough opcional
  • 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 break o return
  • 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.

Share:
CV

Cristhian Villegas

Software Engineer specializing in Java, Spring Boot, Angular & AWS. Building scalable distributed systems with clean architecture.

Comments

Sign in to leave a comment

No comments yet. Be the first!

Related Articles