Go

Go

Tutorial Go: Control de flujo y estructuras de bucle

Go Control de flujo y bucles te enseña bucles for clásicos, while e infinitos. Descubre cómo usar range en colecciones y controla tus bucles eficazmente.

Aprende Go GRATIS y certifícate

Uso del bucle for en sus distintas formas

En Go, el bucle for es la única estructura de bucle disponible, pero es lo suficientemente versátil para manejar diferentes patrones de iteración. 

La forma más común es el bucle for clásico, que se asemeja al de C o Java, compuesto por una inicialización, una condición y un post-proceso. Su sintaxis es:

for inicialización; condición; post-proceso {
    // bloque de código a ejecutar
}

Por ejemplo, para iterar de 0 a 9:

for i := 0; i < 10; i++ {
    fmt.Println(i)
}

En este ejemplo, la variable i se inicializa a 0, la condición i < 10 se evalúa antes de cada iteración, y i++ se ejecuta después de cada ciclo.

El bucle for también puede actuar como un bucle while. Si se omiten la inicialización y el post-proceso, el bucle for se comporta como un while tradicional:

i := 0
for i < 10 {
    fmt.Println(i)
    i++
}

Aquí, el bucle continúa mientras la condición i < 10 sea verdadera, incrementando i manualmente dentro del bloque.

Además, Go permite bucles for infinitos omitiendo todas las partes del encabezado. Este patrón es útil para servidores o tareas que deben ejecutarse continuamente:

for {
    // tareas a realizar continuamente
}

Para salir de un bucle infinito, es común utilizar una sentencia break en combinación con una condición dentro del cuerpo del bucle.

El uso de for en Go es fundamental para iterar sobre secuencias, como arrays, slices y mapas, utilizando la palabra clave range. Sin embargo, este tema se aborda en otra sección de la lección.

Iteración sobre colecciones con range

En Go, la palabra clave range es utilizada para iterar sobre colecciones como arrays, slices, strings, mapas y canales. La forma en que range interactúa con cada tipo de colección varía ligeramente, adaptándose a las características de cada estructura.

Cuando se usa range sobre un array o un slice, itera sobre los índices y valores de los elementos. La sintaxis es la siguiente:

numeros := []int{10, 20, 30}
for indice, valor := range numeros {
    fmt.Printf("Índice: %d, Valor: %d\n", indice, valor)
}

En este ejemplo, indice representa la posición del elemento en el array o slice, mientras que valor es el contenido en esa posición. Si solo se necesita el valor, el índice puede ser descartado usando el identificador de blanco _:

for _, valor := range numeros {
    fmt.Println(valor)
}

En el caso de los strings, range itera sobre cada runa (carácter Unicode) en el string, lo que es crucial para manejar correctamente los caracteres multibyte. Por ejemplo:

text := "Hola, mundo"
for index, runeValue := range text {
    fmt.Printf("Índice: %d, Runa: %c\n", index, runeValue)
}

En el caso de los mapas, range itera sobre las claves y valores. La sintaxis es similar, pero en este contexto, el primer valor es la clave y el segundo es el valor asociado a esa clave:

edades := map[string]int{"Juan": 30, "Ana": 25}
for clave, valor := range edades {
    fmt.Printf("%s tiene %d años\n", clave, valor)
}

Cuando range se utiliza sobre canales, solo se recibe un valor por iteración. Es una forma eficiente de leer desde un canal hasta que se cierre:

canal := make(chan int)
go func() {
    for i := 0; i < 3; i++ {
        canal <- i
    }
    close(canal)
}()

for valor := range canal {
    fmt.Println(valor)
}

En este ejemplo, el canal se cierra después de enviar tres valores, y el bucle for termina automáticamente cuando el canal se cierra.

IMPORTANT Un aspecto importante al usar range es que los valores iterados son copias de los elementos originales. Esto significa que cualquier modificación hecha al valor dentro del bucle no afectará al elemento original en la colección. Por ejemplo, al iterar sobre un slice, los cambios al valor no alterarán el slice subyacente.

Control de bucles con break y continue

En Go, el control de bucles se puede gestionar de forma eficiente utilizando las sentencias break y continue. Estas sentencias permiten modificar el flujo de ejecución dentro de los bucles, proporcionándole al desarrollador un control más preciso sobre cuándo y cómo se deben interrumpir o continuar las iteraciones.

La sentencia break se utiliza para salir inmediatamente de un bucle. Cuando se encuentra un break dentro de un bucle for, la ejecución del bucle se detiene y el control se transfiere a la siguiente instrucción después del bucle. Esta característica es especialmente útil para terminar un bucle cuando se cumple una condición específica, evitando iteraciones innecesarias. Un ejemplo típico es la búsqueda de un elemento en una colección:

numeros := []int{1, 2, 3, 4, 5}
buscar := 3
encontrado := false

for _, num := range numeros {
    if num == buscar {
        encontrado = true
        break // salir del bucle una vez encontrado
    }
}
fmt.Println("Número encontrado:", encontrado)

En este ejemplo, el bucle se interrumpe tan pronto como se encuentra el número buscado, lo que optimiza el rendimiento al evitar iteraciones adicionales.

Por otro lado, la sentencia continue se utiliza para omitir la iteración actual del bucle y pasar a la siguiente. Cuando se ejecuta un continue, el flujo de control salta al inicio del bucle, evaluando de nuevo la condición del bucle para determinar si debe continuar con la siguiente iteración. Esto es útil cuando se desea ignorar ciertas condiciones dentro de un bucle sin interrumpir completamente su ejecución. Un ejemplo común es la ignorancia de números pares en un bucle:

for i := 0; i < 10; i++ {
    if i%2 == 0 {
        continue // saltar los números pares
    }
    fmt.Println(i)
}

Aquí, el uso de continue permite que solo se impriman los números impares, omitiendo el procesamiento de los números pares.

El uso de break y continue en bucles proporciona un control granular sobre el flujo de ejecución, permitiendo optimizar el rendimiento y mejorar la legibilidad del código al manejar casos específicos de manera clara y concisa. En situaciones donde la lógica requiere salir de un bucle bajo ciertas condiciones o ignorar iteraciones específicas, estas sentencias son herramientas esenciales en la caja de herramientas de un desarrollador Go.

Aprende Go GRATIS online

Ejercicios de esta lección Control de flujo y estructuras de bucle

Evalúa tus conocimientos de esta lección Control de flujo y estructuras de bucle con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Todas las lecciones de Go

Accede a todas las lecciones de Go y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Accede GRATIS a Go y certifícate

Certificados de superación de Go

Supera todos los ejercicios de programación del curso de Go y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender la versatilidad del bucle for en Go.
  • Utilizar bucles for clásicos, while e infinitos.
  • Iterar sobre colecciones con range.
  • Controlar la ejecución de bucles usando break y continue.
  • Aplicar patrones de iteración en ejemplos prácticos.