Tracks
/
Go
Go
/
Temario
/
Interfaces
In

Interfaces en Go

2 ejercicios

Acerca de Interfaces

La interfaz como un conjunto de métodos

En su forma más simple, un tipo de interfaz es un conjunto de firmas de métodos. Aquí tienes un ejemplo de definición de interfaz que incluye dos métodos, Add y Value:

type Counter interface {
    Add(increment int)
    Value() int
}

Los nombres de los parámetros como increment se pueden omitir en la definición de la interfaz, pero a menudo aumentan la legibilidad.

Los nombres de las interfaces en Go no contienen la palabra Interface ni I. En su lugar, suelen terminar en er, por ejemplo Reader o Stringer.

Implementar una interfaz

Cualquier tipo que defina los métodos de la interfaz la «implementa» de forma automática e implícita. En Go no existe la palabra clave implements.

El siguiente tipo implementa la interfaz Counter que vimos antes.

type Stats struct {
    value int
    // ...
}

func (s Stats) Add(v int) {
    s.value += v
}

func (s Stats) Value() int {
    return s.value
}

func (s Stats) SomeOtherMethod() {
    // The type can have additional methods not mentioned in the interface.
}

Para implementar la interfaz, no importa si el método tiene un receptor de valor o de puntero. (Vuelve a consultar los conceptos de métodos si tienes dudas al respecto).

Un valor de tipo interfaz puede contener cualquier valor que implemente esos métodos. 1

Eso significa que ahora Stats se puede usar en todos los lugares donde se espera la interfaz Counter.

func SetUpAnalytics(counter Counter) {
    // ...
}

stats := Stats{}
SetUpAnalytics(stats)
// works because Stats implements Counter

Si todos los parámetros y valores de retorno de una función tuvieran que usar tipos concretos (es decir, tipos que no son interfaces), eso limitaría mucho su reutilización. Al usar tipos de interfaz en los parámetros, solo se define el comportamiento que la función necesita para hacer su trabajo. Ahora la función se puede usar con parámetros de distintos tipos concretos, siempre que esos tipos concretos implementen la interfaz. La misma lógica se aplica cuando se usan tipos de interfaz como valores de retorno.

Como las interfaces se implementan de forma implícita, un tipo puede implementar varias interfaces con facilidad. Solo necesita tener definidos todos los métodos necesarios.

Combinar interfaces

Las definiciones de interfaz pueden incluir otras interfaces. Aquí tienes un ejemplo de la biblioteca estándar.

type ReadCloser interface {
	Reader
	Closer
}

// Based on these interfaces:

type Reader interface {
	Read(p []byte) (n int, err error)
}

type Closer interface {
	Close() error
}

En lugar de repetir las firmas de los métodos Read y Close para definir ReadCloser, la definición de la interfaz aprovecha las definiciones existentes de Reader y Closer.

La interfaz vacía

Hay un tipo de interfaz muy especial en Go: el tipo interfaz vacía, que no contiene ningún método. La interfaz vacía se escribe así: interface{}. En Go 1.18 o superior también se puede usar any. Se definió como un alias.

Como la interfaz vacía no tiene métodos, todos los tipos la implementan de forma implícita. Esto es útil para definir una función que pueda aceptar cualquier valor de forma genérica. En ese caso, el parámetro de la función usa el tipo interfaz vacía.

Por ejemplo:

func AnythingGoes(i interface{}) string {
    if i == 0 {
        return "zero"
    }
    if i == "" {
        return "empty string"
    }
    return "something else"
}
  1. Tour of Go: Interfaces ↩

Editar en GitHub El enlace se abre en una ventana o pestaña nueva

Aprende Interfaces

La práctica está bloqueada

Desbloquea 1 ejercicio más para practicar Interfaces