Menu
Coddy logo textTech

Интерфейс fmt.Stringer

Часть раздела Объектно-ориентированное программирование путешествия по GO на Coddy. Урок 75 из 107.

Интерфейс fmt.Stringer управляет тем, как отображаются ваши типы при печати. Это один из наиболее часто реализуемых интерфейсов в Go, определённый в пакете fmt:

type Stringer interface {
    String() string
}

Когда вы передаёте значение в fmt.Println, fmt.Printf с %v или подобные функции, Go проверяет, реализует ли тип Stringer. Если да, Go вызывает String() method, чтобы получить текстовое представление.

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
}

Без метода String() при печати отображался бы формат структуры по умолчанию: {23.5}. Реализуя Stringer, вы точно контролируете, как ваш тип представляется.

Это особенно полезно для типов, у которых необработанные значения полей не передают смысл достаточно ясно. Тип Duration может отображаться как "2h 30m", вместо того чтобы показывать необработанные наносекунды, а тип User может отображать отформатированное имя вместо всех своих полей.

challenge icon

Задание

Легко

Давайте создадим систему учёта времени, которая отображает продолжительность в удобном для пользователя формате! Вы реализуете интерфейс fmt.Stringer, чтобы управлять отображением ваших пользовательских типов при печати.

Вы организуете код в двух файлах:

  • duration.go: Определите типы, связанные со временем, с пользовательскими строковыми представлениями.

    Создайте структуру Duration, которая хранит общее количество минут в виде целого числа. Реализуйте метод String(), чтобы при печати значение отображалось в понятном формате, например 2h 30m для 150 минут или 0h 45m для 45 минут. Часы и минуты должны отображаться всегда.

    Создайте структуру Task с полями Name (string) и Time (Duration). Реализуйте для Task метод String(), чтобы отображать его в формате [Name]: [duration], где для продолжительности используется её собственный метод String.

  • main.go: Создайте и отобразите tasks вместе с их продолжительностью.

    Считайте количество tasks, затем для каждой task считайте её имя и продолжительность в минутах. Создайте экземпляры Task и выведите каждый из них напрямую с помощью fmt.Println: интерфейс Stringer автоматически выполнит форматирование.

    После вывода всех tasks вычислите и выведите общее время для всех tasks в формате:

    Total: [duration]

Будут предоставлены следующие входные данные:

  • Строка 1: количество tasks
  • Следующие строки: имя Task и минуты (по две строки на каждую task)

Например, для следующих данных:

3
Code Review
90
Meeting
45
Documentation
120

Ваш вывод должен быть таким:

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

А для следующих данных:

2
Design
180
Testing
65

Ваш вывод должен быть таким:

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

Реализовав Stringer, вы обеспечите бесшовную интеграцию своих типов с функциями печати Go. Вместо необработанных полей структуры, таких как {90}, вы получите осмысленный вывод, понятный пользователям.

Попробуйте сами

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Прочитать количество задач
	line, _ := reader.ReadString('\n')
	numTasks, _ := strconv.Atoi(strings.TrimSpace(line))

	// TODO: Создать слайс для хранения задач
	// TODO: Отслеживать общее количество минут

	for i := 0; i < numTasks; i++ {
		// Прочитать название задачи
		name, _ := reader.ReadString('\n')
		name = strings.TrimSpace(name)

		// Прочитать длительность задачи в минутах
		minutesLine, _ := reader.ReadString('\n')
		minutes, _ := strconv.Atoi(strings.TrimSpace(minutesLine))

		// TODO: Создать Task с name и Duration
		// TODO: Вывести задачу (fmt.Println будет использовать интерфейс Stringer)
		// TODO: Добавить minutes к total
		_ = name
		_ = minutes
	}

	// TODO: Вывести общую длительность в формате "Total: Xh Ym"
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Go