Lección 1 · Primeros pasos
Qué es Go y tu primer programa
Al terminar esta lección vas a poder escribir un programa completo en Go, entender para qué sirve cada una de sus líneas y usar funciones de otros paquetes. También vas a saber leer dos errores que el compilador muestra a menudo: un paquete importado que no se usa y un nombre escrito con minúscula.
Qué es Go
Go es un lenguaje de programación: una forma de escribir instrucciones que una computadora puede ejecutar. Es de código abierto (cualquiera puede leer y usar su código), nació en Google y se publicó en 2009. Hoy se usa mucho para programas que corren en servidores de internet y para herramientas que se usan desde la terminal.
Tres características lo definen, y las vas a notar desde el primer programa:
- Es compilado. Antes de ejecutar tu programa, otro programa, el compilador, lo lee completo y lo traduce a instrucciones que la computadora ejecuta directamente. Si encuentra un error, se detiene y no se ejecuta ninguna línea.
- Tiene tipado estático. Cada valor tiene un tipo: por ejemplo, un texto, un número entero o un número con decimales. Antes de ejecutar, el compilador revisa que cada valor se use como su tipo lo permite: no te deja multiplicar un texto por un número. Los tipos los verás en la lección Variables y valores cero.
- Tiene recolector de basura (en inglés, garbage collector). Mientras corre, tu programa usa memoria para guardar sus datos. Cuando un dato ya no se usa, Go libera esa memoria por su cuenta: no tienes que escribir nada para eso.
En este curso, el compilador oficial de Go corre dentro de tu navegador. En los ejercicios, el botón Ejecutar primero compila tu programa y, si no hay errores, lo ejecuta.
Si vienes de JavaScript, Python o Java…
En Python y JavaScript no compilas el programa antes de ejecutarlo: un error de tipos aparece solo cuando se ejecuta la línea que lo tiene. En Go, el compilador lo encuentra antes de que se ejecute cualquier línea.
Java también compila, pero a un código intermedio (bytecode) que necesita la máquina virtual de Java para correr. Go compila a código de máquina: un archivo ejecutable que corre sin tener Go instalado. En este sitio, como el compilador corre en el navegador, compila a WebAssembly, un formato que el navegador sabe ejecutar.
La memoria, en cambio, funciona como en los tres: la libera un recolector de basura.
Tu primer programa
Este es un programa completo en Go. Como manda la tradición, el primero saluda al mundo:
package main
import "fmt"
func main() {
fmt.Println("¡Hola, mundo!")
}Salida:
¡Hola, mundo!
Debajo del código ves la salida: lo que el programa imprimió al ejecutarse. En programación,
imprimir es mostrar texto en la salida, no en papel. Lo impreso es exactamente el texto
que está entre las comillas dobles, ¡Hola, mundo!, sin las comillas. Un texto entre comillas dobles es
un string (un valor de texto): Go lo usa tal cual, con sus tildes, signos y espacios.
fmt.Println muestra en la salida lo que le pasas entre los paréntesis, en una línea. Lo veremos en la
lección Salida y entrada con fmt.
Las otras líneas no imprimen nada, pero todo programa en Go las necesita. Las vas a ver una por una en las secciones que siguen:
package maindice que este archivo es un programa.import "fmt"trae el paquetefmt, que es donde estáPrintln. Un paquete es un grupo de código con nombre.func main()y sus llaves encierran lo que hace el programa.
package main y func main
Un programa puede imprimir tantas líneas como quieras. Este imprime el cartel de una papelería:
package main
import "fmt"
// main es donde empieza el programa.
func main() {
fmt.Println("Papelería Central")
fmt.Println("Abierto de lunes a sábado")
fmt.Println("¡Te esperamos!")
}Salida:
Papelería Central Abierto de lunes a sábado ¡Te esperamos!
Las tres líneas salen en el mismo orden en que están escritas. Así funciona main: cuando ejecutas el
programa, Go ejecuta las instrucciones de func main una por una, de arriba abajo. Al llegar a la llave
de cierre, el programa termina.
Cada parte tiene su función:
package mainva al principio del archivo. Todo archivo de Go pertenece a un paquete, y el paquetemaines el que se puede ejecutar como programa.func main()declara la funciónmain. Una función es un bloque de código con nombre, ymaines especial: es la que Go ejecuta al iniciar el programa. Sus instrucciones van entre las llaves{y}. Cómo escribir tus propias funciones lo verás en la lección Funciones.- La línea que empieza con
//es un comentario: una nota para quien lee el código, que Go ignora. Los ejercicios usan comentarios para marcar dónde escribir.
La regla: un programa en Go necesita package main y una func main, y lo que pones dentro de main
se ejecuta en orden.
La llave { va al final de la línea de func main(), como en los ejemplos. No es cuestión de gusto: si
la pasas a la línea siguiente, el programa no compila.
Consejo
Escribe tu código con la forma de los ejemplos: sangría con tabulador y una instrucción por línea. Es
el formato oficial de Go, el que deja la herramienta gofmt, y cualquier persona que programa en Go lo
lee sin esfuerzo.
Paquetes e imports
Un paquete agrupa código relacionado. Go trae una biblioteca estándar con muchos paquetes listos
para usar. fmt es uno; strings, con funciones para trabajar con textos, es otro:
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println("papelería central")
fmt.Println(strings.ToUpper("papelería central"))
}Salida:
papelería central PAPELERÍA CENTRAL
Usar una función se dice llamarla: escribes su nombre y, entre paréntesis, lo que le pasas.
strings.ToUpper recibe un texto y devuelve el mismo texto en mayúsculas, tildes incluidas:
papelería central pasa a ser PAPELERÍA CENTRAL. Como esa llamada está dentro de los paréntesis de
fmt.Println, Go primero obtiene el texto en mayúsculas y después fmt.Println lo imprime.
Para usar un paquete, lo importas con import y su nombre entre comillas dobles. Si son dos o más, lo
habitual es agruparlos entre paréntesis, uno por línea. Después usas lo que trae con el nombre del paquete, un punto y
el nombre de lo que necesitas: strings.ToUpper.
Si importas un paquete y no lo usas, el programa no compila. Aquí sobra strings:
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println("papelería central")
}Salida:
./main.go:5:2: "strings" imported and not used
Lee el mensaje por partes:
./main.go:5:2es el lugar: archivomain.go, línea 5, columna 2. En la línea 5 está"strings", y el tabulador de la sangría cuenta como la columna 1."strings" imported and not useddice el problema: importastestringsy no lo usas.
Para corregirlo, usa el paquete o borra su línea del import. Go es estricto con esto a propósito: un
import que sobra hace más lenta la compilación y confunde a quien lee el código.
Consejo
Agrupa todos los imports en un solo bloque entre paréntesis. El orden no cambia nada para el
compilador; por convención van en orden alfabético, que es como los deja gofmt.
Si vienes de JavaScript, Python o Java…
En Python, JavaScript y Java, un import que no usas es como mucho una advertencia del editor. En Go es un error: el programa no compila hasta que lo usas o lo borras.
Nombres exportados
Fíjate en cómo se escriben los nombres que usas de otros paquetes:
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Repeat("=", 17))
fmt.Println(strings.ToUpper("papelería central"))
fmt.Println(strings.Repeat("=", 17))
}Salida:
================= PAPELERÍA CENTRAL =================
strings.Repeat recibe un texto y un número, y devuelve el texto repetido esa cantidad de veces:
strings.Repeat("=", 17) da diecisiete signos =, el mismo ancho que PAPELERÍA CENTRAL.
Println, ToUpper y Repeat empiezan con mayúscula, y no es casualidad. En Go, un nombre que empieza
con mayúscula está exportado: se puede usar desde otros paquetes. Un nombre que empieza con
minúscula solo se puede usar dentro de su propio paquete.
main va con minúscula porque Go exige ese nombre exacto. Tampoco necesita estar exportada: ningún otro
paquete la usa, Go la ejecuta por su cuenta.
Si escribes println con minúscula, el programa no compila:
package main
import "fmt"
func main() {
fmt.Println("Papelería Central")
fmt.println("Abierto de lunes a sábado")
}Salida:
./main.go:7:6: undefined: fmt.println (but have Println)
Lee el mensaje por partes:
./main.go:7:6: archivomain.go, línea 7, columna 6, justo donde empiezaprintln.undefined: fmt.printlnsignifica “no definido”: Go no encuentra ningúnprintlnentre los nombres que exportafmt.(but have Println)significa “pero tienePrintln”: Go te sugiere el nombre que sí existe.
Fíjate en que la salida no muestra Papelería Central, aunque esa línea estaba bien. Es lo que viste
al principio: Go es compilado, y con un error en cualquier línea no se ejecuta ninguna.
Para corregirlo, escribe fmt.Println. Go distingue mayúsculas de minúsculas en todos los nombres:
println, Println y PrintLn son tres nombres distintos.
Tampoco sirve borrar el fmt.: println, sin fmt., es otra función. Viene integrada en Go para casos
especiales y escribe en otro lugar, la salida de errores, que los ejercicios no revisan.
Consejo
Si no recuerdas cómo se escribe un nombre, búscalo en la documentación oficial de su paquete, por ejemplo pkg.go.dev/strings. Ahí aparece todo lo que el paquete exporta, con sus mayúsculas exactas.
Si vienes de JavaScript, Python o Java…
En Java decides quién puede usar un nombre con public o private. En Go no hay palabras para esto:
decide la primera letra, y el compilador lo hace cumplir. Un nombre con minúscula se parece más a la
visibilidad de paquete de Java (sin modificador) que a private: lo usa todo el código de su paquete.
En JavaScript, un módulo comparte solo lo que marcas con export. En Python, un guion bajo al inicio
(_precio) avisa que algo es interno, pero nada impide usarlo.
En resumen
- Go es compilado y tiene tipado estático: el compilador revisa el programa completo antes de ejecutar una sola línea. La memoria la libera el recolector de basura.
- Todo programa empieza con
package main, y lo que escribes enfunc mainse ejecuta en orden, de arriba abajo. - Para usar un paquete, lo importas con
import. Cada import tiene que usarse. - De otro paquete solo puedes usar los nombres que empiezan con mayúscula: los exportados.
- Un error del compilador se lee por partes: primero el lugar (
archivo:línea:columna) y después qué pasó.
Ejercicios
Debajo de Papelería Central, imprime Cuadernos, lápices y más en otra línea.
Para salir del editor con el teclado, pulsa Escape y luego Tab.
package main
import "fmt"
func main() {
fmt.Println("Papelería Central")
// Escribe aquí la segunda línea.
}