Соглашения по именованию файлов в Go: snake_case или что-то ещё?
Основные правила именования файлов в Go
В Go нет жёстких синтаксических ограничений на имена файлов (кроме того, что они должны быть валидными для ОС), но есть устоявшиеся конвенции, которым следуют почти все Go-разработчики. Давайте разберём их по порядку.
1. Всегда используйте snake_case (строчные буквы с подчёркиваниями)
Это главное правило. Имена файлов должны быть в нижнем регистре, слова разделяются подчёркиванием _. Никакого CamelCase или PascalCase для файлов. Почему? Потому что на некоторых файловых системах (например, macOS по умолчанию нечувствительна к регистру, а Linux — чувствительна). Если вы назовёте файл MyHandler.go на macOS, он может работать, но на Linux вы получите ошибку, если где-то в импорте или сборке будет ссылка на myhandler.go.
Пример правильного именования:
// Плохо
MyHandler.go
UserRepository.go
// Хорошо
my_handler.go
user_repository.go
2. Имя файла должно отражать его содержимое
В Go принято, чтобы один файл содержал логически связанный код. Например:
handlers.go— HTTP-обработчикиmodels.go— структуры данных (модели)routes.go— маршрутыmiddleware.go— промежуточное ПОerrors.go— определения ошибокtesting.go— тесты (хотя обычно тесты лежат в_test.go)
3. Специальные суффиксы: _test, _os, _arch
Go использует соглашения для условной компиляции и тестирования:
- Тесты: файлы должны заканчиваться на
_test.go. Например,handlers_test.go. - Платформозависимый код: используйте суффиксы
_linux.go,_windows.go,_darwin.goи т.д. Например,file_unix.go,file_windows.go. - Архитектурозависимый код:
_amd64.go,_arm.goи т.д.
4. Имя файла не должно совпадать с именем пакета
Хотя технически это возможно, это может вызвать путаницу. Например, если ваш пакет называется handler, не называйте файл handler.go — лучше handlers.go или handler_impl.go.
5. Пример правильной структуры вашего проекта
Вот как можно организовать ваш проект с заметками:
// main.go
package main
func main() {
// ...
}
// handlers.go
package main
func CreateNoteHandler() { ... }
func GetNoteHandler() { ... }
// models.go
package main
type Note struct {
ID int
Text string
}
// routes.go
package main
func SetupRoutes() { ... }
// database.go
package main
func InitDB() { ... }
func SaveNote(n Note) error { ... }
6. Что насчёт одного файла на тип?
В некоторых языках (Java, C#) принято иметь один файл на класс. В Go это не обязательно. Обычно один файл содержит несколько связанных типов и функций. Разделяйте файлы по логическим модулям, а не по каждому типу. Например:
types.go— все основные типы и константыvalidation.go— функции валидацииserialization.go— JSON/XML сериализация
7. Исключения из правил
Иногда в стандартной библиотеке Go встречаются файлы с одним словом без подчёркиваний: http.go, json.go, fmt.go. Это нормально, если имя короткое и однозначное. Но если имя состоит из нескольких слов, используйте подчёркивания: http_transport.go, json_encoder.go.
Итог: для вашего проекта используйте handlers.go, models.go, routes.go — это будет соответствовать конвенциям Go и не вызовет проблем на разных платформах.
Альтернативный подход: группировка по функциональности
В дополнение к основным правилам, в крупных проектах часто используется стратегия «один файл — одна ответственность», но не в смысле «один тип», а в смысле «одна функциональная область». Например, если у вас есть пакет api, вы можете разбить его так:
api/
├── create.go // логика создания ресурса
├── get.go // логика получения
├── update.go // обновление
├── delete.go // удаление
├── middleware.go // middleware
└── errors.go // ошибки
Этот подход особенно удобен, когда обработчики становятся большими. Каждый файл содержит ровно одну функцию-обработчик и связанные с ней вспомогательные функции. Имена файлов при этом отражают HTTP-метод или операцию, а не просто «handlers».
Важно: даже при таком подходе сохраняйте snake_case. Не называйте файл CreateNote.go — правильно create_note.go.
Когда использовать CamelCase?
Единственный случай, когда в имени файла может быть заглавная буква — это если файл экспортирует только один тип и вы хотите подчеркнуть, что это основной тип пакета. Но это редкое исключение, и даже в стандартной библиотеке так не делают. Лучше всегда придерживаться snake_case.
Ответов пока нет.
Войдите чтобы оставить ответ