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})
}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})
}# 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"}.