Писаные и неписаные правила
В информатике есть только две сложные вещи: инвалидация кеша и именование вещей. - Фил Карлтон
Это не смешная шутка. Писать легко, но читать больно. Вы когда-нибудь задумывались, к чему относится определенная переменная или какова цель определенного пакета? Что ж, вот почему нам нужны правила и условности.
Но хотя условности призваны облегчить жизнь, их можно переоценить и неправильно использовать . Очень важно установить соглашения и правила для именования, но слепое следование им может быть вредным.
В этой статье я рассмотрю некоторые важные соглашения об именах переменных в Go (письменные и неписаные правила) и то, как ими можно злоупотреблять - особенно в случае коротких имен переменных. Именование пакетов и файлов, а также структура проекта не рассматриваются в этой статье, так как они заслуживают отдельной статьи.
Письменные правила в Go
Как и в любом другом языке программирования, в Go есть правила именования. Кроме того, именование имеет семантический эффект, который определяет видимость идентификаторов вне пакета.
MixedCaps
В Go принято использовать MixedCaps
или mixedCaps
(просто camelCase) вместо подчеркивания для написания имен из нескольких слов. Если идентификатор должен быть видимым вне пакета, его первый символ должен быть в верхнем регистре. Если вы не собираетесь использовать его в другом пакете, можете смело придерживаться mixedCaps
.
package awesome type Awesomeness struct { } // Do is an exported method and is accessible in other packages func (a Awesomeness) Do() string { return a.doMagic("Awesome") } // doMagic is where magic happens and only visible inside awesome func (a Awesomeness) doMagic(input string) string { return input }
Если вы попытаетесь вызвать doMagic
извне, вы получите ошибку времени компиляции.
Имена интерфейсов
По соглашению, интерфейсы с одним методом именуются именем метода плюс суффикс -er или аналогичной модификацией для создания существительного агента:
Reader
,Writer
,Formatter
,CloseNotifier
и т. Д. - Официальная документация Go
Эмпирическое правило - MethodName + er = InterfaceName
. Сложность здесь возникает, когда у вас есть интерфейс с более чем одним методом. Именование в соответствии с соглашением не всегда будет очевидным. Должен ли я разделить интерфейс на несколько интерфейсов одним методом? Я думаю, что это субъективное решение, которое зависит от конкретного случая.
Геттеры
Как упоминалось в официальных документах, Go не имеет автоматической поддержки для сеттеров и получателей, но и не запрещает их. Просто для этого есть несколько правил:
"Нет ничего плохого в том, чтобы предоставить геттеры и сеттеры самостоятельно, и часто это уместно, но нет ни идиоматики, ни необходимости вставлять
Get
в имя геттера".
owner := obj.Owner() if owner != user { obj.SetOwner(user) }
Но стоит упомянуть, что если установщик не выполняет никакой специальной логики, лучше просто экспортировать поле и избавиться от методов установки и получения. Если вы сторонник ООП, это может показаться странным. Но это не так.
Неписаные правила в Go
Некоторые правила официально не задокументированы, но широко распространены в сообществе.
Более короткие имена переменных
Сообщество Go пропагандирует использование более коротких описательных переменных, но я думаю, что это конкретное соглашение используется неправильно. Как-то часто забывают об описательной части. Описательное название позволит читателю понять, о чем идет речь, еще до того, как увидит это в действии.
Программы должны быть написаны для того, чтобы люди могли их читать, и только случайно - чтобы машины могли их выполнять. - Гарольд Абельсон
- Однобуквенный идентификатор: особенно используется для локальных переменных с ограниченной областью действия. Мы все согласны с тем, что нам не нужны
index
илиidx
, чтобы понимать, что это инкрементатор. Использование однобуквенного идентификатора, когда он ограничивается рамками цикла, является обычным и рекомендуется.
for i := 0; i < len(pods); i++ { // } ... for _, p := range pods { // }
- Сокращенное название: по возможности рекомендуется использовать S сокращенное название при условии, что оно будет легко понять любому, кто впервые читает код. Чем шире сфера использования, тем больше она должна быть описательной.
pid // Bad (does it refer to podID or personID or productID?) spec // good (refers to Specification) addr // good (refers to Address)
Уникальные имена
Речь идет о сокращениях, таких как API, HTTP, и т. Д. , или именах, таких как ID и DB. Обычно мы сохраняем эти слова в их исходной форме. :
userID
вместоuserId
productAPI
вместоproductApi
Длина линии
В Go нет фиксированной длины строки, но всегда рекомендуется избегать длинных строк.
Заключение
Я попытался обобщить общие правила именования в Go, а также то, когда и в какой степени мы можем их применять. Я также объяснил основную идею укороченного именования в Go: найти баланс между краткостью и наглядностью.
Условные обозначения призваны направлять вас, а не мешать. Так что вы должны чувствовать себя комфортно, ломая их всякий раз, когда это кажется уместным и по-прежнему служит общей цели.