Las instrucciones condicionales brindan a los programadores la capacidad indicar a sus programas que realicen una acción si una condición es verdadera y otra si la condición es falsa. Con frecuencia, nos conviene comparar alguna variable con múltiples valores posibles y realizar diferentes acciones en cada circunstancia. Es posible lograr esto utilizando solo instrucciones if
. Sin embargo, escribir software no solo se trata de lograr que las cosas funcionen, sino también de comunicar su intención a usted mismo en el futuro y a otros desarrolladores. switch
es una instrucción condicional alternativa útil para comunicar las acciones realizadas por sus programas de Go cuando se les presentan diferentes opciones.
Todo lo que podamos escribir con la instrucción de switch también se puede escribir con instrucciones if
. En este tutorial, veremos algunos ejemplos de lo que puede lograr la instrucción switch, las instrucciones if
que sustituye y en que situaciones se aplica de forma más adecuada.
Switch se utiliza comúnmente para describir las acciones efectuadas por un programa cuando a una variable se le asignan valores específicos. En el siguiente ejemplo se muestra la forma en que lograríamos esto usando instrucciones if
:
package main
import "fmt"
func main() {
flavors := []string{"chocolate", "vanilla", "strawberry", "banana"}
for _, flav := range flavors {
if flav == "strawberry" {
fmt.Println(flav, "is my favorite!")
continue
}
if flav == "vanilla" {
fmt.Println(flav, "is great!")
continue
}
if flav == "chocolate" {
fmt.Println(flav, "is great!")
continue
}
fmt.Println("I've never tried", flav, "before")
}
}
Esto generará el siguiente resultado:
Outputchocolate is great!
vanilla is great!
strawberry is my favorite!
I've never tried banana before
Dentro de main
, definimos un slice de sabores de helado. Luego usaremos un for loop
para iterarlos. Utilizamos tres instrucciones if
para imprimir diferentes mensajes que indican preferencias por diferentes sabores de helado. Cada instrucción if
debe usar la instrucción continue
para detener la ejecución del bucle for
, de modo que el mensaje predeterminado al final no se imprima para los sabores de helado preferidos.
Al añadir nuevas preferencias de helado, debemos seguir agregando instrucciones if
para manejar los nuevos casos. En los mensajes duplicados, como en el caso de “vanilla”
y “chocolate”
, deben estar duplicadas las instrucciones if
. Para los futuros lectores de nuestro código (incluidos nosotros), la naturaleza repetitiva de las instrucciones if
oculta la parte importante de lo que hacen, (cuando se compara la variable con varios valores y tomando y se toman diferentes acciones). Además, nuestro mensaje de reserva se distingue de los condicionales y hace que parezca que no está relacionado. La instrucción switch
puede servirnos para organizar mejor esta lógica.
La instrucción switch
comienza con la palabra clave switch
y le sigue, en su forma más básica, alguna variable contra la cual puedan realizarse comparaciones. A esto le sigue un par llaves ({}
) en el que pueden aparecer varias_ cláusulas de caso_. Las cláusulas de caso describen las acciones que su programa de Go debe realizar cuando la variable proporcionada a la instrucción switch es igual al valor referido por las cláusulas de caso. El siguiente ejemplo convierte el ejemplo anterior para que utilice switch
en lugar de varias instrucciones if
:
package main
import "fmt"
func main() {
flavors := []string{"chocolate", "vanilla", "strawberry", "banana"}
for _, flav := range flavors {
switch flav {
case "strawberry":
fmt.Println(flav, "is my favorite!")
case "vanilla", "chocolate":
fmt.Println(flav, "is great!")
default:
fmt.Println("I've never tried", flav, "before")
}
}
}
El resultado es el mismo que el anterior:
Outputchocolate is great!
vanilla is great!
strawberry is my favorite!
I've never tried banana before
Una vez más, definimos un segmento de sabores de helado en main
y usamos la instrucción range
para iterar cada sabor. Sin embargo, esta vez usamos una instrucción switch
que examinará la variable flav
. Utilizamos dos cláusulas case
para indicar las preferencias. Ya no necesitamos las instrucciones continue
porque la instrucción switch
solo ejecutará una cláusula case
. También podemos combinar la lógica duplicada de los condicionales “chocolate”
y “vanilla”
separando cada uno con una coma en la declaración de la cláusula case
. La cláusula default
sirve como cláusula general. Se ejecutará para cualquier sabor que no hayamos tenido en cuenta en el cuerpo de la instrucción switch
. En este caso, “banana”
hará que se ejecute default
, con lo cual se imprimirá el mensaje I've never tried banana before
.
Esta forma simplificada de las instrucciones switch
aborda el uso más común para ellas: comparar una variable con varias alternativas. También nos proporciona practicidad cuando queremos realizar la misma acción para varios valores diferentes y cualquier otra acción cuando no se cumple ninguna de las condiciones enumeradas al usar la palabra clave default
.
Cuando esta forma simplificada de switch
resulta demasiado limitada, podemos usar una forma más general de la instrucción switch
.
Las instrucciones switch
son útiles para agrupar las colecciones de condicionales más complicadas a fin de mostrar que están de algún modo relacionadas. Esto se utiliza con mayor frecuencia al comparar una variable con un rango de valores, en lugar de valores específicos como en el ejemplo anterior. El siguiente ejemplo implementa un juego de adivinanzas usando instrucciones if
que se podrían beneficiar con una instrucción switch
:
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano())
target := rand.Intn(100)
for {
var guess int
fmt.Print("Enter a guess: ")
_, err := fmt.Scanf("%d", &guess)
if err != nil {
fmt.Println("Invalid guess: err:", err)
continue
}
if guess > target {
fmt.Println("Too high!")
continue
}
if guess < target {
fmt.Println("Too low!")
continue
}
fmt.Println("You win!")
break
}
}
El resultado puede variar dependiendo del número aleatorio que seleccionó y de lo bien que se desempeñe en el juego. A continuación, se muestra el resultado de una sesión de ejemplo:
OutputEnter a guess: 10
Too low!
Enter a guess: 15
Too low!
Enter a guess: 18
Too high!
Enter a guess: 17
You win!
En nuestro juego de adivinanzas se requiere un número al azar para compararlas, por lo que usamos la función rand.Intn
del paquete math/rand
. A fin de asegurarnos de obtener valores diferentes para target
cada vez que juguemos, usamos rand.Seed
para aleatorizar el generador de números aleatorios según la hora actual. El argumento 100
en rand.Intn
nos proporcionará un número dentro del rango de 0 a 100. Luego, usaremos un bucle for
para comenzar a recopilar adivinanzas del jugador.
La función fmt.Scanf
nos proporciona un medio para leer las entradas del usuario en una variable que elijamos. Se requiere un verbo de cadena de formato que convierta la entrada del usuario al tipo que esperamos. Aquí %d
significa que esperamos un int
y pasamos la dirección de la variable guess
de modo que fmt.Scanf
pueda establecer esa variable. Después de manejar cualquier error de análisis, usamos dos instrucciones if
para comparar la adivinanza del usuario con el valor target
. El string
que muestran, junto con bool
, controla el mensaje que se presenta al jugador y si el juego se cerrará.
Estas instrucciones if
ocultan el hecho de que el rango de valores con los que se compara la variable están todos relacionados de alguna manera. También puede ser difícil, a simple vista, saber si faltó alguna parte del rango. En el siguiente ejemplo se vuelve a refactorizar el ejemplo anterior para usar una instrucción switch
en su lugar:
package main
import (
"fmt"
"math/rand"
)
func main() {
target := rand.Intn(100)
for {
var guess int
fmt.Print("Enter a guess: ")
_, err := fmt.Scanf("%d", &guess)
if err != nil {
fmt.Println("Invalid guess: err:", err)
continue
}
switch {
case guess > target:
fmt.Println("Too high!")
case guess < target:
fmt.Println("Too low!")
default:
fmt.Println("You win!")
return
}
}
}
Con esto, se mostrará un resultado similar al siguiente:
OutputEnter a guess: 25
Too low!
Enter a guess: 28
Too high!
Enter a guess: 27
You win!
En esta versión del juego de adivinanzas, se sustituyó el bloque de instrucciones if
por una instrucción switch
. Se omite el argumento de la expresión de switch
, ya que solo nos interesa recopilar los condicionales juntos utilizando switch
. Cada cláusula case
contiene una expresión diferente que compara guess
con target
. Como la primera vez que sustituimos las instrucciones if
por switch
, ya no necesitamos las instrucciones continue
porque solo se ejecutará una cláusula case
. Por último, la cláusula default
se encarga del caso en el que guess == target
, ya que cubrimos todos los demás valores posibles con las otras dos cláusulas case
.
En los ejemplos que vimos hasta el momento, se ejecutará exactamente una instrucción caso. De vez en cuando, es posible que desee combinar los comportamientos de varias cláusulas case
. Las instrucciones switch
proporcionan otra palabra clave para lograr este comportamiento.
A veces, querrá volver a utilizar el código que otra cláusula case
contiene. En estos casos, es posible solicitar que Go ejecute el cuerpo de la siguiente cláusula case
enumerada usando la palabra clave fallthrough
. En el siguiente ejemplo, se modifica nuestro ejemplo anterior de sabores de helado para reflejar con mayor precisión nuestro entusiasmo por el helado de fresa:
package main
import "fmt"
func main() {
flavors := []string{"chocolate", "vanilla", "strawberry", "banana"}
for _, flav := range flavors {
switch flav {
case "strawberry":
fmt.Println(flav, "is my favorite!")
fallthrough
case "vanilla", "chocolate":
fmt.Println(flav, "is great!")
default:
fmt.Println("I've never tried", flav, "before")
}
}
}
Veremos el siguiente resultado:
Outputchocolate is great!
vanilla is great!
strawberry is my favorite!
strawberry is great!
I've never tried banana before
Como ya lo observamos antes, definimos un segmento string
para representar los sabores e iterar este usando un bucle for
. La instrucción switch
aquí es idéntica a la que vimos antes, pero se agrega la clave fallthrough
al final de la cláusula case
para “strawberry”
. Esto hará que Go ejecute el cuerpo de case “strawberry”:
, imprimiendo primero la cadena strawberry is my favorite!
. Cuando este encuentre fallthrough
, ejecutará el cuerpo de la cláusula case
siguiente. Esto hará que el cuerpo de case “vanilla”, “chocolate”:
se ejecute e imprima strawberry is great!
.
Los desarrolladores de Go no utilizan la palabra clave fallthrough
a menudo. Normalmente, la reutilización del código mediante fallthrough
se puede obtener de mejor manera definiendo una función con el código común. Por estas razones, generalmente no se recomienda utilizar fallthrough
.
Las instrucciones switch
nos ayudan a transmitir, a otros desarrolladores que leen nuestro código, que una serie de comparaciones están de alguna manera relacionadas entre sí. Hacen que sea mucho más fácil añadir comportamientos diferentes cuando un nuevo caso se añade en el futuro y permite garantizar que cualquier cosa que se haya olvidado se maneje de manera adecuada también con cláusulas default
. La próxima vez que tenga que escribir varias instrucciones if
que impliquen todas la misma variable, intente reescribirla con una instrucción switch
, le resultará más sencillo volver a trabajar cuando llegue el momento de considerar algún otro valor alternativo.
Si desea obtener más información acerca del lenguaje de programación de Go, consulte toda la serie sobre Cómo realizar codificaciones en Go.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!