Skip to main content

Command Palette

Search for a command to run...

Tipos y Structs en Go: Tu Primera Inmersión en el Lenguaje

Updated
5 min read

Si vienes de Java como yo, probablemente estés acostumbrado a pensar en términos de clases, herencia y objetos. Go tiene un enfoque diferente pero igualmente poderoso. En este post, exploraremos cómo Go maneja los tipos de datos estructurados a través de structs y por qué este enfoque puede ser más simple y flexible de lo que imaginas.

¿Qué son los Structs?

En Go, un struct es similar a una clase en Java, pero con algunas diferencias fundamentales:

  • No hay herencia: Go no soporta herencia de clases como Java
  • Composición sobre herencia: En lugar de extender clases, Go promueve la composición mediante embedding
  • Más simple: Menos ceremonia, más código directo

Veamos un ejemplo básico:

type Person struct {
    // Campos públicos (empiezan con mayúscula) - similar a public en Java
    Name string
    Age  int

    // Campos privados (empiezan con minúscula) - similar a private en Java
    email string

    // Puedes agregar tags para serialización, validación, etc.
    // Similar a anotaciones en Java (@JsonProperty, etc.)
    BirthDate time.Time `json:"birth_date" validate:"required"`
}

Visibilidad: Mayúsculas vs Minúsculas

En Go, la visibilidad se controla con la primera letra:

  • Mayúscula = público (como public en Java)
  • Minúscula = privado (como private en Java)

No necesitas palabras clave como public o private. El lenguaje lo determina automáticamente.

Tags: Las Anotaciones de Go

Los tags en Go son similares a las anotaciones en Java (@JsonProperty, @Valid, etc.). Te permiten agregar metadata a los campos:

BirthDate time.Time `json:"birth_date" validate:"required"`

Constructores Idiomáticos

En Go, no hay constructores automáticos como en Java. En su lugar, se usa una convención: funciones que empiezan con New:

func NewPerson(name string, age int, email string) *Person {
    return &Person{
       Name:      name,
       Age:       age,
       email:     email,
       BirthDate: time.Now(),
    }
}

Nota el uso del operador & que retorna un puntero. En Go, es común trabajar con punteros para evitar copias innecesarias de estructuras grandes.

Composición vs Herencia: Struct Embedding

Aquí está una de las diferencias más importantes con Java. En lugar de usar herencia (extends), Go usa embedding o composición:

type Employee struct {
    Person              // Campos de Person están directamente accesibles
    Address             // Campos de Address también
    EmployeeID string
    Salary    float64
    Department string
}

Cuando embebes un struct, todos sus campos y métodos están disponibles directamente:

employee := NewEmployee("Jane Smith", 28, "jane@example.com", "EMP001", 75000.0)
employee.Street = "123 Main St"
employee.City = "San Francisco"
employee.Country = "USA"
fmt.Printf("Employee: %s\n", employee.Name) // Acceso directo a campos embebidos
fmt.Printf("Address: %s\n", employee.GetFullAddress())
fmt.Println()

Esto es más flexible que la herencia porque puedes cambiar la composición sin romper la jerarquía de clases.

Métodos y Receptores

En Go, puedes agregar métodos a cualquier tipo (no solo structs). Los métodos usan receptores:

// GetEmail es un método getter (similar a getEmail() en Java)
// El receptor (receiver) es (p Person) - esto es value receiver
func (p Person) GetEmail() string {
    return p.email
}

// Pointer receiver - recibe una referencia

// SetEmail es un método setter con pointer receiver
// Usa *Person para modificar el struct original
func (p *Person) SetEmail(email string) {
    p.email = email
}

¿Cuándo usar cada uno?

  • Value receiver: Cuando el método solo lee datos o el struct es pequeño
  • Pointer receiver: Cuando necesitas modificar el struct o es grande (evita copias costosas)

Comparación de Structs

A diferencia de Java donde necesitas implementar equals(), en Go la comparación es automática si todos los campos son comparables:

p1 := Person{Name: "John", Age: 30}
p2 := Person{Name: "John", Age: 30}
p3 := Person{Name: "Jane", Age: 25}

fmt.Println("p1 == p2:", p1 == p2) // true
fmt.Println("p1 == p3:", p1 == p3) // false

Structs Anónimos

Go permite crear structs sin nombre, útiles para configuraciones temporales:

// Struct anónimo (similar a clase anónima en Java, pero más simple)
config := struct {
    Host string
    Port int
    SSL  bool
}{
    Host: "localhost",
    Port: 8080,
    SSL:  true,
}

Esto es más simple que crear clases anónimas en Java.

Ejemplo Práctico: Sistema de Pagos

Para cerrar, veamos un ejemplo práctico que prepara el terreno para las interfaces (que veremos en el siguiente post):

// PaymentMethod es una interfaz (veremos interfaces después)
type PaymentMethod interface {
    ProcessPayment(amount float64) error
    GetName() string
}

// CreditCard representa una tarjeta de crédito
type CreditCard struct {
    Number     string
    ExpiryDate string
    CVV        string
    CardHolder string
}

// ProcessPayment implementa PaymentMethod para CreditCard
func (c *CreditCard) ProcessPayment(amount float64) error {
    fmt.Printf("Processing credit card payment of $%.2f for card ending in %s\n", amount, c.Number[len(c.Number)-4:])
    return nil
}

Este ejemplo muestra cómo diferentes tipos pueden implementar el mismo comportamiento sin herencia explícita.

Conclusiones

Los structs en Go son más simples que las clases en Java, pero no menos poderosos:

Simplicidad: Menos código boilerplate

Composición: Más flexible que la herencia

Performance: Control explícito sobre copias vs referencias

Claridad: El código es más directo y fácil de entender

Si vienes de Java, el cambio de mentalidad puede tomar un poco de tiempo, pero una vez que te acostumbres, encontrarás que Go te da más control con menos complejidad.

Próximos Pasos

En el siguiente post exploraremos las interfaces implícitas de Go y cómo implementan el principio de "duck typing". Verás cómo el sistema de pagos que empezamos aquí se completa con múltiples proveedores usando interfaces.


¿Tienes preguntas sobre structs en Go? Déjame saber en los comentarios. Y si quieres ver el código completo con todos los ejemplos, puedes encontrarlo en mi repositorio go-mastery-lab.

Enjoy!

José Díaz

+51 939 965 148

More from this blog

JoeDayz

55 posts

Community Guy | Java Champion | AWS Architect | Software Architect