ProgramaciónDesarrollador Go

¿Cómo funcionan los métodos para estructuras en Go? ¿Cuál es la diferencia entre declarar un método y una función, y cómo se implementan los métodos para tipos basados en alias (type alias)?

Supere entrevistas con el asistente de IA Hintsage

Respuesta

En Go, los métodos son funciones con un receiver (receptor) que indica a qué tipo pertenece el método:

type User struct { Name string } func (u *User) SayHello() { fmt.Println("Hola,", u.Name) }
  • Un método está asociado a un tipo específico (por ejemplo, User), mientras que una función no.
  • El receptor del método ((u *User)) actúa como el primer argumento en la función, pero la sintaxis y las llamadas son diferentes.

¡Importante! Solo se pueden declarar métodos para tipos definidos en tu paquete (no se permiten métodos en tipos definidos en otros paquetes, incluidos tipos incorporados). El comportamiento con alias (type alias) es especial:

  • Para nuevos tipos basados en existentes (type MyInt int) — se pueden agregar métodos.
  • Para type alias (type MyInt = int) — no se pueden agregar métodos, porque es solo un alias.

Ejemplo:

type MyInt int func (m MyInt) Double() int { return int(m) * 2 } // Type alias type MyIntAlias = int // func (m MyIntAlias) Double() int { ... } // error de compilación

Pregunta capciosa

¿Se puede declarar un método para un slice del tipo []int o para un type alias?

Respuesta: No se pueden declarar métodos para el tipo incorporado ([]int). Para un nuevo tipo de usuario basado en un slice — se puede:

type MySlice []int func (s MySlice) Sum() int { ... } // permitido

Para type alias no se puede:

type SuperSlice = []int // func (s SuperSlice) Sum() int { ... } // error

Ejemplos de errores reales debido a la falta de conocimiento sobre los matices del tema


Historia

En el proyecto de microservicios, el equipo definió un type alias para int64 (para identificadores) y trataron de declarar métodos de validación directamente para él — el código no compilaba, tuvieron que refactorizar todas las estructuras para soportar métodos.

Historia

En el proyecto de backend, escribieron métodos para un slice personalizado, pero accidentalmente no definieron un nuevo tipo (type ... []T), y trabajaron con el incorporado []T, por lo que no pudieron agregar ningún método para trabajar con los elementos del slice.

Historia

Al intentar agregar métodos a tipos de un paquete externo (por ejemplo, time.Time) para estandarizar el trabajo con fechas se descubrió que esto no era posible en Go — se tuvo que usar composición y funciones utilitarias.