io и io/ioutil
Тема дорожной карты · Golang
Пакет io — базовый уровень абстракции Go для потокового ввода и вывода, предоставляющий интерфейсы io.Reader и io.Writer, на которых построены вся стандартная библиотека и большинство сторонних Golang-пакетов. Функции io.Copy, io.ReadAll, io.LimitReader и io.TeeReader компонуют эти интерфейсы для перемещения данных между источниками и назначениями без загрузки всего в память сразу — критически важно для высоконагруженных сервисов. Пакет io также определяет io.Closer, io.Seeker, io.ReadWriter и комбинированный io.ReadWriteCloser, широко используемые в net/http, пакете os и обработчиках gRPC Streaming. При построении HTTP-middleware в Go или работе с bufio.Scanner понимание того, как пакет io компонует читатели и записыватели, предотвращает распространённые ошибки с памятью и производительностью. Пакет io — один из ключевых элементов стандартной библиотеки Go, который должен знать каждый Golang-разработчик для написания идиоматичного эффективного кода.
Как это работает
io и io/ioutil знаменита batteries-included: net/http (production-уровневый HTTP клиент + сервер), encoding/json/xml/csv (сериализация), database/sql (интерфейс — в паре с драйвером типа pgx, go-sql-driver/mysql), os + os/exec + io/fs (файлы, процессы), crypto/* (хеширование, шифры, TLS), context (cancellation + значения), time, regexp, text/template / html/template, log/slog (структурированное логирование, 1.21+).
Когда применять
По умолчанию stdlib — большинство, к чему тянутся в npm/pip других языков, уже в Go-stdlib. log/slog — для нового логирования (заменяет log + logrus + zap для большинства нужд). net/http-сервер напрямую — пока реально не нужен фреймворк. database/sql + драйвер — вместо ORM, кроме случая многих тривиальных CRUD-эндпойнтов.
Типичные ошибки
Ловушки io и io/ioutil: свой HTTP-роутинг вместо net/http.ServeMux (route patterns в 1.22 — достаточно для многих приложений); игнор http.Server.ReadTimeout и WriteTimeout (slowloris / hung-connection уязвимости); time.Now() прямо в тестах (мок через интерфейс или clockwork); json.Marshal неэкспортированных полей struct (тихо ноль — пишите с заглавной или используйте json:"...").