Structs en Go: Tags y composición con embedding (ejemplos claro)
¿Qué son los structs en Go?
Los structs son tipos personalizados que permiten agrupar campos de diferentes tipos de datos bajo un mismo nombre. En Go, se definen usando la palabra clave struct seguida de un tipo. Por ejemplo:
// Definimos un struct Persona
type Persona struct {
nombre string
edad int
}
// Crear una instancia
p := Persona{"Marcos", 30}
// Acceder a campos
fmt.Println(p.nombre) // Output: MarcosEn el ejemplo, creamos un struct Persona con campos nombre y edad. Luego instanciamos p y accedemos a sus campos usando el operador punto (.).
Tipos de structs
- Structs básicos: Agrupan datos simples (ej:
string,int). - Structs anónimos: No se especifica el nombre del tipo, útil para composiciones.
- Structs con métodos: Puedes añadir funciones asociadas al struct (como
Print()).
Ejemplo con método
package main
import "fmt"
// Struct con método
type Cuenta struct {
saldo float64
}
// Método para mostrar saldo
func (c Cuenta) MostrarSaldo() {
fmt.Printf("Saldo: %f
", c.saldo)
}
func main() {
c := Cuenta{100.50}
c.MostrarSaldo() // Output: Saldo: 100.50
}El método MostrarSaldo() está asociado al struct Cuenta y se llama usando la notación c.MostrarSaldo().
¿Qué son los tags?
Los tags son cadenas asociadas a campos de un struct, escritas entre comillas. Se usan principalmente para:
- Formatear salida (ej: JSON).
- Documentar campos.
// Struct con tags
type Usuario struct {
ID string `json:"identificador"
Email string `json:"correo"
}
// Imprimir con tags
u := Usuario{"123", "mario@example.com"}
fmt.Printf("%+v
", u)
// Output: {identificador:123 correo:mario@example.com}El tag json:"identificador" indica cómo se debe serializar el campo ID al formato JSON.
Uso común de tags
- Formato de salida: Controlar cómo se muestra un campo en strings.
- Documentación: Agregar comentarios dentro del struct.
- Validación: Especificar restricciones (ej:
json:" required").
Composición mediante embedding
La composición es un principio de diseño donde un struct "embede" a otro, permitiendo reutilizar su comportamiento. En Go, se hace asignando un struct como campo de otro.
// Struct principal
type Perfil struct {
Usuario // Embedding
puntuacion int
}
// Acceder a campos del struct embedded
p := Perfil{Usuario{ID: "456"}, 90}
fmt.Println(p.Usuario.ID) // Output: 456Aquí, Perfil embede al struct Usuario. Podemos acceder directamente a sus campos sin usar punto adicional.
Métodos en structs embeded
Si los métodos del struct embebido son públicos (empezando con mayúscula), también se pueden llamar desde el struct principal:
package main
import "fmt"
// Struct embebido con método
type Direccion struct {
ciudad string
}
// Método en Direccion
func (d Direccion) MostrarCiudad() {
fmt.Printf("Vivo en %s
", d.ciudad)
}
// Struct principal
type Persona struct {
Direccion // Embedding
}
func main() {
p := Persona{Direccion{"Buenos Aires"}}
p.Direccion.MostrarCiudad() // Output: Vivo en Buenos Aires
}Este ejemplo muestra cómo llamar un método del struct embebido desde el struct principal.
Ventajas de embedding
- Reutilización de código: Evita repetir campos y métodos.
- Modularidad: Organiza el código en structs lógicos.
- Encapsulamiento: Puedes ocultar implementaciones dentro de un struct.
Errores comunes y buenas prácticas
- Colisión de nombres: Si el struct embebido tiene campos con nombres iguales al principal, se puede usar
requeridopara evitarlo. - Campos inaccesibles: Solo podrás acceder a campos públicos de structs embeded.
- Excesivo embedding: No abuses de embeddings, puede complicar el código.
Conclusión
Los structs en Go son fundamentales para modelar datos. Los tags ofrecen flexibilidad en la salida y documentación, mientras que el embedding permite composición clara y reutilizable. Combinar estos conceptos ayuda a construir código organizado y mantenible.
Próximos pasos
- Explora
reflectpara manipular structs dinámicamente. - Estudia
structcon campos anidados para estructuras complejas.
DUGLAS MORENO
Comentarios (0)
Sé el primero en comentar.