¿Por qué Go parece fácil pero rompe a los principiantes?
\n\nGo (o Golang) es un lenguaje que fue creado con un solo objetivo: que los programadores sufran menos. Sintaxis minimalista, concurrencia incorporada, compilación rápida: parece que se puede aprender en una semana. Y sí, se puede aprender. Pero «escribir buen código» y «escribir código en Go» son dos historias diferentes.
\n\nLos principiantes a menudo traen hábitos de Python, JavaScript o Java e intentan aplicarlos a Go. El resultado son errores difíciles de detectar, pánico en tiempo de ejecución y la sensación de que «Go está roto». Spoiler: Go no está roto. Simplemente piensa de manera diferente.
\n\nEn este artículo analizaremos los 5 errores más comunes al aprender Go. Si estás empezando, léelo con atención. Si ya escribes en Go, comprueba si todavía los cometes.
\n\nError n.º 1: Ignorar errores (y el hábito de Python)
\n\nEn Python o JavaScript estás acostumbrado a que una función pueda devolver un resultado o lanzar una excepción. Envuelves la llamada en un try/catch y vives tranquilo. En Go es diferente: no hay excepciones. Solo hay valores de retorno, y uno de ellos es el error.
\n\nEl error más común de los principiantes es escribir result, _ := someFunc() y olvidarse del error. O, peor aún, simplemente no verificarlo:
// MAL: el error se ignora\nfile, _ := os.Open("config.yaml")\n// Si el archivo no existe — file == nil, y la siguiente línea fallará con pánico\ndefer file.Close()\n\n\nEn Go, el error no es algo terrible. Es solo un valor. Hay que verificarlo. Siempre. Sin excepciones.
\n\n¿Cómo hacerlo bien?
\n\n// BIEN: verificamos el error inmediatamente\nfile, err := os.Open("config.yaml")\nif err != nil {\n log.Fatalf("no se pudo abrir el archivo: %v", err)\n}\ndefer file.Close()\n\n\nEsto no es paranoia. Es disciplina. Go te enseña a ser cuidadoso. Si ignoras un error en producción, prepárate para que a las 3 de la mañana el servicio se caiga y los registros estén en silencio.
\n\nConsejo: nunca uses _ para el error, a menos que estés 100% seguro de que nunca ocurrirá. Y esas situaciones en código real casi no existen.
Error n.º 2: Pánico donde se necesita un error
\n\nEn Go existe el mecanismo panic y recover. Los principiantes a menudo los confunden con excepciones y empiezan a lanzar pánico ante cualquier problema. Esto es un error.
panic es una detención de emergencia del programa. Está diseñado para situaciones en las que continuar la ejecución es imposible: por ejemplo, desreferenciar un puntero nulo o salir de los límites de un array. Usar panic para manejar la lógica de negocio es de mal gusto.
// MAL: pánico en lugar de error\nfunc divide(a, b int) int {\n if b == 0 {\n panic("¡división por cero!")\n }\n return a / b\n}\n\n\nEl enfoque correcto es devolver un error:
\n\n// BIEN: devolvemos un error\nfunc divide(a, b int) (int, error) {\n if b == 0 {\n return 0, fmt.Errorf("división por cero")\n }\n return a / b, nil\n}\n\n\nUsa panic solo para situaciones realmente críticas. Todo lo demás son errores. Go te da error por una razón.
Error n.º 3: Mal manejo de gorutinas y falta de sincronización
\n\nLas gorutinas son, quizás, la característica más genial de Go. Pero también es la más peligrosa para los principiantes. Escena típica: lanzas 1000 gorutinas, escribes en una variable compartida y obtienes una condición de carrera (data race).
\n\n// MAL: condición de carrera\nvar counter int\nfor i := 0; i < 1000; i++ {\n go func() {\n counter++ // ¡inseguro!\n }()\n}\ntime.Sleep(time.Second)\nfmt.Println(counter) // resultado impredecible\n\n\n¿Por qué es un problema? Porque counter++ no es una operación atómica. Consiste en leer, incrementar y escribir. Dos gorutinas pueden leer el mismo valor, incrementarlo