Простые приложения на Go
Простые приложения на Go
Язык программирования Go (Golang) создан для написания надежных, эффективных и понятных системных утилит. Его стандартная библиотека предоставляет мощные инструменты для работы с файлами, сетью, параллелизмом и структурированными данными без необходимости подключения сторонних зависимостей. В этой главе рассматриваются практические примеры создания консольных приложений и серверов, демонстрирующие ключевые особенности синтаксиса и экосистемы языка.
Как запускать примеры из главы
- Сохраните код в файл
.goсpackage main(имя — в Как запустить). - В каталоге с файлом:
go run имя_файла.go
go run имя_файла.go
Разбор:
go runвыполняет быструю проверку примера без отдельного шага сборки бинарника.- Команда компилирует код во временный артефакт и сразу запускает его.
- Такой режим удобен для обучения, потому что сокращает цикл "изменил код -> увидел результат".
- Для нескольких файлов в модуле:
go mod init exampleодин раз, затемgo run .
go mod init example
Разбор:
go mod init exampleсоздаёт файлgo.modи включает модульный режим.- После этого зависимости фиксируются версиями и проект собирается воспроизводимо.
- Команду выполняют один раз в корне нового проекта.
Проверка: go version (Go 1.21+).
Генератор паролей
Генератор паролей демонстрирует работу со строками, массивами символов и генерацией случайных чисел. Стандартная библиотека math/rand позволяет создавать криптографически стойкие последовательности через пакет crypto/rand.
Как запустить
- Файл:
password.go - Команда:
go run password.go
go run password.go
- Нужно: только stdlib.
- Результат:
Сгенерированный пароль: ...
Код примера
Код ITЗагрузка примера кода…
Разбор:
generatePassword(length int)формирует пароль заданной длины и возвращает строку.crypto/randиспользуется для криптографически стойкой генерации, что важно для паролей.- Буфер
[]byteзаполняется случайными индексами символов изcharset. rand.Int(rand.Reader, big.NewInt(...))ограничивает диапазон значений границами набора символов.string(password)превращает байтовый срез в итоговый пароль для вывода.
Разбор кода
- Пакет
crypto/rand: Используется вместоmath/randдля получения безопасных случайных чисел, что критично для генерации паролей. - Структура данных
[]byte: Слайс байтов используется как буфер для хранения символов будущего пароля. Это эффективно по памяти. - Цикл
for range: Итерация по слайсу автоматически определяет индекс и значение элемента. - Преобразование типов: Функция
num.Int64()преобразует большое целое число изbig.Intв стандартный типint64для использования в качестве индекса строки.
Сортировщик текстового файла
Этот пример показывает чтение текста из файла, разделение его на строки, сортировку списка строк и запись результата обратно в файл.
Как запустить
- Файл:
sort_file.go - Подготовка:
input.txtрядом с программой; укажите пути вmain. - Команда:
go run sort_file.go
go run sort_file.go
- Результат:
output.txtс отсортированными строками.
Код примера
Код ITЗагрузка примера кода…
Разбор кода
bufio.Scanner: Эффективный инструмент для посимвольного или построчного чтения больших файлов без загрузки всего содержимого в память.strings.TrimSpace: Удаляет пробелы и символы перевода строки по краям каждой строки перед обработкой.sort.Strings: Встроенная функция сортировки, которая использует алгоритм быстрой сортировки (quicksort) для упорядочивания слайса строк.defer: Обеспечивает закрытие файловых дескрипторов при выходе из функции, предотвращая утечки ресурсов.writer.Flush(): Явно сбрасывает буфер вывода на диск, гарантируя сохранение данных.
Консольный калькулятор
Калькулятор реализует базовую арифметику с обработкой ввода пользователя и разделением логики вычислений на отдельные функции.
Как запустить
- Файл:
calculator.go - Команда:
go run calculator.go
go run calculator.go
- Нужно: интерактивный терминал.
- Результат: цикл вычислений до выхода.
Код примера
Код ITЗагрузка примера кода…
Разбор кода
- Тип
float64: Используется для представления вещественных чисел с высокой точностью. switch: Конструкция выбора действия, которая четко разделяет логику для каждого оператора.- Обработка ошибок: Возврат ошибки при попытке деления на ноль или вводе некорректной операции.
strconv.ParseFloat: Преобразование строкового ввода в числовой тип с проверкой на корректность формата.
Трекер задач в JSON
Как запустить
- Файл:
tasks.go(блок "Код реализации") - Команда:
go run tasks.go
go run tasks.go
- Результат:
tasks.json, список задач в консоли.
Пример демонстрирует сериализацию (преобразование структур данных в JSON) и десериализацию, а также работу с файловой системой для сохранения состояния.
Структура данных
type Task struct {
ID int `json:"id"`
Title string `json:"title"`
Done bool `json:"done"`
Priority int `json:"priority"` // 1-высокий, 5-низкий
}
type TaskList struct {
Tasks []Task `json:"tasks"`
}
Код реализации
Код ITЗагрузка примера кода…
Разбор кода
- Теги
json:"...": Позволяют управлять именами полей в JSON-структуре. Например, полеDoneсохраняется какdone. encoding/json: Стандартный пакет для работы с форматом JSON.json.MarshalIndent: Преобразует структуру в строку JSON с отступами для удобного чтения человеком.os.WriteFile: Современный аналог создания и записи файла с указанием прав доступа (0644).- Логика ID: Простая эвристика для генерации уникального идентификатора на основе последнего элемента списка.
Простой HTTP-сервер и клиент
Как запустить
- Файлы:
server.go,client.go(блоки ниже). - Терминал 1:
go run server.go
go run server.go
- Терминал 2:
go run client.go
go run client.go
- Остановка:
Ctrl+Cна сервере.
Подробнее: Веб на стандартной библиотеке · TCP и UDP.
Go обладает встроенным веб-сервером, который работает очень быстро благодаря встроенной поддержке многопоточности.
Серверная часть
Код ITЗагрузка примера кода…
Клиентская часть
Код ITЗагрузка примера кода…
Разбор кода
http.HandleFunc: Регистрирует функцию обработки запросов для конкретного URL-пути.r.URL.Query().Get("name"): Извлекает параметры из строки запроса (например,?name=Value).http.Response: Объект ответа содержит статус код, заголовки и тело ответа.io.ReadAll: Чтение всего тела ответа в байтовый срез.defer resp.Body.Close(): Обязательная практика для освобождения сетевого ресурса после завершения работы.
Отправитель HTTP-запросов (с кастомными параметрами)
Этот пример расширяет функциональность клиента, позволяя отправлять POST-запросы с произвольными данными и заголовками.
Как запустить
- Файл:
http_post.go - Команда:
go run http_post.go(сервер уже запущен).
go run http_post.go
- Результат: статус и тело ответа.
Код примера
Код ITЗагрузка примера кода…
Разбор кода
http.NewRequest— Создает объект запроса с указанным методом (GET, POST, PUT и т.д.) и телом.bytes.NewBuffer: Позволяет использовать байтовый срез как поток данных для тела запроса.req.Header.Set: Установка пользовательских заголовков, важных для идентификации клиента или формата данных.client.Do: Выполняет запрос и возвращает ответ, позволяя настроить таймауты и редиректы через структуруhttp.Client.
Утилита для сканирования директорий
Инструмент для обхода файловой системы и сбора информации о файлах и подпапках.
Как запустить
- Файл:
scan.go - Команда:
go run scan.go
go run scan.go
- Результат: список файлов и суммарный размер.
Код примера
Код ITЗагрузка примера кода…
Разбор кода
filepath.Walk: Рекурсивно проходит по всей структуре директории, вызывая функцию для каждого найденного пути.os.FileInfo— Структура, содержащая метаданные файла (размер, права доступа, время изменения).info.IsDir(): Метод для определения типа объекта (файл или каталог).filepath.Rel: Вычисление относительного пути для красивого отображения структуры.
Скрипт для создания резервного копирования файлов
Автоматизация процесса дублирования файлов с добавлением временной метки к имени копии.
Как запустить
- Файл:
backup.go - Команда:
go run backup.go
go run backup.go
- Результат: копия в каталоге бэкапов с датой в имени.
Код примера
Код ITЗагрузка примера кода…
Разбор кода
time.Now().Format: Форматирование даты в строку, пригодную для имени файла (ISO 8601 стиль адаптирован под Windows/Linux).io.Copy: Оптимизированная функция для побайтового копирования данных между потоками.os.MkdirAll— Создание директории, если она не существует, включая все необходимые промежуточные уровни.filepath.Join: Корректное объединение путей с учетом разделителей для разных операционных систем.
Мониторинг дискового пространства
Утилита проверяет свободное место на диске и выводит статистику в процентах и абсолютных значениях.
Как запустить
- Файл:
disk.go - Команда:
go run disk.go
go run disk.go
- Результат: свободно/занято на выбранном диске.
Код примера
Код ITЗагрузка примера кода…
Примечание: Стандартная библиотека Go не предоставляет прямой функции для получения общего объема диска и свободного места. Для этого обычно используют пакет syscall (Unix) или golang.org/x/sys/windows. Приведенный код демонстрирует структуру программы, готовую к интеграции системных вызовов.
Парсер URL и проверка доступности ресурса
Инструмент анализирует компоненты URL (хост, путь, порт) и проверяет, доступен ли сервер по этому адресу.
Как запустить
- Файл:
url_check.go - Команда:
go run url_check.go
go run url_check.go
- Нужно: сеть.
- Результат: статус и доступность URL.
Код примера
Код ITЗагрузка примера кода…
Разбор кода
url.Parse— Разбивает строку URL на составные части (схема, хост, порт, путь).parsedURL.Port(): Извлекает номер порта, если он явно указан.client.Head— Отправка запроса метода HEAD, который получает только заголовки без тела ответа, что экономит трафик.Timeout: Ограничение времени ожидания ответа для предотвращения зависания программы при недоступном сервере.
Конвертер форматов дат
Утилита конвертирует строковые представления дат в другие форматы, используя встроенный механизм форматирования времени.
Как запустить
- Файл:
dates.go - Команда:
go run dates.go
go run dates.go
- Результат: дата в новом формате в stdout.
Код примера
Код ITЗагрузка примера кода…
Разбор кода
time.ParseInLocation: Парсинг строки в объектtime.Timeс учетом временной зоны.t.Format: Преобразование объекта времени в строку по заданному шаблону.- Шаблон
2006-01-02: В Go используется специальное эталонное времяMon Jan 2 15:04:05 MST 2006для определения формата. Любая дата в коде должна соответствовать этому шаблону.
Утилита для просмотра запущенных процессов
Отображение списка активных процессов с их идентификаторами (PID) и командами запуска.
Как запустить
- Файл:
ps.go - Команда:
go run ps.go
go run ps.go
- Результат: таблица процессов ОС.
Код примера
Код ITЗагрузка примера кода…
Примечание: Для реальной работы с процессами в Go рекомендуется использовать пакеты вроде github.com/shirou/gopsutil, так как прямое выполнение команд (exec.Command) зависит от ОС и требует наличия специфических утилит. Данный пример демонстрирует принцип взаимодействия с оболочкой.
Дополнительные сниппеты с разбором
HTTP-клиент с таймаутом и проверкой статуса
client := &http.Client{Timeout: 3 * time.Second}
resp, err := client.Get("https://example.com")
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode >= 400 {
return fmt.Errorf("unexpected status: %d", resp.StatusCode)
}
Разбор:
Timeoutограничивает ожидание и защищает CLI от зависания на сетевых вызовах.defer resp.Body.Close()обязателен для освобождения соединения.- Проверка диапазона
>= 400позволяет единообразно обрабатывать ошибки HTTP. - Такой шаблон подходит для большинства утилит, работающих с внешними API.
Пайплайн обработки строк через канал
in := make(chan string)
out := make(chan string)
go func() {
defer close(out)
for s := range in {
out <- strings.ToUpper(strings.TrimSpace(s))
}
}()
Разбор:
- Канал
inпринимает исходные данные, аoutотдаёт нормализованный результат. range inпродолжает работу, пока входной канал не будет закрыт.defer close(out)корректно завершает downstream-этапы пайплайна.- Сниппет показывает основу для многослойной потоковой обработки данных в Go.
Характерный пример именно для Go — Горизонтальная масштабируемость через Горутины
Главная особенность языка Go — это нативная поддержка параллелизма через горутины (goroutines) и каналы (channels). Ниже приведен пример, который обрабатывает список URL параллельно, используя ограниченное количество горуток.
Как запустить
- Файл:
goroutines.go - Команда:
go run goroutines.go
go run goroutines.go
- Нужно: сеть для URL из примера.
- Результат: параллельные ответы или ошибки по каждому адресу.
Код ITЗагрузка примера кода…
Разбор:
sync.WaitGroupгарантирует, что итоговый вывод начнётся только после завершения всех goroutine.- Канал
semaphoreс буферомworkersограничивает параллелизм и предотвращает перегрузку сети. - Каждая goroutine выполняет
HEAD-запрос и сохраняет статус или ошибку в структуруResult. defer func() { <-semaphore }()освобождает слот даже при раннем выходе по ошибке.time.Since(start)измеряет реальное время параллельной обработки списка URL.
Разбор кода
go func(...): Запуск функции в отдельной горуток. Горутина потребляет минимум памяти и переключается очень быстро.
go func(...)
sync.WaitGroup: Синхронизатор, позволяющий основной программе ждать завершения всех запущенных горуток.chan struct{}(Семафор): Канал пустого типа, ограничивающий максимальное количество одновременно работающих горуток. Это защищает систему от перегрузки.defer: Гарантирует освобождение ресурса канала даже при возникновении ошибки внутри горутины.time.Since: Подсчет времени выполнения блока кода для оценки производительности.
Этот пример иллюстрирует философию Go: простота написания параллельного кода, безопасность потоков и высокая эффективность использования ресурсов процессора.
Базовый разбор HTTP и HTTPS находится в отдельной статье — HTTP как основа веб-интеграций.