Las herramientas básicas de Go: go fmt, go vet, go build, go run y go install
Introducción
Cuando empezás a trabajar con Go, te encontrás con un ecosistema de comandos que forman parte del propio toolchain del lenguaje. Estos comandos no son solo utilidades opcionales; son la columna vertebral que te permite escribir código limpio, detectar errores temprano, compilar tus programas y distribuirlos de forma sencilla. En este artículo vas a aprender qué hace cada uno de los cinco comandos más usados: go fmt, go vet, go build, go run y go install. Para cada uno verás su propósito, cómo invocarlo en la terminal y ejemplos concretos con la salida esperada. Al final tendrás un cuadro de referencia que podés aplicar inmediatamente en tus proyectos.
Este tutorial está pensado para desarrolladores que ya saben escribir un programa sencillo en Go (por ejemplo, un main que imprima algo) pero que aún no han explorado a fondo el toolchain. Si venís de otros lenguajes y buscás comprender por qué Go se siente tan "listo para usar", aquí encontrarás la respuesta.
go fmt: el formateador oficial
Qué hace
go fmt aplica el estilo de formato estándar de Go a todos los archivos .go de un paquete o de un árbol de directorios. El formato que impone es el mismo que usarías si ejecutaras gofmt -w. Al usar go fmt te asegurás de que todo el código siga las mismas reglas de sangrado, alineación y uso de espacios, lo que evita discusiones estilísticas en revisiones de código y hace que los diffs sean más limpios.
Cómo usarlo
El comando se ejecuta desde la raíz de tu módulo o desde cualquier subdirectorio. La sintaxis más común es:
$ go fmt ./...El ./... le indica a Go que procese el paquete actual y todos sus subpaquetes de forma recursiva. Si solo querés formatear un paquete específico, podés usar su ruta de importación relativa o absoluta.
Ejemplo práctico
Creemos un pequeño archivo llamado saludar.go con un formato intencionalmente desordenado:
package main
import ( "fmt" )
func main(){
fmt .Println("Hola, mundo!" )
}Si lo guardamos así y ejecutamos go fmt saludar.go, el comando reescribe el archivo aplicando el estilo correcto. Veamos la terminal:
$ go fmt saludar.go
$ cat saludar.goSalida esperada después del cat:
package main
import "fmt"
func main() {
fmt.Println("Hola, mundo!
i
}Observá cómo se agregó la tabulación después de func main() {, se cerró correctamente la llamada a Println y se eliminaron los espacios extra. Si el archivo ya estaba bien formateado, go fmt no produce ninguna salida y no modifica nada.
Buenas prácticas con go fmt
- Ejecutá
go fmtantes de cada commit. Muchos equipos lo integran en hooks de pre‑commit para que el repositorio nunca tenga código mal formateado. - No le tengas miedo a que cambie tu estilo personal: el formato de Go es deliberadamente minimalista y está probado en millones de líneas de código.
- Si trabajás en un equipo grande, considerar usar
gofmt -sademás dego fmtpara simplificaciones adicionales (como eliminar paréntesis innecesarios).
go vet: el analizador estático
Qué hace
go vet examina el código fuente en busca de errores sutiles que el compilador no detecta, pero que pueden provocar comportamientos inesperados en tiempo de ejecución. Entre los cheques más comunes están: llamadas a funciones con argumentos de tipo incorrecto, uso de fmt.Printf con verbos de formato que no coinciden con los argumentos, construcciones de nil en interfaces, y posibles condiciones de carrera en ciertas operaciones de canal.
Cómo usarlo
Al igual que go fmt, se ejecuta sobre paquetes:
$ go vet ./...Si go vet encuentra algo, imprime una descripción del problema junto con la ubicación (archivo y línea). Si no hay nada, no muestra salida.
Ejemplo práctico
Vamos a crear un archivo llamado errores.go que contenga dos problemas típicos que go vet detecta:
package main
import "fmt"
func main() {
// Error 1: verbo de formato incorrecto
fmt.Printf("El número es %d
", "cinco" )
// Error 2: conversión innecesaria que genera un warning
var x int = 10
_ = float64(x) // esto está bien, pero veamos otro
var y interface{} = nil
fmt.Println(y.(string)) // panic en tiempo de ejecución si se ejecuta
}Ejecutemos go vet:
$ go vet errores.goSalida esperada:
# command-line-arguments
./errores.go:6:13: invalid argument: cannot use "cinco" (type string) as type int in argument to fmt.Printf
./errores.go:12:22: impossible type assertion:
y.(string) cannot fail (it always panics)El primer mensaje indica que le pasamos una cadena donde se esperaba un entero para el verbo %d. El segundo avisa de que la aserción de tipo y.(string) siempre fallará porque y es nil y su tipo subyacente no es string.
Buenas prácticas con go vet
- Corre
go vetcomo parte de tu pipeline de CI. Es barato y atrapa muchos errores antes de que lleguen a producción. - Si ves un
vetque considerás un falso positivo, podés usar la directiva//nolintpara suprimirlo en esa línea, pero hacételo sólo cuando estés seguro. - Combiná
go vetcongolangci-lintsi querés unificante.
go build: compilando tus programas
Qué hace
go build toma los archivos fuente de un paquete y produce un binario ejecutable (o una biblioteca, si el paquete no tiene main). A diferencia de algunos lenguajes que requieren un paso de enlace separado, Go hace todo en una sola invocación: compila cada archivo, genera el código de objeto y lo enlaza en un ejecutable independiente que no necesita dependencias externas excepto la libc del sistema.
Cómo usarlo
Para compilar un programa sencillo y dejar el ejecutable en el directorio actual:
$ go build -o miprogramaEl flag -o especifica el nombre del archivo de salida; si lo omitís, Go usa el nombre del directorio o del archivo main.go.
Ejemplo práctico
Tomemos nuestro programa saludar.go (ya formateado) y lo compilamos:
$ go build -o saludar saludar.go
$ ./saludarSalida esperada:
Hola, mundo!Si queremos compilar para otro sistema operativo o arquitectura sin cambiar de máquina, usamos las variables de entorno GOOS y GOARCH:
$ GOOS=windows GOARCH=amd64 go build -o saludar.exe saludar.goEsto producirá un ejecutable de Windows llamado saludar.exe mientras seguimos en Linux.
Buenas prácticas con go build
Siempre especificá
-ocuando el nombre por defecto no sea claro, especialmente en scripts de CI.Usá la bandera
-ldflagspara embeddear información de versión o Git commit en el binario:$ go build -ldflags "-X main.version=v1.2.3" -o miappEn proyectos grandes, considerar el uso de
go build ./...para compilar todos los paquetes y asegurarse de que no haya errores de dependencia faltante.
go run: compilar y ejecutar al vuelo
Qué hace
go run combina los pasos de compilación y ejecución en un solo comando. Compila el paquete temporalmente, crea un ejecutable en un directorio temporal y lo lanza inmediatamente. Es ideal para pruebas rápidas, ejemplos y scripts donde no querés lidiar con la gestión de binarios.
Cómo usarlo
La forma más simple es:
$ go run archivo.goSi tu programa consta de varios archivos, podés pasarlos todos o usar ./... para incluir todo el paquete:
$ go run .
$ go run ./...Ejemplo práctico
Volvamos a saludar.go y ejecutémoslo con go run:
$ go run saludar.goSalida esperada:
Hola, mundo!Probemos ahora un programa que recibe argumentos de línea de comandos:
package main
import (
"fmt"
"os"
)
func main() {
if len(os.Args) < 2 {
fmt.Println("Uso: go run saludo.go <nombre>
os.Exit(1)
}
fmt.Printf("Hola, %s!
", os.Args[1])
}Guardémoslo como saludo.go y ejecutémoslo:
$ go run saludo.go LucíaSalida esperada:
Hola, Lucía!Buenas prácticas con go run
No lo uses en producción: el overhead de compilar cada vez puede ser significativo y no deja un binario reproducible.
Ideal para ejemplos en documentación, talleres o cuando estás aprendiendo nuevas APIs del estándar.
Si necesitás pasar variables de entorno al programa, simplemente hacelo como con cualquier otro ejecutable:
$ VAR=valor go run programa.go
go install: instalar binarios en tu espacio de trabajo
Qué hace
go install compila un paquete y coloca el binario resultante en el directorio $GOPATH/bin (o $HOME/go/bin si usás módulos con GO111MODULE=on). Es la forma recomendada de instalar herramientas de línea de comandos escritas en Go, como golangci-lint, delve o tus propios utilitarios.
Cómo usarlo
Desde el directorio del módulo que contiene un main paquetes, ejecutá:
$ go install ./...Esto instalará todos los ejecutables encontrados. Si querés instalar solo uno, podés especificar su ruta de importación:
$ go install ejemplo.com/mimodulo/cmd/miherramienta@latestEjemplo práctico
Supongamos que tenemos un pequeño programa llamado saludar.go dentro de un módulo ejemplo.com/saludador. La estructura es:
saludador/
├── go.mod
└── cmd/
└── saludar/
└── main.goEl main.go contiene:
package main
import "fmt"
func main() {
fmt.Println("¡Saludos desde la herramienta instalada!
)
}Desde la raíz del módulo ejecutamos:
$ go install ./cmd/saludarDespués de que termine, el binario quedará en $HOME/go/bin/saludar (asumiendo que $GOBIN no está definido). Podemos verificarlo:
$ $HOME/go/bin/saludarSalida esperada:
¡Saludos desde la herramienta instalada!Si más tarde querés actualizarlo a una nueva versión del código, simplemente volvé a ejecutar go install y se reemplazará el binario.
Buenas prácticas con go install
- Mantené tu
$GOPATH/bin(o$HOME/go/bin) en tu$PATHpara poder llamar a las herramientas directamente desde cualquier terminal. - Usá versiones semánticas en tus módulos y, al instalar en CI, especificá la versión con
@v1.2.3para asegurar reproducibilidad. - Si desarrollás una herramienta que será usada por otros, considerar incluir un
Makefileo un script que invoquego installcomo paso de liberación.
Buenas prácticas generales y errores comunes
Buenas prácticas
- Formateá antes de revisar: ejecutá
go fmten tu editor al guardar o mediante un pre‑commit hook. Así evitás ruido en los diffs. - Analizá estáticamente: integrá
go veten tu pipeline de CI; es rápido y evita que errores sutiles lleguen a master. - Compilá con bandera de liberación: en producción usá
go build -ldflags="-s -w"para eliminar información de depuración y reducir el tamaño del binario. - Versioná tus binarios: al instalar herramientas, usar
go install ruta@versiongarantiza que todos los miembros del equipo tengan la misma versión. - Separá comandos de desarrollo y de liberación:
go runpara iterar rápido,go buildpara generar artefactos, ygo installpara colocar herramientas en tu$PATH.
Errores comunes
- Olvidar
./...: si ejecutásgo fmtogo vetsolo sobre un archivo específico, podés pasar por alto problemas en otros paquetes del mismo módulo. - Confundir
go buildcongo runen scripts de CI: usargo rundeja binarios temporales que pueden borrarse antes de que termine el job, provocando fallos difíciles de reproducir. - Ignorar la salida de
go vet: algunos desarrolladores la consideran solo "advertencias" y la ignoran, perdiéndose riesgos como format strings incorrectos. - Instalar sin establecer
$GOBIN: si la variable no está definida, el binario va a$HOME/go/bin. Si ese directorio no está en tu$PATH, no podrás llamar al comando directamente y pensarás que la instalación falló. - Usar
go installen modo módulo singo.modpresente: si estás fuera de un módulo, el comando puede intentar instalar en el modo GOPATH tradicional y generar confusión.
Conclusión
Los cinco comandos que vimos hoy conforman el núcleo del flujo de trabajo en Go. go fmt te brinda un estilo uniforme sin discusiones; go vet te avisa de problemas que el compilador no ve; go build produce binarios portátiles y eficientes; go run te permite probar al instante; y go install pone tus herramientas al alcance de la mano. Al incorporarlos de manera consciente en tu rutina — formateando antes de commit, vetando en CI, construyendo con flags de liberación y instalando lo que necesitás — estarás aprovechando al máximo la filosofía de Go: simplicidad, velocidad y confiabilidad.
Te animo a que probés cada comando con los ejemplos de este artículo, los adaptes a tus propios proyectos y los integréis en tus scripts de build y en tus hooks de Git. Con esa base, estarás listo para afrontar desafíos más complejos, como cross‑compilación, generación de módulos públicos o creación de herramientas de línea de comandos que otros desarrolladores instalarán con un solo go install. ¡Éxitos en tu camino con Go!
DUGLAS MORENO
Comentarios (0)
Sé el primero en comentar.