Go: Simplicidad y Rendimiento
Aprende Go, el lenguaje de Google para sistemas escalables y concurrencia
Go: Simplicidad y Rendimiento
Go (o Golang) es un lenguaje de programación creado por Google en 2009. Diseñado por Rob Pike, Ken Thompson y Robert Griesemer, Go combina la eficiencia de los lenguajes compilados con la facilidad de uso de los lenguajes dinámicos. Es especialmente popular para construir servicios web, herramientas de línea de comandos y sistemas distribuidos.
¿Por qué Go? Go es usado por empresas como Google, Uber, Dropbox, Docker y Kubernetes. Su simplicidad y excelente soporte para concurrencia lo hacen ideal para microservicios y sistemas cloud-native.
Características Distintivas
- Compilación Rápida - Compila proyectos grandes en segundos
- Garbage Collection - Gestión automática de memoria eficiente
- Concurrencia Nativa - Goroutines y channels facilitan la programación paralela
- Tipado Estático - Con inferencia de tipos para código conciso
- Herramientas Integradas - Formateo, tests y build nativos
- Binario Único - Compila a un único ejecutable sin dependencias
Fundamentos
Tipos de Datos y Variables
package main
import "fmt"
func main() {
// Declaración explícita
var nombre string = "María"
var edad int = 25
var altura float64 = 1.68
var activo bool = true
// Declaración corta (inferencia de tipo)
email := "[email protected]"
contador := 0
// Constantes
const pi = 3.14159
const (
EstadoPendiente = iota // 0
EstadoAprobado // 1
EstadoRechazado // 2
)
// Arrays (tamaño fijo)
var numeros [5]int = [5]int{1, 2, 3, 4, 5}
// Slices (tamaño dinámico)
frutas := []string{"manzana", "banana", "naranja"}
frutas = append(frutas, "uva")
// Maps
usuarios := map[string]int{
"alice": 25,
"bob": 30,
}
usuarios["carol"] = 28
fmt.Println(nombre, edad, altura, activo, email)
fmt.Println(numeros, frutas, usuarios)
}
Estructuras de Control
package main
import "fmt"
func main() {
// If/else
edad := 18
if edad >= 18 {
fmt.Println("Mayor de edad")
} else if edad >= 13 {
fmt.Println("Adolescente")
} else {
fmt.Println("Niño")
}
// If con declaración inicial
if valor := obtenerValor(); valor > 0 {
fmt.Println("Valor positivo:", valor)
}
// For (único bucle en Go)
for i := 0; i < 5; i++ {
fmt.Println(i)
}
// For range
frutas := []string{"manzana", "banana", "naranja"}
for indice, fruta := range frutas {
fmt.Printf("%d: %s\n", indice, fruta)
}
// Switch
dia := "lunes"
switch dia {
case "lunes", "martes", "miércoles", "jueves", "viernes":
fmt.Println("Día laborable")
case "sábado", "domingo":
fmt.Println("Fin de semana")
default:
fmt.Println("Día inválido")
}
}
func obtenerValor() int {
return 42
}
Funciones
package main
import (
"errors"
"fmt"
)
// Función simple
func saludar(nombre string) string {
return fmt.Sprintf("¡Hola, %s!", nombre)
}
// Múltiples retornos
func dividir(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("división por cero")
}
return a / b, nil
}
// Retornos nombrados
func calcular(a, b int) (suma, producto int) {
suma = a + b
producto = a * b
return // retorno implícito
}
// Variadic function
func sumar(numeros ...int) int {
total := 0
for _, n := range numeros {
total += n
}
return total
}
// Closure
func contador() func() int {
count := 0
return func() int {
count++
return count
}
}
func main() {
fmt.Println(saludar("María"))
resultado, err := dividir(10, 2)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Resultado:", resultado)
}
fmt.Println(sumar(1, 2, 3, 4, 5))
cont := contador()
fmt.Println(cont(), cont(), cont())
}
Structs y Métodos
package main
import "fmt"
// Struct
type Usuario struct {
ID int
Nombre string
Email string
Activo bool
}
// Método (receptor por valor)
func (u Usuario) Saludar() string {
return fmt.Sprintf("¡Hola, %s!", u.Nombre)
}
// Método (receptor por puntero - puede modificar)
func (u *Usuario) Desactivar() {
u.Activo = false
}
// Constructor (convención)
func NuevoUsuario(id int, nombre, email string) *Usuario {
return &Usuario{
ID: id,
Nombre: nombre,
Email: email,
Activo: true,
}
}
func main() {
u1 := Usuario{ID: 1, Nombre: "María", Email: "[email protected]", Activo: true}
u2 := NuevoUsuario(2, "Juan", "[email protected]")
fmt.Println(u1.Saludar())
fmt.Println(u2.Saludar())
u2.Desactivar()
fmt.Println("Juan activo:", u2.Activo)
}
Concurrencia
package main
import (
"fmt"
"sync"
"time"
)
// Goroutine básica
func tarea(id int) {
for i := 0; i < 3; i++ {
fmt.Printf("Tarea %d: iteración %d\n", id, i)
time.Sleep(100 * time.Millisecond)
}
}
// Channels
func productor(ch chan<- int) {
for i := 0; i < 5; i++ {
ch <- i
time.Sleep(100 * time.Millisecond)
}
close(ch)
}
func consumidor(ch <-chan int) {
for valor := range ch {
fmt.Println("Recibido:", valor)
}
}
// WaitGroup
func conWaitGroup() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Printf("Worker %d ejecutando\n", id)
time.Sleep(time.Second)
}(i)
}
wg.Wait()
fmt.Println("Todos los workers finalizaron")
}
func main() {
// Goroutines
go tarea(1)
go tarea(2)
time.Sleep(500 * time.Millisecond)
// Channels
ch := make(chan int)
go productor(ch)
consumidor(ch)
// WaitGroup
conWaitGroup()
}
Herramientas Esenciales
| Comando | Propósito |
|---|---|
go build | Compila el proyecto |
go run | Compila y ejecuta |
go test | Ejecuta tests |
go fmt | Formatea código |
go mod init | Inicializa módulo |
go get | Añade dependencia |
Lista de Verificación de Aprendizaje
- Dominar tipos básicos y estructuras de datos
- Entender funciones, métodos e interfaces
- Aprender goroutines y channels
- Estudiar patrones de concurrencia
- Practicar con APIs REST
- Explorar testing nativo
- Construir un microservicio
Recursos Esenciales
Cita
“Go está diseñado para personas que escriben y mantienen sistemas de software grandes.” - Rob Pike
¡Go es la elección perfecta cuando necesitas rendimiento, simplicidad y excelente soporte para concurrencia!