Hoja de referencia de Golang
Comandos y construcciones útiles de Go
Aquí tienes la estructura básica de un programa Go, patrones de manejo de errores y comparación entre canales y goroutines.
Cheatsheet del lenguaje Go
Sintaxis básica
Declaración del paquete
package main
Importar paquetes
import "fmt"
import (
"fmt"
"math"
)
Función principal
func main() {
// Tu código aquí
}
Variables y tipos
Declaración de variable
var name string
var age int = 25
x := 10 // Declaración corta
Tipos básicos
- bool
- string
- int, int8, int16, int32, int64
- uint, uint8, uint16, uint32, uint64
- float32, float64
- complex64, complex128
Estructuras de control
Instrucción if
if x > 0 {
// código
} else if x < 0 {
// código
} else {
// código
}
Bucle for
for i := 0; i < 10; i++ {
// código
}
Bucle range
for index, value := range collection {
// código
}
Instrucción switch
switch variable {
case value1:
// código
case value2:
// código
default:
// código
}
Funciones
Declaración de función
func functionName(param1 type1, param2 type2) returnType {
// código
return value
}
Valores de retorno múltiples
func divideAndRemainder(x, y int) (int, int) {
return x / y, x % y
}
Estructuras de datos
Arreglos
var numbers int
numbers := int{1, 2, 3, 4, 5}
Rebanadas (slices)
slice := []int{1, 2, 3}
slice := make([]int, 3, 5)
Mapas
m := make(map[string]int)
m["key"] = value
Estructuras
type Person struct {
Name string
Age int
}
p := Person{Name: "Alice", Age: 30}
Métodos
Declaración de método
func (r Rectangle) Area() float64 {
return r.width * r.height
}
Interfaces
Declaración de interfaz
type Shape interface {
Area() float64
}
Concurrencia
Goroutines
go functionName()
Canales
ch := make(chan int)
ch <- value // Enviar
value := <-ch // Recibir
Manejo de errores
Verificación de errores
if err != nil {
// Manejar el error
}
Defer
defer file.Close()
Pruebas
Función de prueba
func TestFunction(t *testing.T) {
// Código de prueba
}
Este cheat sheet cubre las construcciones y comandos más esenciales del lenguaje Go. Incluye sintaxis básica, estructuras de control, funciones, estructuras de datos, métodos, interfaces, primitivas de concurrencia y manejo de errores. Recuerda que Go enfatiza la simplicidad y la legibilidad, por lo que estas construcciones forman la base para escribir código Go eficiente y claro.
Manejo de errores en Go
El manejo de errores en Go es directo y explícito, enfatizando la claridad y la robustez. Aquí tienes las técnicas clave para manejar errores en Go:
- Devolver errores como valores: Las funciones que pueden fallar deben devolver un error como su último valor de retorno. Por ejemplo:
func Hello(name string) (string, error) {
if name == "" {
return "", errors.New("nombre vacío")
}
message := fmt.Sprintf("Hola, %v. Bienvenido!", name)
return message, nil
}
- Siempre verificar errores: Después de llamar a una función que devuelve un error, verificar inmediatamente si el error no es nulo. Por ejemplo:
result, err := SomeFunction()
if err != nil {
// Manejar el error
log.Fatal(err)
}
- Usar el envoltorio de errores: Al propagar errores hacia arriba en la pila de llamadas, envuélvelos para añadir contexto usando
fmt.Errorf()
con el verbo%w
. Por ejemplo:
f, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("fallo al abrir: %w", err)
}
-
Utilizar
defer
para limpieza: Usadefer
para asegurarte de que los recursos se cierren o limpien correctamente, incluso si ocurre un error. -
Crear tipos de error personalizados: Implementa la interfaz
error
para tipos de error personalizados para proporcionar información de error más detallada. -
Usar el paquete
errors
: Aprovecha funciones comoerrors.New()
para crear mensajes de error simples, yerrors.Is()
oerrors.As()
para comprobación y conversión de tipos de error. -
Evitar el uso de
panic
: Reservapanic
para situaciones verdaderamente irrecoverables. El manejo normal de errores debe usar valores de retorno. -
Proporcionar información de error explícita: Haz que los mensajes de error sean claros e informativos para ayudar en la depuración y solución de problemas.
Siguiendo estas prácticas, puedes crear programas Go robustos que manejen errores de manera efectiva y mantengan la claridad del código.
Mejores prácticas para goroutines y canales en Go
Uso eficiente de goroutines
-
Evitar la creación excesiva de goroutines: Crea goroutines con juicio, considerando la naturaleza de la tarea y si realmente se beneficia de la ejecución paralela.
-
Sincronización adecuada: Usa mecanismos de sincronización como canales o grupos de espera para gestionar eficazmente las goroutines y evitar el desperdicio de recursos.
-
Considerar la naturaleza de la tarea: Evalúa si una tarea realmente se beneficia de la ejecución concurrente antes de usar goroutines.
Uso efectivo de canales
-
Elegir el tipo de canal adecuado: Usa canales no缓冲 para sincronización y canales缓冲 cuando necesites desacoplar las operaciones de envío y recepción.
-
Capacidad del buffer: Cuando uses canales缓冲, considera cuidadosamente el tamaño del buffer para equilibrar el rendimiento y el uso de recursos.
-
Cerrar canales correctamente: Asegúrate de cerrar los canales cuando ya no se enviarán más datos para evitar bloqueos y fugas de recursos.
Patrones de concurrencia
-
Patrón de piscina de trabajadores: Implementa piscinas de trabajadores usando goroutines y canales para una distribución eficiente de tareas y recolección de resultados.
-
Patrón productor-consumidor: Usa goroutines como productores y consumidores, con canales facilitando el flujo de datos entre ellos.
Manejo de errores y gestión de recursos
-
Usar defer para limpieza: Emplea declaraciones
defer
para asegurar una limpieza adecuada de recursos, incluso en presencia de errores. -
Manejar panics: Implementa
recover()
en goroutines de larga duración para evitar que todo el programa se detenga debido a un panic en una sola goroutine.
Comunicación y sincronización
-
Preferir canales sobre memoria compartida: Usa canales para la comunicación entre goroutines para evitar condiciones de carrera y simplificar la sincronización.
-
Usar select para múltiples canales: Emplea la instrucción
select
para manejar operaciones de múltiples canales concurrentemente.
Consideraciones de rendimiento
-
Limitar operaciones concurrentes: Usa semáforos o piscinas de trabajadores para limitar el número de operaciones concurrentes y evitar el agotamiento de recursos.
-
Evitar la optimización prematura: Analiza tu código para identificar cuellos de botella antes de aplicar optimizaciones de concurrencia.
Pruebas y depuración
-
Usar el detector de carreras: Ejecuta regularmente tus pruebas con la bandera
-race
para detectar carreras de datos. -
Escribir pruebas concurrentes: Crea pruebas que ejerzan específicamente tus rutas de código concurrente para asegurar su fiabilidad.
Siguiendo estas mejores prácticas, puedes aprovechar eficazmente el modelo de concurrencia de Go, haciendo que tus programas sean más eficientes, mantenibles y menos propensos a problemas comunes relacionados con la concurrencia.
Ver otros artículos del blog técnico.
Actualizar golang en Linux
- Ve y descarga la nueva versión: https://go.dev/doc/install
- Elimina la antigua:
sudo rm -rf /usr/local/go
- Instala la nueva:
cd Downloads
sudo tar -C /usr/local -xzf go1.24.3.linux-amd64.tar.gz
Enlaces útiles
- https://go.dev/
- Generar PDF en GO - Librerías y ejemplos
- Rendimiento de AWS Lambda: JavaScript vs Python vs Golang
- Corregir error de GORM AutoMigrate en PostgreSQL
- Reinstalar Linux
- Hoja de trucos de Bash
- Hoja de trucos de Markdown
- Decodificar y imprimir token JWT
- Popularidad de lenguajes y frameworks de programación
- Espacio de Golang
- Alternativas a Beautiful Soup para Go