Saltar al contenido

Variables, tipos y valores cero

Al terminar esta lección vas a poder guardar datos en variables, elegir el tipo de cada una (un número entero, un número con decimales, un texto o un sí o un no) y saber qué valor tiene una variable a la que no le diste ninguno. También vas a saber leer los errores que aparecen cuando una variable sobra, cuando la declaras dos veces o cuando su valor no es del tipo correcto.

Declarar una variable con var

En la lección anterior, la Papelería Central imprimía textos fijos. Ahora va a guardar datos: el nombre de un producto y cuántas unidades le quedan.

main.go
package main

import "fmt"

func main() {
	var producto string = "cuaderno"
	var stock int = 24
	fmt.Println(producto)
	fmt.Println(stock)
}

Salida:

cuaderno
24

Una variable es un nombre que guarda un valor para usarlo después. Declarar una variable es crearla: desde esa línea, el nombre existe y guarda su valor. var producto string = "cuaderno" se lee por partes:

  • var dice que vas a declarar una variable.
  • producto es su nombre.
  • string es su tipo: la clase de valor que guarda. Los tipos los ves en una sección más abajo.
  • = "cuaderno" le da su primer valor.

fmt.Println(producto) imprime cuaderno, no la palabra producto. Sin comillas, producto es el nombre de una variable, y Go usa el valor que guarda. Con comillas, "producto" sería un texto, y Go lo imprimiría tal cual.

Cambiar el valor con =

La papelería vende tres cuadernos y el stock baja a 21. La variable ya existe, así que solo le das un valor nuevo:

main.go
package main

import "fmt"

func main() {
	var stock int = 24
	fmt.Println(stock)
	stock = 21
	fmt.Println(stock)
}

Salida:

24
21

stock = 21 asigna un valor nuevo a stock: el 21 reemplaza al 24. Como main se ejecuta de arriba abajo, el primer fmt.Println imprime 24 y el segundo, 21.

Una variable se declara una sola vez y después puede cambiar de valor todas las veces que haga falta, con =. Por eso se llama variable. En stock = 21 no va var: sería una segunda declaración de stock, y Go no deja declarar dos veces el mismo nombre.

Los tipos básicos

Cada variable tiene un tipo, y el tipo decide qué valores puede guardar. Estos son los cuatro que más vas a usar, con los datos de un producto de la papelería:

main.go
package main

import "fmt"

func main() {
	var producto string = "cuaderno"
	var stock int = 24
	var precio float64 = 2.75
	var enOferta bool = true
	fmt.Println(producto)
	fmt.Println(stock)
	fmt.Println(precio)
	fmt.Println(enOferta)
}

Salida:

cuaderno
24
2.75
true

  • string: un texto, entre comillas dobles. producto vale cuaderno.
  • int: un número entero, sin decimales, que también puede ser negativo. stock vale 24. El nombre viene de integer, entero en inglés.
  • float64: un número con decimales. precio vale 2.75. El nombre viene de floating point (punto flotante), la forma en que la computadora guarda los decimales, y el 64 es su tamaño en memoria.
  • bool: un valor que solo puede ser true (verdadero) o false (falso). Sirve para los datos de sí o no: enOferta vale true, así que el cuaderno está en oferta.

Go tiene más tipos numéricos, que se diferencian por su tamaño en memoria. Ese tamaño se mide en bits: un bit es la unidad más chica de memoria, un 0 o un 1, y con más bits caben más valores. El número del nombre es ese tamaño, como el 64 de float64:

  • int8, int16, int32 e int64: enteros con signo. Un int8 guarda de -128 a 127.
  • uint, y uint8 a uint64: enteros sin signo, que no guardan negativos. Un uint8 guarda de 0 a 255.
  • float32: números con decimales, con menos precisión que float64.

Existen para casos especiales, como un formato de archivo que fija el tamaño de cada número. Para un entero, usa int, y para un número con decimales, float64: son los que usa casi toda la biblioteca estándar, y los que vas a usar casi siempre.

Los decimales se escriben con punto, como en inglés: 2.75. Si escribes var precio float64 = 2,75, Go lee dos valores separados por una coma, 2 y 75, y el programa no compila.

Como viste en la lección anterior, Go tiene tipado estático: el tipo de una variable queda fijo al declararla. Una variable int guarda siempre enteros. Un error típico es escribir un número entre comillas:

main.go
package main

import "fmt"

func main() {
	var stock int = "24"
	fmt.Println(stock)
}

Salida:

./main.go:6:18: cannot use "24" (untyped string constant) as int value in variable declaration

Lee el mensaje por partes:

  • ./main.go:6:18 es el lugar: archivo main.go, línea 6, columna 18, donde empieza "24".
  • cannot use "24" significa “no se puede usar "24"”.
  • (untyped string constant) dice qué es "24" para Go: un string, un texto escrito tal cual en el código. Lo que significan untyped y constant lo verás en la lección Constantes e iota.
  • as int value in variable declaration significa “como valor int en la declaración de una variable”.

Las comillas hacen de "24" un texto, aunque adentro haya un número. Para corregirlo, quita las comillas: var stock int = 24.

Si vienes de JavaScript, Python o Java…

En JavaScript, los números de todos los días son de un solo tipo, number, con decimales o sin ellos. Go separa los enteros (int) de los números con decimales (float64).

En Python, una variable puede cambiar de tipo: después de stock = 24 puedes escribir stock = "veinte". En Go, stock es int para siempre, y el compilador lo revisa antes de ejecutar.

En Java, los tipos se parecen: int, double, String y boolean. El float64 de Go equivale al double de Java. El int de Go ocupa 64 bits en las computadoras actuales, como el long de Java.

Declarar con :=

Hay una forma más corta de declarar una variable:

main.go
package main

import "fmt"

func main() {
	producto := "cuaderno"
	stock := 24
	precio := 2.75
	fmt.Println(producto, stock, precio)
}

Salida:

cuaderno 24 2.75

:= declara una variable nueva y le da un valor en el mismo paso, sin var y sin escribir el tipo: Go lo deduce del valor. producto es un string porque "cuaderno" es un texto, stock es un int porque 24 es un entero, y precio es un float64 porque 2.75 tiene decimales. Igual que con var, el tipo queda fijo.

La última línea imprime las tres variables en una sola línea. Si le pasas a fmt.Println varios valores separados por comas, los imprime en orden, con un espacio entre uno y otro. El resto de lo que sabe hacer fmt lo verás en la lección Salida y entrada con fmt.

:= siempre declara: a su izquierda tiene que haber al menos una variable nueva. Si stock ya existe, Go no te deja declararla otra vez:

main.go
package main

import "fmt"

func main() {
	stock := 24
	fmt.Println(stock)
	stock := 21
	fmt.Println(stock)
}

Salida:

./main.go:8:8: no new variables on left side of :=

Lee el mensaje por partes:

  • ./main.go:8:8 es el lugar: archivo main.go, línea 8, columna 8, donde está el :=.
  • no new variables on left side of := significa “no hay variables nuevas a la izquierda de :=”: stock ya existe desde la línea 6.

Para cambiar el valor de una variable que ya existe, usa =, como en la sección “Cambiar el valor con =”: stock = 21. La regla es := para declarar y = para asignar.

Si vienes de JavaScript, Python o Java…

En JavaScript, declarar dos veces con let stock = 24 en el mismo bloque también es un error. En Python, en cambio, stock = 30 crea la variable o reemplaza su valor, sin distinción. Go separa las dos cosas: := declara y = asigna.

Valores cero

Con var puedes declarar una variable sin darle un valor: escribes el nombre y el tipo, y nada más.

main.go
package main

import "fmt"

func main() {
	var producto string
	var stock int
	var precio float64
	var enOferta bool
	fmt.Println("Producto:", producto)
	fmt.Println("Stock:", stock)
	fmt.Println("Precio:", precio)
	fmt.Println("En oferta:", enOferta)
}

Salida:

Producto:
Stock: 0
Precio: 0
En oferta: false

En Go, una variable siempre tiene un valor. Si no le das uno, Go le pone el valor cero de su tipo:

  • "", el texto vacío, para string. Por eso no aparece nada después de Producto:.
  • 0 para int.
  • 0 para float64. fmt.Println lo imprime sin decimales, pero precio sigue siendo un float64.
  • false para bool.

La regla: una variable declarada sin valor empieza con el valor cero de su tipo. Para eso se usa var: := siempre necesita un valor a la derecha.

Consejo

Dentro de una función, := es la forma habitual de declarar: es más corta y el tipo se deduce del valor. Usa var cuando el valor cero es justo el que quieres, como en un contador de ventas que empieza en cero (var vendidos int), o cuando necesitas un tipo distinto del que Go deduciría: precio := 3 sería un int, y var precio float64 = 3 es un float64.

Si vienes de JavaScript, Python o Java…

En JavaScript, let stock; deja la variable con el valor undefined. En Python, una variable no existe hasta que le asignas un valor. En Java, una variable local sin valor no se puede leer: el programa no compila.

En Go no hay variables sin valor: el valor cero es un valor de verdad, que puedes imprimir y usar.

Toda variable declarada se usa

Supón que declaras el precio del cuaderno, pero te olvidas de imprimirlo:

main.go
package main

import "fmt"

func main() {
	producto := "cuaderno"
	precio := 2.75
	fmt.Println(producto)
}

Salida:

./main.go:7:2: declared and not used: precio

Lee el mensaje por partes:

  • ./main.go:7:2 es el lugar: archivo main.go, línea 7, columna 2, donde empieza precio.
  • declared and not used: precio significa “declarada y no usada: precio”.

Dentro de una función, toda variable que declaras tiene que usarse, o el programa no compila. Usarla es leer su valor, por ejemplo al imprimirla; darle otro valor con = no cuenta.

Es la misma idea que con los imports: una variable que sobra suele ser una señal de que algo falta, como un dato que olvidaste imprimir. Para corregirlo, usa la variable (aquí, fmt.Println(producto, precio)) o borra su declaración.

Descartar valores con _

Algunas funciones devuelven más de un valor; las veremos en la lección Funciones. strings.Cut corta un texto en dos partes, donde aparece un separador, y devuelve tres valores: lo que está antes, lo que está después y un bool que dice si encontró el separador. La papelería lo usa para leer sus pedidos, que llegan como cliente:producto:

main.go
package main

import (
	"fmt"
	"strings"
)

func main() {
	pedido := "Camila:cuaderno rayado"
	cliente, producto, encontrado := strings.Cut(pedido, ":")
	fmt.Println(cliente)
	fmt.Println(producto)
	fmt.Println(encontrado)
}

Salida:

Camila
cuaderno rayado
true

Para recibir varios valores, escribes varias variables a la izquierda de :=, separadas por comas y en el mismo orden en que la función devuelve los valores. Aquí := declara tres variables a la vez: cliente vale Camila, producto vale cuaderno rayado y encontrado vale true, porque el pedido tiene un :.

Si solo te interesa el producto, tienes un problema: hay que recibir los tres valores, pero si dejas cliente y encontrado sin usar, Go responde declared and not used. Para eso existe _:

main.go
package main

import (
	"fmt"
	"strings"
)

func main() {
	pedido := "Camila:cuaderno rayado"
	_, producto, _ := strings.Cut(pedido, ":")
	fmt.Println(producto)
}

Salida:

cuaderno rayado

_ es el identificador vacío (en inglés, blank identifier; un identificador es un nombre, como producto): recibe un valor y lo descarta. Ocupa el lugar de una variable, pero no es una variable: no guarda nada, así que no tienes que usarlo y tampoco puedes leerlo (fmt.Println(_) no compila). Puedes escribirlo todas las veces que haga falta.

La regla: usa _ en el lugar de cada valor que Go te obliga a recibir y que no necesitas.

Si vienes de JavaScript, Python o Java…

En Python, _ es un nombre de variable como cualquier otro: por convención indica que el valor no interesa, pero lo guarda y puedes imprimirlo. En JavaScript, al desarmar un arreglo dejas un hueco: const [, producto] = partes. En Go, _ es parte del lenguaje y no guarda nada.

En resumen

  • Una variable guarda un valor con un nombre. Se declara una sola vez, con var o con :=, y cambia de valor con =.
  • Los tipos básicos son int (enteros), float64 (decimales, con punto), string (texto) y bool (true o false). El tipo de una variable no cambia.
  • Una variable declarada sin valor tiene el valor cero de su tipo: 0, "" o false.
  • Toda variable declarada dentro de una función tiene que usarse, y := necesita a su izquierda al menos una variable nueva.
  • _ descarta un valor que tienes que recibir y no necesitas.

Ejercicios

Debajo de cuaderno, declara con var una variable stock de tipo int con el valor 24, e imprímela: 24.

  main.go

Para salir del editor con el teclado, pulsa Escape y luego Tab.

package main

import "fmt"

func main() {
	var producto string = "cuaderno"
	fmt.Println(producto)
	// Escribe aquí: declara stock con var e imprímela.
}
 

¿Ver la solución?

La solución reemplazará tu código en el editor. Antes de verla, prueba con una pista: se aprende más cuando lo resuelves tú.