Interface fmt.Stringer
Parte da seção Programação Orientada a Objetos do Journey de GO da Coddy. Lição 75 de 107.
A interface fmt.Stringer controla como seus tipos aparecem quando são impressos. É uma das interfaces mais implementadas em Go, definida no pacote fmt:
type Stringer interface {
String() string
}Quando você passa um valor para fmt.Println, fmt.Printf com %v ou funções semelhantes, o Go verifica se o tipo implementa Stringer. Se implementar, o Go chama o método String() para obter a representação textual.
type Temperature struct {
Celsius float64
}
func (t Temperature) String() string {
return fmt.Sprintf("%.1f°C", t.Celsius)
}
func main() {
temp := Temperature{Celsius: 23.5}
fmt.Println(temp) // 23.5°C
}Sem o método String(), a impressão exibiria o formato padrão da struct: {23.5}. Ao implementar Stringer, você controla exatamente como seu tipo se apresenta.
Isso é particularmente útil para tipos cujos valores brutos dos campos não transmitem o significado com clareza. Um tipo Duration pode ser exibido como "2h 30m" em vez de mostrar os nanossegundos brutos, ou um tipo User pode exibir um nome formatado em vez de todos os seus campos.
Desafio
FácilVamos criar um sistema de controle de tempo que exibe durações em um formato fácil de entender! Você implementará a interface fmt.Stringer para controlar como seus tipos personalizados aparecem quando são impressos.
Você organizará seu código em dois arquivos:
duration.go: defina seus tipos relacionados a tempo com representações de string personalizadas.Crie uma struct
Durationque armazene um número total de minutos como um inteiro. Implemente o métodoString()para que, quando impressa, ela seja exibida em um formato legível, como2h 30mpara 150 minutos ou0h 45mpara 45 minutos. As horas e os minutos devem sempre ser exibidos.Crie uma struct
Taskcom campos paraName(string) eTime(Duration). ImplementeString()em Task para exibi-la no formato[Name]: [duration], em que a duração usa seu próprio método String.main.go: crie e exiba tarefas com suas durações.Leia uma quantidade de tarefas e, em seguida, leia o nome e a duração em minutos de cada tarefa. Crie instâncias de Task e imprima cada uma diretamente usando
fmt.Println: a interface Stringer cuidará da formatação automaticamente.Depois de imprimir todas as tarefas, calcule e imprima o tempo total de todas as tarefas no formato:
Total: [duration]
As seguintes entradas serão fornecidas:
- Linha 1: número de tarefas
- Linhas seguintes: nome e minutos da tarefa (duas linhas por tarefa)
Por exemplo, dada a entrada:
3
Code Review
90
Meeting
45
Documentation
120Sua saída deverá ser:
Code Review: 1h 30m
Meeting: 0h 45m
Documentation: 2h 0m
Total: 4h 15mE dada a entrada:
2
Design
180
Testing
65Sua saída deverá ser:
Design: 3h 0m
Testing: 1h 5m
Total: 4h 5mAo implementar Stringer, seus tipos se integram perfeitamente às funções de impressão do Go. Em vez de ver campos brutos da struct, como {90}, você obtém uma saída significativa e compreensível para os usuários.
Experimente você mesmo
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Ler o número de tarefas
line, _ := reader.ReadString('\n')
numTasks, _ := strconv.Atoi(strings.TrimSpace(line))
// TODO: Criar um slice para armazenar as tarefas
// TODO: Acompanhar o total de minutos
for i := 0; i < numTasks; i++ {
// Ler o nome da tarefa
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
// Ler a duração da tarefa em minutos
minutesLine, _ := reader.ReadString('\n')
minutes, _ := strconv.Atoi(strings.TrimSpace(minutesLine))
// TODO: Criar um Task com o name e Duration
// TODO: Imprimir a tarefa (fmt.Println usará a interface Stringer)
// TODO: Adicionar minutes ao total
_ = name
_ = minutes
}
// TODO: Imprimir a duração total no formato "Total: Xh Ym"
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de OOP em Go
Arquivos ExternosWorkspace e Módulos do GoPacotes e ImportsNomes Exportados vs. Não ExportadosIntrodução à OOP em GoStructs como ClassesDefinindo Métodos em StructsReceptores de Ponteiro vs. de ValorInicialização de StructsFunções ConstrutorasRecapitulação — Calculadora Simples4Interfaces
Introdução às InterfacesImplementação ImplícitaInterface como ContratoInterface Vazia (any)Asserção de TipoSwitch de TipoComposição de InterfacesInterfaces Stringer e ErrorRecapitulação - Calculadora de Formas7Encapsulamento
Campos Exportados vs. Não ExportadosEncapsulamento no Nível de PacoteMétodos Getters e SettersOcultação de Informações em GoRecapitulação - Registros de Alunos10Genéricos (Go 1.18+)
Introdução aos genéricosParâmetros de tipoRestrições de tipoStructs genéricasAlternativa para métodos genéricosRecapitulação - Coleção genérica13Padrões de Projeto — Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão Abstract FactoryPadrão ObserverPadrão Strategy2Tipos e Structs em Profundidade
Tipos Básicos e CompostosDefinições de Tipos PersonalizadosTags de StructStructs AnônimasStructs AninhadasValores Zero e PadrõesRecapitulação - Livro de Contatos5Composição em vez de herança
Por que Go não tem herançaNoções básicas de incorporação de structsPromoção de métodosIncorporação de várias structsIncorporação vs agregaçãoOcultação de métodos incorporadosRecapitulação - Hierarquia de funcionários8Tratamento de Erros e OOP
A interface errorTipos de Erro PersonalizadosEncapsulamento de Erros (fmt.Errorf)Erros Sentinelaerrors.Is() e errors.As()Panic, Defer e RecoverRecapitulação - Analisador de Arquivos11Biblioteca Padrão e POO
io.Reader e io.Writersort.InterfaceInterface fmt.Stringerencoding/json com StructsInterface http.HandlerRevisão - Modelos de API REST3Ponteiros e Memória
Fundamentos de Ponteiros em GoPonteiros para StructsPassagem por Valor vs. ReferênciaA Função new()Coleta de Lixo em GoRecapitulação - Construtor de Lista Ligada6Polimorfismo em Go
Polimorfismo via InterfacesDuck Typing em GoRegras de Satisfação de InterfacesColeções PolimórficasInjeção de DependênciasRecapitulação - Processador de Pagamentos9Concorrência e OOP
Fundamentos de GoroutinesCanais e comunicaçãoCanais com e sem bufferInstrução selectsync.Mutex e sync.RWMutexsync.WaitGroupDesign de structs thread-safeRevisão - Worker PoolPratique por conta própria: Compilador de Go online