Historia del tema:
Go implementó un concepto simple pero poderoso de métodos e interfaces, basado en el duck typing. Los métodos solo se pueden asociar a tipos nombrados (struct o alias), y las interfaces son conjuntos de métodos. Esta es la clave para el polimorfismo y las abstracciones sin necesidad de una declaración explícita de implements.
Problema:
Los programadores que vienen de Java o C# a menudo esperan palabras clave explícitas como implements o extends y se confunden con las diferencias entre métodos con receptor por valor y por puntero, lo que conduce a un comportamiento impredecible y errores al implementar interfaces.
Solución:
Definición de un método y una interfaz:
type User struct { Name string } func (u User) Greet() string { return "Hello, " + u.Name } func (u *User) SetName(name string) { u.Name = name } type Greeter interface { Greet() string }
Características clave:
¿Se pueden declarar métodos para un tipo alias con un tipo base int o string?
Sí, si es un tipo nombrado, por ejemplo:
type MyInt int func (m MyInt) Double() int { return int(m) * 2 }
¿Cuál es la diferencia entre implementar una interfaz a través de métodos con puntero y por valor?
Si el método de la interfaz se declara como (T), tanto T como *T implementan la interfaz. Si es (*T), solo *T satisface la interfaz. Esto es crítico para pasar estructuras a funciones que aceptan interfaces.
¿Cómo funcionan "zero value" para interfaces y qué pasará si se llama a un método en un valor nil?
Una variable de interfaz sin inicialización es igual a nil, intentar llamar a un método en un campo nil causará pánico, a menos que se implemente un manejo explícito de punteros nil.
El tipo se declara con métodos por puntero (*T), la interfaz espera métodos por valor (T), y la estructura no compila al intentar usarse en interfaces. Intento de declarar un método para una variable de tipo []User, en lugar de para el tipo User.
Ventajas:
Desventajas:
Todos los métodos que implementan interfaces se declaran con el receptor correcto. No se utilizan interfaces donde no son necesarias (tipo concreto donde se puede, polimorfismo donde se necesita).
Ventajas:
Desventajas: