Писаные и неписаные правила

В информатике есть только две сложные вещи: инвалидация кеша и именование вещей. - Фил Карлтон

Это не смешная шутка. Писать легко, но читать больно. Вы когда-нибудь задумывались, к чему относится определенная переменная или какова цель определенного пакета? Что ж, вот почему нам нужны правила и условности.

Но хотя условности призваны облегчить жизнь, их можно переоценить и неправильно использовать . Очень важно установить соглашения и правила для именования, но слепое следование им может быть вредным.

В этой статье я рассмотрю некоторые важные соглашения об именах переменных в 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: найти баланс между краткостью и наглядностью.

Условные обозначения призваны направлять вас, а не мешать. Так что вы должны чувствовать себя комфортно, ломая их всякий раз, когда это кажется уместным и по-прежнему служит общей цели.