AnyCompiler

Interfaces

Uma interface define um conjunto de methods que um tipo deve ter. Ao contrário de muitas linguagens, Go não tem palavra-chave "implements" alguma — um tipo satisfaz uma interface automaticamente, só por ter methods com nomes e assinaturas correspondentes. Isso é chamado de satisfação implícita (ou estrutural) de interface.

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

Como é um erro real de method faltando

Como a satisfação é verificada estruturalmente, passar um tipo ao qual falta um method exigido é capturado imediatamente em tempo de compilação. Isso é genuinamente o que o compilador relata — capturado de uma execução real, não escrito para parecer plausível:

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 definiu um method Area(), então simplesmente não satisfaz Shape — não há declaração explícita para corrigir, porque nunca houve uma para começar. Adicione o method que falta, e o mesmíssimo valor de Triangle satisfaria Shape sem nenhuma outra mudança.

A seguir: pointers — & e *, mais diretos que o modelo de ownership do Rust.

Practice exercise

Defina uma interface Named com um method Name() string. Defina um struct Dog { DogName string } com um method Name() que retorne d.DogName. Escreva uma function greet(n Named) que imprima "Hello, " + n.Name(). Chame greet com um Dog{DogName: "Rex"}.