Menu
Coddy logo textTech

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 impressos. É uma das interfaces mais comumente 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 em texto.

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 mostraria o formato padrão da struct: {23.5}. Ao implementar o Stringer, você controla exatamente como seu tipo se apresenta.

Isso é particularmente útil para tipos onde os valores brutos dos campos não transmitem o significado de forma clara. Um tipo Duration pode ser exibido como "2h 30m" em vez de mostrar nanossegundos brutos, ou um tipo User pode mostrar um nome formatado em vez de todos os seus campos.

challenge icon

Desafio

Fácil

Vamos construir um sistema de rastreamento de tempo que exibe durações em um formato amigável para humanos! Você implementará a interface fmt.Stringer para controlar como seus tipos personalizados aparecem quando impressos.

Você organizará seu código em dois arquivos:

  • duration.go: Defina seus tipos relacionados ao tempo com representações de string personalizadas.

    Crie uma struct Duration que armazena um número total de minutos como um inteiro. Implemente o método String() para que, quando impresso, ele seja exibido em um formato legível como 2h 30m para 150 minutos, ou 0h 45m para 45 minutos. Horas e minutos devem sempre ser mostrados.

    Crie uma struct Task com campos para Name (string) e Time (Duration). Implemente String() em Task para exibir no formato [Name]: [duration], onde a duração usa seu próprio método String.

  • main.go: Construa e exiba tarefas com suas durações.

    Leia uma contagem de tarefas, então, para cada tarefa, leia seu nome e duração em minutos. Crie instâncias de Task e imprima cada uma diretamente usando fmt.Println—a interface Stringer cuidará da formatação automaticamente.

    Após 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 da tarefa e minutos (duas linhas por tarefa)

Por exemplo, dado:

3
Code Review
90
Meeting
45
Documentation
120

Sua saída deve ser:

Code Review: 1h 30m
Meeting: 0h 45m
Documentation: 2h 0m
Total: 4h 15m

E dado:

2
Design
180
Testing
65

Sua saída deve ser:

Design: 3h 0m
Testing: 1h 5m
Total: 4h 5m

Ao 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 que faz sentido para os usuários.

Folha de consulta

A interface fmt.Stringer controla como os tipos aparecem quando são impressos:

type Stringer interface {
    String() string
}

Quando você passa um valor para fmt.Println ou fmt.Printf com %v, o Go verifica se o tipo implementa Stringer. Se implementar, o Go chama o método String() para obter a representação em texto.

Exemplo de implementação:

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 mostra o formato padrão da struct: {23.5}. Ao implementar Stringer, você controla exatamente como seu tipo se apresenta, tornando a saída mais significativa e amigável para o usuário.

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: Rastrear 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 uma Task com o name e Duration
		// TODO: Imprimir a tarefa (fmt.Println usará a interface Stringer)
		// TODO: Adicionar os minutos ao total
		_ = name
		_ = minutes
	}

	// TODO: Imprimir a duração total no formato "Total: Xh Ym"
}
quiz iconTeste seus conhecimentos

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