0Pricing
Go Academy · Lección

Definición e implementación de interfaces

Implementación implícita y la interfaz vacía

Definición e implementación de interfaces es una lección gratuita de Go Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Go Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Go Academy incluye 4 lecciones en total.

¿Qué es una interfaz?

Una interfaz en Go es un conjunto de firmas de métodos. Cualquier tipo que implemente todos esos métodos satisface la interfaz de forma implícita; no se necesita ninguna palabra clave implements. Esto se denomina tipado estructural o duck typing.

Declarar una interfaz

Defina una interfaz con la palabra clave type:

package main
import "fmt"

type Shape interface {
    Area() float64
    Perimeter() float64
}

type Circle struct{ Radius float64 }
func (c Circle) Area() float64      { return 3.14159 * c.Radius * c.Radius }
func (c Circle) Perimeter() float64 { return 2 * 3.14159 * c.Radius }

func main() {
    var s Shape = Circle{5}
    fmt.Printf("Area: %.2f\n", s.Area())
}

Satisfacción implícita

No es necesario declarar la intención. Si un tipo tiene los métodos adecuados, satisface la interfaz automáticamente:

package main
import "fmt"

type Greeter interface{ Greet() string }

type English struct{}
func (e English) Greet() string { return "Hello" }

type Spanish struct{}
func (s Spanish) Greet() string { return "Hola" }

func say(g Greeter) { fmt.Println(g.Greet()) }

func main() {
    say(English{})
    say(Spanish{})
}

La interfaz vacía

interface{} (o any en Go 1.18+) es satisfecha por todos los tipos. Se utiliza cuando el tipo se desconoce en tiempo de compilación:

package main
import "fmt"

func printAny(v any) { fmt.Printf("%T: %v\n", v, v) }

func main() {
    printAny(42)
    printAny("hello")
    printAny([]int{1,2,3})
}

Valores de interfaz

Un valor de interfaz contiene dos elementos: un tipo concreto y un valor concreto. Una interfaz nil tiene ambos establecidos en nil:

package main
import "fmt"

type Animal interface{ Sound() string }
type Dog struct{}
func (d Dog) Sound() string { return "woof" }

func main() {
    var a Animal
    fmt.Println(a == nil) // true
    a = Dog{}
    fmt.Println(a == nil) // false
    fmt.Println(a.Sound())
}

Satisfacción de varias interfaces

Un tipo puede satisfacer varias interfaces simultáneamente:

package main
import "fmt"

type Reader interface{ Read() string }
type Writer interface{ Write(string) }
type ReadWriter interface{ Reader; Writer }

type File struct{ content string }
func (f *File) Read() string       { return f.content }
func (f *File) Write(s string)     { f.content = s }

func main() {
    var rw ReadWriter = &File{}
    rw.Write("hello")
    fmt.Println(rw.Read())
}

Asignación de interfaces

Una interfaz más amplia puede contener un valor concreto de una interfaz más específica. La asignación entre tipos de interfaz requiere que el tipo concreto satisfaga ambas:

package main
import "fmt"

type Stringer interface{ String() string }

type Point struct{ X, Y int }
func (p Point) String() string { return fmt.Sprintf("(%d,%d)", p.X, p.Y) }

func main() {
    var s Stringer = Point{3, 4}
    fmt.Println(s.String())
}

Trampa de la interfaz nil

Una interfaz que no es nil y contiene un valor concreto nil NO es igual a nil:

package main
import "fmt"

type MyErr struct{}
func (e *MyErr) Error() string { return "oops" }

func bad() error {
    var e *MyErr // nil pointer
    return e     // returns non-nil interface!
}

func main() {
    err := bad()
    fmt.Println(err == nil) // false — common gotcha
}

Las interfaces facilitan las pruebas

Definir las dependencias como interfaces permite sustituir las implementaciones reales por mocks en las pruebas:

package main
import "fmt"

type EmailSender interface{ Send(to, body string) error }

type MockSender struct{ Sent []string }
func (m *MockSender) Send(to, body string) error {
    m.Sent = append(m.Sent, to)
    return nil
}

func notify(s EmailSender, addr string) { s.Send(addr, "hello") }

func main() {
    mock := &MockSender{}
    notify(mock, "a@b.com")
    fmt.Println(mock.Sent) // [a@b.com]
}

Acepte interfaces, devuelva estructuras

Una buena práctica de Go: los parámetros de las funciones deben ser interfaces (para ofrecer flexibilidad) y los tipos devueltos deben ser tipos concretos (para que el código que llama sepa qué recibe):

package main

type Logger interface{ Log(string) }

type FileLogger struct{}
func (f *FileLogger) Log(s string) {}

func NewFileLogger() *FileLogger { // returns concrete
    return &FileLogger{}
}

func process(l Logger) {} // accepts interface

func main() { process(NewFileLogger()) }

Mantenga las interfaces pequeñas

La biblioteca estándar de Go favorece las interfaces pequeñas: io.Reader tiene un método y io.Writer tiene un método. Las interfaces pequeñas son más fáciles de combinar y de simular con mocks.

Comprobación rápida

¿Es necesario que un tipo declare que implementa una interfaz?

Repaso: interfaces

Conclusiones principales:

  • Las interfaces definen comportamiento, no datos
  • La satisfacción es implícita; no existe la palabra clave implements
  • La interfaz vacía (any) acepta todos los tipos
  • Preste atención a la trampa de la interfaz nil
  • Mantenga las interfaces pequeñas y centradas

Propuesta de práctica

Defina una interfaz Storage con Save(key, value string) error y Load(key string) (string, error). Impleméntela con un MemStorage respaldado por un mapa y pruébelo.

Preguntas frecuentes

¿La lección «Definición e implementación de interfaces» es gratis?

Sí — el texto completo de «Definición e implementación de interfaces» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Go Academy, actualiza a CoddyKit PRO. El curso de Go Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Definición e implementación de interfaces»?

Implementación implícita y la interfaz vacía Practicas Go Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Go Academy?

No se requiere experiencia previa. Go Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Definición e implementación de interfaces»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Go Academy?

Sí. Cada lección de Go Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Definición e implementación de interfaces
  2. Interfaces principales de la biblioteca estándar
  3. Aserciones de tipo y switches de tipo
  4. Composición de interfaces y buenas prácticas
← Volver a Go Academy