12 Métodos en Structs y Comparación en Go
Published Apr 30, 2024
🧠 Introducción
En Go, un método es una función asociada a un tipo definido por el usuario, como un struct
. Esto permite encapsular comportamientos relacionados con los datos, de forma muy similar (pero no igual) a la programación orientada a objetos.
1. 🧱 ¿Qué es un método?
Un método es simplemente una función que se define con un receptor:
func (p Point) nombreMetodo() tipoRetorno {
// código
}
Donde Point
es un struct y p
es una copia (o un puntero) a la instancia actual.
2. ✍️ Ejemplo básico
type Point struct {
x float32
y float32
}
func (p Point) Sum() float32 {
return p.x + p.y
}
func main() {
pt1 := Point{x: 5.6, y: 3.8}
fmt.Println(pt1.Sum()) // 9.4
}
- El receptor
(p Point)
hace queSum
sea un método del structPoint
. - Los métodos pueden usar cualquier lógica y acceder a los campos del struct.
3. 🔄 Métodos con punteros
Cuando quieres modificar el valor del struct dentro del método, necesitas pasar un puntero:
func (p *Point) MoveX() {
p.x = p.x + 5
}
pt1 := Point{x: 5.6, y: 3.8}
pt1.MoveX()
fmt.Println(pt1.x) // 10.6
🧠 Nota:
Aunque esto se parece a programación orientada a objetos, Go no tiene herencia ni sobrecarga de métodos.
Sobrecarga es cuando defines varias funciones con el mismo nombre pero distintas firmas.
Go no lo permite: cada nombre de método debe ser único dentro del mismo tipo.
4. 📊 Comparar structs
Puedes usar el operador ==
solo si el struct no contiene slices, maps o funciones:
type Point struct {
x float32
y float32
}
pt1 := Point{5.6, 3.8}
pt2 := Point{5.6, 3.8}
fmt.Println(pt1 == pt2) // true
Pero si el struct incluye un slice:
type Point struct {
x float32
y float32
name []string
}
Recibirás un error:
invalid operation: pt1 == pt2 (struct containing []string cannot be compared)
5. 🧰 Comparación con cmp
El paquete github.com/google/go-cmp/cmp
permite comparar structs complejos (con slices, maps, etc).
📦 Instalación:
go get -u github.com/google/go-cmp/cmp
Para que funcione, los campos deben estar exportados (inicial con mayúscula).
✅ Ejemplo:
import "github.com/google/go-cmp/cmp"
type Point struct {
X float32
Y float32
Name []string
}
pt1 := Point{X: 5.6, Y: 3.8, Name: []string{"elprogramadorgt"}}
pt2 := Point{X: 5.6, Y: 3.8, Name: []string{"elprogramadorgt"}}
fmt.Println(cmp.Equal(pt1, pt2)) // true
6. 🛠️ Método de comparación personalizado
Puedes definir tu propio método .Equal()
para comparar lo que a ti te interese:
func (p Point) Equal(p2 Point) bool {
return p.X == p2.X && p.Y == p2.Y
}
Así ignoras el campo Name
, por ejemplo:
pt1 := Point{X: 5.6, Y: 3.8, Name: []string{"a"}}
pt2 := Point{X: 5.6, Y: 3.8, Name: []string{"b"}}
fmt.Println(pt1.Equal(pt2)) // true
✅ Conclusión
- Puedes definir métodos sobre structs para agregarles lógica propia.
- Usa punteros () si quieres que el método modifique el struct.
- Los structs no admiten sobrecarga de métodos.
- Go permite comparar structs simples con
==
, pero para structs complejos (como los que contienen slices) usacmp
o define tu propia comparación.
🛠️ Práctica recomendada
- Crea un struct
Rectangle
con camposWidth
yHeight
. - Define un método
Area()
que retorne su área. - Define un método
Resize(factor float64)
que modifique los valores usando puntero. - Crea dos
Rectangle
con los mismos valores, pero con un campo adicional tipo[]string
, y usacmp.Equal()
para compararlos. - Agrega tu propio método
.Equal()
que compare soloWidth
yHeight
.
🚀 Siguientes pasos
Ya sabes definir structs y métodos, así que es momento de avanzar hacia:
- 🧱 Composición de structs: cómo reutilizar structs dentro de otros structs.
- 🧠 Interfaces en Go: cómo describir comportamientos reutilizables.
- 📦 Organización de structs en paquetes y archivos reales de proyecto.