Entendiendo las variables en Go: guía básica para principiantes

Sirpyerre Rojas
7 min readJan 3, 2023

--

De Golang +

Antes que nada les quiero desear un feliz año nuevo 2023, espero que este año sea mejor que el anterior y que todos los proyectos que tengan en mente se puedan realizar.

Continuamos con el curso de Go, en esta ocasión vamos a aprender sobre las variables en Go.

Hasta ahora hemos visto los tipos de datos básicos en Go. Hemos visto cómo usar valores literales como 42 y "Hola mundo". Pero, ¿cómo podemos usar estos valores en nuestro programa? ¿Cómo podemos guardarlos para usarlos más tarde? ¿Cómo podemos cambiarlos? Para responder estas preguntas, vamos a aprender sobre las variables.

Las variables son contenedores para almacenar valores. Por ejemplo: x es una variable. Cuando le asignamos un valor, como x=1, decimos que la variable x tiene el valor 1.

Las variables representan dos cosas:

  1. La cantidad de memoria que vamos a leer y escribir.
  2. Lo que representa esa memoria.

Las variables son el corazón del lenguaje. Los tipos son la vida.

Todas las variables tienen un tipo, y el tipo de una variable determina el tamaño y la representación de la variable. Las variables deben ser declaradas antes de ser usadas.

Ejemplo:

var i int

La palabra reservada var indica que se va a declarar una variable. La palabra reservada int indica que la variable va a ser de tipo entero.

Se pueden declarar varias variables en una sola línea:

var i,j,k int

El nombre de la variable es usado para referirse a la variable en el código.

Vamos a cambiar el programa de “Hola mundo” para usar variables:

package main

import "fmt"

func main() {
var saludo string = "Hola mundo"
fmt.Println(saludo )
}

Nota que la string literal del programa original sigue apareciendo en el programa. Pero en lugar de enviar la cadena directamente a la función Println, la cadena se almacena en la variable saludo. Las variables en Go son creadas con la palabra clave var, entonces el nombre de la variable, luego el tipo de la variable, y finalmente el valor de la variable. El valor de la variable puede ser omitido, en cuyo caso su valor será el valor por defecto para el tipo de la variable.

Valores por defecto

Cuando una variable es declarada sin un valor explícito, el compilador asigna un valor por defecto a la variable. El valor por defecto depende del tipo de la variable. Por ejemplo:

  • Las variables de tipo entero son inicializadas con el valor 0.
  • Las de tipo flotante son inicializadas con el valor 0.0 .
  • Las de tipo booleanas son inicializadas en false .
  • De tipo string son inicializadas con el valor ""(cadena vacía).

Podemos omitir el valor de la variable en la declaración y después asignarle el valor y el programa funcionará igual:

package main

import "fmt"

func main() {
var saludo string
saludo = "Hola mundo"
fmt.Println(saludo )
}

Ya vimos cómo declarar variables pero no es la única forma de hacerlo:

  • Declaración e inicialización: var foo int = 42
  • Multiple declaración: var foo, bar int = 42, 13
  • Con inferencia de tipos: var foo, bar = 42, "bar"
  • Sin inicialización: var foo int

A Go no le gusta el código muerto, por lo que si una variable no se usa, el compilador nos dará un error. Por ejemplo, si intentamos compilar el siguiente programa:

package main

import "fmt"

func main() {
var saludo string = "Hola mundo"
}

El compilador nos dará el siguiente error:

./variables.go:6:2: saludo declared and not used

Declaración corta de variables

Go permite declarar variables de forma más concisa usando la palabra clave :=. Esta forma de declaración solo puede ser usada dentro de una función. Cuando usamos :=para declarar una variable, no es necesario especificar el tipo de la variable, ya que el compilador lo infiere por el valor de la variable. La estructura de la declaración es:

nombre := expresión

Esta forma puede ser usada para declarar una sola variable, o para declarar múltiples variables. Por ejemplo:

  • Con inicialización: foo := rand.Float64() * 100.0
  • Multiple declaración: foo, bar := 42, "bar"

En la práctica la declaración corta es la forma más común de declarar e inicializar variables; varse usa principalmente para declarar variables que necesitan un tipo explícito o que se inicializan más tarde.

Cómo nombrar una variable

Nombrar variables apropiadamente es importante en el desarrollo de software.

El compilador de Go no cuida de los nombres de las variables, pero es importante que los nombres de las variables sean descriptivos y describan su propósito.

Supongamos que tenemos el siguiente código:

x := "Max"
fmt.Println("My dog's name is", x)

El nombre de la variable x no nos dice nada sobre el propósito de la variable. Vamos a cambiar el nombre de la variable a dogName:

dogName := "Max"
fmt.Println("My dog's name is", dogName)

El nombre de la variable dogName nos dice que la variable contiene el nombre de un perro. La variable dogNamees más descriptiva que x y hace que el código sea más legible.

En el código anterior, usamos la forma camelCase para nombrar la variable. La forma camelCase es la forma más común de nombrar variables en Go. En la forma camelCase, la primera letra de cada palabra es mayúscula, excepto la primera palabra, que comienza con una letra minúscula. Por ejemplo, dogName y maxson nombres de variables en la forma camelCase.

Palabras reservadas

Go tiene 25 palabras reservadas que no pueden ser usadas como nombres de variables. Estas palabras reservadas son:

break        default      func         interface    select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var

Alcance de una variable (scope)

El alcance de una variable es el lugar en el código donde la variable puede ser usada.

Bloques

En Go, las variables son declaradas dentro de bloques. Un bloque es un conjunto de declaraciones entre llaves {}. Por ejemplo, el bloque de código dentro de la función main es un bloque. El bloque de código dentro de un ifes un bloque. El bloque de código dentro de un fores un bloque. Cada bloque tiene su propio alcance. Las variables declaradas dentro de un bloque no pueden ser usadas fuera del bloque. Por ejemplo, la variable x declarada dentro del bloque de código de la función main no puede ser usada fuera de la función main:

package main

import "fmt"

func main() {
x := 42
fmt.Println(x)
}

La variable x declarada dentro del bloque de código del if no puede ser usada fuera del if:

package main

import "fmt"

func main() {
if true {
x := 42
fmt.Println(x)
}
fmt.Println(x)
}

El compilador nos dará el siguiente error:

./scope.go:10:2: undefined: x

Lexical Scoping (alcance léxico)

Go mira primero las partes más internas del código para localizar una variable, si no la encuentra, mirá las partes más externas del código y así hasta encontrarla. Este es el concepto de alcance léxico. Por ejemplo, la variable xdeclarada dentro del bloque de código del if puede ser usada dentro del bloque de código del for:

package main

import "fmt"

func main() {
if true {
x := 42
fmt.Println(x)
}
for x := 0; x < 100; x++ {
fmt.Println(x)
}
}

Identificador en blanco

El identificador en blanco, representado por el operador _ guión bajo (underscore), es una variable que se puede usar para ignorar valores.

Es comúnmente usado para ignorar valores innecesarios en una asignación, lo que puede ser útil en un lenguaje que admite múltiples retornos y exige que no haya variables sin usar. Por ejemplo, la función fmt.Println retorna dos valores, el primero es el número de bytes escritos y el segundo es un error. Si no nos interesa el error, podemos usar el identificador en blanco para ignorarlo:

package main

import "fmt"

func main() {
n, _ := fmt.Println("Hello, playground")
fmt.Println(n)
}

El identificador en blanco también puede ser usado para importar un paquete únicamente por sus efectos secundarios, es decir, para ejecutar el código dentro del paquete.

import _ "github.com/lib/pq"

Los paquetes importados de esta forma se crean e inicializan de manera normal, incluyendo la activación de cualquiera de sus funciones de inicio, pero el código del paquete no puede ser referenciado desde el código del programa.

Por ejemplo, el siguiente código no compila:

import _ "github.com/lib/pq"

func main() {
pq.Open("...")
}

El compilador nos dará el siguiente error:

./blank.go:6:2: undefined: pq

Constantes

Las constantes son similares a las variables, excepto que su valor no puede ser cambiado y deben ser inicializadas al declararlas: estas no tienen un valor 0. Las constantes se declaran usando la palabra reservada const:

package main

import "fmt"

func main() {
const x = "Hello world"
fmt.Println(x)
}

Ahora intenta cambiar el valor de la constante x:

x = "otra cadena"

El compilador nos dará el siguiente error:

./constants.go:8:2: cannot assign to x

Tanto varcomo const se pueden usar tanto a nivel de paquete y nivel función, de la siguiente manera:

package main

import "fmt"

const language string = "Go"

var favorite bool = true

func main() {
const text = "Does %s rule? %t!"
var output = fmt.Sprintf(text, language, favorite)
fmt.Println(output)
}

Para demostrar su comportamiento similar el programa anterior mezcla arbitrariamente definiciones de tipos explícitos con inferencia de tipos tanto para las constantes como para las variables.

Por ahora es todo con respecto a las variables y constantes, en la siguiente entrega veremos las estructuras de control.

Recapitulando un poco desde el primer post hemos visto:

  • ¿Qué es Go? y sus características.
  • Instalación de Visual Studio Code y las herramientas de Go.
  • Instalación de Go.

En la segunda entrega vimos los siguientes temas:

  • Hola mundo en Go.
  • Cómo leer un programa en Go.
  • Y las partes de un programa en Go.

En la tercera parte del tutorial vimos los tipos de datos en Go y nos adentramos en los tipos de datos básicos.

Referencias:

  • Introducing Go: Build Reliable, Scalable Programs — Caleb Doxsey.
  • Cloud Native Go — Miek Gieben.
  • Imagen tomada de https://twitter.com/golangch

Muchas gracias por leer este artículo. Si te gustó, por favor compártelo con tus amigos y sígueme en Twitter o Linkedin para más contenido como este.

--

--

Sirpyerre Rojas

Desarrollador backend apasionado, especializado en Go y PHP. Siempre intentando mejorar mi código. Disfruto pasar tiempo con mi esposa e hijos.