0Pricing
Go Academy · Урок

Интерфейс Stringer

Настраивайте способ печати типов

«Интерфейс Stringer» — бесплатный урок Go Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.

Вывод структуры по умолчанию

По умолчанию вывод структуры с помощью %v показывает её исходные поля. Для отладки этого достаточно, но такой вывод не всегда удобен для читателя.

package main

import "fmt"

type Color struct{ R, G, B int }

func main() {
    c := Color{255, 0, 0}
    fmt.Println(c)
}

Интерфейс Stringer

Интерфейс fmt.Stringer содержит один метод:

  • String() string

Любой тип, определяющий его, управляет своим представлением при выводе.

package main

import "fmt"

type Greeting struct{ Name string }

func (g Greeting) String() string {
    return "Hello, " + g.Name
}

func main() {
    fmt.Println(Greeting{"Ada"})
}

Автоматическое использование

Если у типа есть метод String(), то Println, Printf с %v или %s и другие подобные функции автоматически вызывают его.

package main

import "fmt"

type Greeting struct{ Name string }

func (g Greeting) String() string {
    return "Hi " + g.Name
}

func main() {
    g := Greeting{"Bob"}
    fmt.Printf("%s and %v\n", g, g)
}

Форматирование внутри String()

Создайте результат с помощью fmt.Sprintf, чтобы получить аккуратное пользовательское представление.

package main

import "fmt"

type Color struct{ R, G, B int }

func (c Color) String() string {
    return fmt.Sprintf("rgb(%d, %d, %d)", c.R, c.G, c.B)
}

func main() {
    fmt.Println(Color{255, 128, 0})
}

Stringer для именованных типов

Stringer предназначен не только для структур. Любой именованный тип, даже основанный на int, может реализовать его. Это классический шаблон перечисления.

package main

import "fmt"

type Day int

func (d Day) String() string {
    names := []string{"Mon", "Tue", "Wed"}
    return names[d]
}

func main() {
    fmt.Println(Day(1))
}

Перечисления с удобным выводом

Объедините iota с Stringer, чтобы константы выводились в виде понятных имён, а не чисел.

package main

import "fmt"

type State int

const (
    Idle State = iota
    Running
    Done
)

func (s State) String() string {
    return []string{"Idle", "Running", "Done"}[s]
}

func main() {
    fmt.Println(Running)
}

Получатель-значение и получатель-указатель

Если String() использует получатель-значение, и значения, и указатели выводятся корректно. При использовании получателя-указателя это происходит только для указателей.

package main

import "fmt"

type Tag struct{ Name string }

func (t Tag) String() string { return "#" + t.Name }

func main() {
    t := Tag{"go"}
    fmt.Println(t)
    fmt.Println(&t)
}

Избегайте бесконечной рекурсии

Никогда не вызывайте fmt.Sprintf("%v", t) для того же типа внутри его собственного String(). Это будет бесконечно вызывать String() снова. Форматируйте поля напрямую.

package main

import "fmt"

type Money struct{ Cents int }

func (m Money) String() string {
    return fmt.Sprintf("$%.2f", float64(m.Cents)/100)
}

func main() {
    fmt.Println(Money{1050})
}

Stringer в срезах

При выводе среза значений Stringer каждый элемент форматируется с помощью его метода String().

package main

import "fmt"

type Tag struct{ Name string }

func (t Tag) String() string { return "#" + t.Name }

func main() {
    tags := []Tag{{"go"}, {"web"}}
    fmt.Println(tags)
}

Использование в качестве интерфейса

Вы можете сохранить любой Stringer в переменной типа fmt.Stringer и вызвать String() через интерфейс.

package main

import "fmt"

type City struct{ Name string }

func (c City) String() string { return "City of " + c.Name }

func main() {
    var s fmt.Stringer = City{"Oslo"}
    fmt.Println(s.String())
}

Почему это важно

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

package main

import "fmt"

type Temp float64

func (t Temp) String() string {
    return fmt.Sprintf("%.1f°C", float64(t))
}

func main() {
    fmt.Println(Temp(21.5))
}

Быстрая проверка

Какой метод должен определить тип, чтобы удовлетворять интерфейсу fmt.Stringer?

Итоги: интерфейс Stringer

Вы научились настраивать вывод:

  • Реализуйте String() string, чтобы удовлетворять интерфейсу fmt.Stringer.
  • fmt автоматически вызывает его для %v и %s.
  • Это особенно удобно для перечислений; избегайте рекурсивного использования %v для того же типа.
package main

import "fmt"

type Level int

func (l Level) String() string {
    return []string{"low", "mid", "high"}[l]
}

func main() {
    fmt.Println(Level(2))
}

Часто задаваемые вопросы

Урок «Интерфейс Stringer» бесплатный?

Да — полный текст урока «Интерфейс Stringer» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.

Чему я научусь в уроке «Интерфейс Stringer»?

Настраивайте способ печати типов Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Go Academy?

Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Интерфейс Stringer»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Go Academy?

Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Глаголы Printf
  2. Sprintf и Fprintf
  3. Интерфейс Stringer
  4. Сканирование ввода
← Назад к Go Academy