Уроки модуля (1/5)
Соглашения об именах и стиль
В Go существуют строгие и необсуждаемые соглашения об именах и стилях: официальный форматтер gofmt (и его расширенный набор goimports) определяет отступы, интервалы и порядок импорта. Обсуждение стиля считается не по теме: вы запускаете gofmt -w и идете дальше. Это высвобождает энергию для более интересных задач.
Видимость: верхний или нижний регистр.
Ключевые слова public/private отсутствуют. Первая буква имени определяет видимость:
- Прописные → экспортируются за пределы пакета (
User,Login,MaxRetries). - В нижнем регистре → частный для пакета (
user,parseLine,defaultTimeout).
Это относится к: типам, функциям, методам, переменным, константам, полям структуры.
type User struct {
Name string // exported
email string // private to the package
}«Частное» поле структуры не сериализуется с помощью encoding/json (см. Модуль 8) и недоступно из тестов в pkg_test.
CamelCase, никогда не Snake_case
Никаких подчеркиваний в именах, состоящих из нескольких слов:
- ✅
HTTPClient,userName,parseRequest - ❌
Http_Client,user_name,parse_request
Акронимы пишутся прописными буквами (или строчными буквами, если используется частная область действия):
- ✅
URL,ID,HTML,JSON,parseURL,userID - ❌
Url,Id,Html,Json,parseUrl,userId
type APIResponse struct {
UserID int
HTMLURL string
}Короткие имена для коротких областей
Стиль Go предпочитает краткость при равной ясности в узких областях:
// idiomatic
for i, v := range items { ... }
for k, v := range m { ... }
if err := f(); err != nil { ... }
func (s *Server) Serve(w http.ResponseWriter, r *http.Request) { ... }Установленные соглашения:
i, j, kдля индексов цикла.vдля значений,kдля ключей.rдля*Request/io.Reader,wдляWriter/ResponseWriter.errза ошибки.ctxдляcontext.Context.- Приемники метода: 1–2 одинаковые буквы во всем типе (
s *Server,u *User). Никогдаthisилиself.
Чем шире область действия, тем более информативным должно стать имя: локальная count подойдет, но экспортированная переменная Count должна сообщить вам, что она имеет значение.
Нет префикса «I» в интерфейсах, нет суффикса «Impl».
// idiomatic
type Reader interface { ... }
type fileReader struct { ... } // concrete implementation
// not idiomatic
type IReader interface { ... }
type ReaderImpl struct { ... }Небольшие интерфейсы часто используют суффикс -er: Reader, Writer, Stringer, Closer. Это отражает тот факт, что они описывают поведение (в идеале — один метод).
Имена пакетов
Пакет имеет одно имя, короткое, все строчные, без подчеркиваний:
- ✅
bytes,http,os,userauth - ❌
userAuth,user_auth,UserAuth
Имя пакета представляет собой префикс использования его символов: bytes.Buffer, http.Client. Так что user.User излишен: лучше переименовать тип (user.Account) или пакет.
gofmt не подлежит обсуждению
gofmt обеспечивает:
- Отступы с помощью табуляции (не пробелов).
- Заключите скобку
{на той же строке, что и подпись. - Импорт группами, разделенными пустой строкой;
goimportsтакже добавляет недостающий импорт. - Пространства вокруг операторов.
Всегда запускайте перед фиксацией:
go fmt ./...
goimports -w .
go vet ./...Линтеры (staticcheck, golangci-lint) добавляют дополнительные правила (неиспользуемые переменные, затенение, бесполезные сравнения, ...).
Упражнения
Укажите структуру Http_Client в HTTPClient (и URL-адрес в URL-адресе), а затем перейдите к сокращенным ссылкам.
Решение доступно после 3 попыток
Инвертировать видимость: вернуть спортивное имя пользователя (большой) и личный пароль (минус).
Решение доступно после 3 попыток
Что это за имя идиоматично в Go для спортивного типа «HTTP-сервер»?
type ??? struct {}