AnyCompiler

Interfaces

Una interface define un conjunto de methods que un tipo debe tener. A diferencia de muchos lenguajes, Go no tiene ninguna palabra clave "implements" — un tipo satisface una interface automáticamente, con solo tener methods con nombres y firmas coincidentes. Esto se llama satisfacción de interface implícita (o estructural).

package main

import "fmt"

type Shape interface {
	Area() float64
}

type Circle struct {
	Radius float64
}

func (c Circle) Area() float64 {
	return 3.14159 * c.Radius * c.Radius
}

func describe(s Shape) {
	fmt.Printf("Area: %.2f\n", s.Area())
}

func main() {
	describe(Circle{Radius: 2})
}
Output
Area: 12.57

Cómo se ve un error real de método faltante

Como la satisfacción se comprueba de forma estructural, pasar un tipo al que le falta un method requerido se detecta inmediatamente en tiempo de compilación. Esto es genuinamente lo que reporta el compilador — capturado de una ejecución real, no escrito para parecer plausible:

package main

import "fmt"

type Shape interface {
	Area() float64
}

type Triangle struct {
	Base, Height float64
}

func describe(s Shape) {
	fmt.Printf("Area: %.2f\n", s.Area())
}

func main() {
	describe(Triangle{Base: 4, Height: 3})
}
Output
# command-line-arguments
./main.go:18:19: cannot use Triangle literal (type Triangle) as type Shape in argument to describe:
	Triangle does not implement Shape (missing Area method)

Triangle nunca definió un method Area(), así que simplemente no satisface Shape — no hay ninguna declaración explícita que corregir, porque nunca hubo ninguna para empezar. Añade el method que falta, y ese mismo valor de Triangle satisfaría Shape sin ningún otro cambio.

Siguiente: pointers — & y *, más directos que el modelo de ownership de Rust.

Practice exercise

Define una interface Named con un method Name() string. Define un struct Dog { DogName string } con un method Name() que devuelva d.DogName. Escribe una función greet(n Named) que imprima "Hello, " + n.Name(). Llama a greet con un Dog{DogName: "Rex"}.