Stringer é uma interface para definir o formato de string dos valores.
A interface consiste em um único método String:
type Stringer interface {
String() string
}
Os tipos que quiserem implementar essa interface precisam ter um método String() que retorne uma representação do tipo em string, amigável para humanos.
O pacote fmt (e muitos outros) procura por esse método para formatar e imprimir valores.
Suponha que estamos trabalhando em uma aplicação que lida com distâncias geográficas medidas em unidades diferentes.
Definimos os tipos DistanceUnit e Distance da seguinte forma:
type DistanceUnit int
const (
Kilometer DistanceUnit = 0
Mile DistanceUnit = 1
)
type Distance struct {
number float64
unit DistanceUnit
}
No exemplo acima, Kilometer e Mile são constantes do tipo DistanceUnit.
Esses tipos não implementam a interface Stringer, porque não têm o método String.
Por isso, as funções do fmt vão imprimir valores Distance usando o "formato padrão" do Go:
mileUnit := Mile
fmt.Sprint(mileUnit)
// => 1
// The result is '1' because that is the underlying value of the 'Mile' constant (see constant declarations above)
dist := Distance{number: 790.7, unit: Kilometer}
fmt.Sprint(dist)
// => {790.7 0}
// not a very useful output!
Para deixar a saída mais informativa, implementamos a interface Stringer para os tipos DistanceUnit e Distance, adicionando um método String a cada tipo:
func (sc DistanceUnit) String() string {
units := []string{"km", "mi"}
return units[sc]
}
func (d Distance) String() string {
return fmt.Sprintf("%v %v", d.number, d.unit)
}
As funções do pacote fmt vão chamar esses métodos ao formatar valores Distance:
kmUnit := Kilometer
kmUnit.String()
// => km
mileUnit := Mile
mileUnit.String()
// => mi
dist := Distance{
number: 790.7,
unit: Kilometer,
}
dist.String()
// => 790.7 km