0Pricing
Go Academy · Урок

Интерфейсы основной библиотеки

fmt.Stringer, io.Reader, io.Writer

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

fmt.Stringer

У fmt.Stringer один метод: String() string. Реализуйте его, чтобы управлять отображением типа при использовании fmt.Println и %v:

package main
import "fmt"

type Color int
const (Red Color = iota; Green; Blue)
func (c Color) String() string {
    return []string{"Red","Green","Blue"}[c]
}

func main() {
    fmt.Println(Red, Green, Blue) // Red Green Blue
}

Интерфейс ошибок

Встроенный интерфейс error содержит один метод: Error() string. Любой тип, реализующий этот интерфейс, можно использовать как ошибку:

package main
import "fmt"

type ValidationError struct{ Field, Msg string }
func (e *ValidationError) Error() string {
    return e.Field + ": " + e.Msg
}

func validate(age int) error {
    if age < 0 { return &ValidationError{"age", "must be non-negative"} }
    return nil
}

func main() {
    fmt.Println(validate(-1))
}

io.Reader

У io.Reader один метод: Read(p []byte) (n int, err error). Его реализуют файлы, тела HTTP-запросов, строки и буферы:

package main
import ("fmt"; "strings")

func countBytes(r interface{ Read([]byte)(int,error) }) int {
    buf := make([]byte, 512)
    total := 0
    for {
        n, err := r.Read(buf)
        total += n
        if err != nil { break }
    }
    return total
}

func main() {
    r := strings.NewReader("hello world")
    fmt.Println(countBytes(r)) // 11
}

io.Writer

У io.Writer один метод: Write(p []byte) (n int, err error). Он используется в fmt.Fprintf, при ведении журналов, для записи HTTP-ответов и в других случаях:

package main
import ("bytes"; "fmt")

func main() {
    var buf bytes.Buffer
    fmt.Fprintf(&buf, "Hello, %s!", "Go")
    fmt.Println(buf.String()) // Hello, Go!
}

io.ReadWriter и io.Closer

Стандартная библиотека объединяет небольшие интерфейсы в более крупные:

package main
import "io"

// io.ReadWriter = io.Reader + io.Writer
// io.ReadCloser = io.Reader + io.Closer
// io.ReadWriteCloser = all three

func process(rw io.ReadWriter) {
    buf := make([]byte, 8)
    rw.Read(buf)
    rw.Write(buf)
}

func main() { _ = process }

sort.Interface

sort.Interface требует методов Len() int, Less(i, j int) bool и Swap(i, j int):

package main
import ("fmt"; "sort")

type ByLength []string
func (b ByLength) Len() int           { return len(b) }
func (b ByLength) Less(i, j int) bool { return len(b[i]) < len(b[j]) }
func (b ByLength) Swap(i, j int)      { b[i], b[j] = b[j], b[i] }

func main() {
    fruits := ByLength{"banana","apple","kiwi"}
    sort.Sort(fruits)
    fmt.Println([]string(fruits)) // [kiwi apple banana]
}

http.Handler

У http.Handler один метод: ServeHTTP(ResponseWriter, *Request). Весь стек HTTP в Go построен на этом единственном интерфейсе:

package main
import ("fmt"; "net/http")

type Hello struct{}
func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Hello, World!")
}

func main() {
    http.ListenAndServe(":8080", Hello{})
}

fmt.GoStringer

Реализуйте GoString() string, чтобы управлять представлением типа в синтаксисе Go при использовании %#v:

package main
import "fmt"

type Version struct{ Major, Minor int }
func (v Version) GoString() string {
    return fmt.Sprintf("Version{%d, %d}", v.Major, v.Minor)
}

func main() {
    fmt.Printf("%#v\n", Version{1, 18}) // Version{1, 18}
}

encoding.TextMarshaler

Реализуйте MarshalText() ([]byte, error) и UnmarshalText([]byte) error для пользовательского текстового кодирования (строк JSON, YAML и т. п.):

package main
import "fmt"

type Status int
const (Active Status = iota; Inactive)
func (s Status) MarshalText() ([]byte, error) {
    if s == Active { return []byte("active"), nil }
    return []byte("inactive"), nil
}

func main() {
    s := Active
    b, _ := s.MarshalText()
    fmt.Println(string(b)) // active
}

Комбинирование стандартных интерфейсов

Объединяйте стандартные интерфейсы с помощью io.TeeReader, io.MultiWriter и других средств, чтобы создавать мощные конвейеры без написания новых типов:

package main
import ("bytes"; "fmt"; "io"; "strings")

func main() {
    r := strings.NewReader("hello")
    var buf bytes.Buffer
    tee := io.TeeReader(r, &buf)
    io.ReadAll(tee)
    fmt.Println(buf.String()) // hello
}

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

Какой интерфейс должен реализовать тип, чтобы его можно было использовать как ошибку в Go?

Итоги

Основные интерфейсы стандартной библиотеки:

  • fmt.Stringer — пользовательское представление при выводе
  • error — значения ошибок
  • io.Reader / io.Writer — потоковый ввод-вывод
  • sort.Interface — пользовательская сортировка
  • http.Handler — обработка HTTP-запросов

Практическое задание

Реализуйте sort.Interface для []Person (где Person имеет поля Name и Age), чтобы сортировать элементы по убыванию возраста. Выведите отсортированный список.

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

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

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

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

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

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

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

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

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

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

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

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

  1. Определение и реализация интерфейсов
  2. Интерфейсы основной библиотеки
  3. Утверждения типов и переключатели типов
  4. Композиция интерфейсов и лучшие практики
← Назад к Go Academy