Go
June 12, 2023

Эффективный GO. Имена

Имена так же важны в Go, как и в любом другом языке. Они даже имеют семантический эффект: видимость имени вне пакета определяется тем, является ли его первый символ заглавным. Поэтому стоит потратить немного времени на обсуждение соглашений об именах в программах Go.

Имена пакетов

Когда пакет импортируется, имя пакета становится средством доступа к содержимому.

import "bytes"

пакет импорта может говорить о bytes.Buffer. Полезно, если каждый, кто использует пакет, может использовать одно и то же имя для ссылки на его содержимое, что означает, что имя пакета должно быть хорошим: коротким, лаконичным, запоминающимся. Следуя соглашению имена пакетам даются из одного слова в нижнем регистре; не должно быть необходимости в символах подчеркивания или смешанных заглавных буквах. Err ради краткости, так как каждый, кто использует ваш пакет, будет вводить это имя. И не беспокойтесь о коллизиях априори. Имя пакета является только именем по умолчанию для импорта; оно не обязательно должно быть уникальным для всего исходного кода, и в редких случаях конфликта импортирующий пакет может выбрать другое имя для локального использования. В любом случае путаница возникает редко, потому что имя файла в импорте определяет, какой именно пакет используется.

Другое соглашение заключается в том, что имя пакета является базовым именем его исходного каталога; пакет в src/encoding/base64 импортируется как "encoding/base64", но имеет имя base64, а не encoding_base64 и не encodingBase64.

Тот кто импортирует пакет будет использовать имя для ссылки на его содержимое, поэтому экспортируемые имена в пакете могут использовать этот факт, чтобы избежать повторения. (Не используйте нотацию import ., которая может упростить тесты, которые должны выполняться вне тестируемого пакета, но в противном случае лучше их избегать.) Например, тип для чтения буффера в пакете bufio называется Reader, а не BufReader, потому что пользователи видят его как bufio.Reader, что является четким и лаконичным именем. Кроме того, поскольку импортированные сущности всегда адресуются по имени пакета, тоbufio.Reader не конфликтует с io.Reader. Точно так же функция создания новых экземпляров дляring.Ring — определение конструктора в Go — обычно называется NewRing, но поскольку Ring — единственный тип, экспортируемый пакетом, а пакет называется ring, то называется просто New, которую пользователи пакета видят как ring.New. Используйте структуру пакета, чтобы выбирать хорошие имена.

Еще один короткий пример: Once.Do; Once.Do(setup) читается хорошо, и его нельзя улучшить, написав Once.DoOrWaitUntilDone(setup). Длинные имена автоматически не улучшают читабельность. Полезный комментарий к документу часто может быть более ценным, чем очень длинное имя.

Геттеры

Go не обеспечивает автоматическую поддержку геттеров и сеттеров. Нет ничего плохого в том, чтобы рализовать геттеры и сеттеры самостоятельно, и часто это уместно, и здесь нет идиоматичности и необходимости включать Get в имя геттера. Если у вас есть поле с именем owner (нижний регистр, неэкспортируемое), метод получения может называться Owner (верхний регистр, экспортируемое), а не GetOwner. Использование имен в верхнем регистре для экспорта позволяет отличить поле от метода. Функция сеттер, при необходимости, скорее всего, будет называться SetOwner. Оба имени хорошо читаются на практике:

owner := obj.Owner()
if owner != user {
    obj.SetOwner(user)
}

Имена интерфейсов

По соглашению, интерфейсы с одним методом именуются по имени метода плюс суффикс -er или аналогичной модификацией для создания существительного агента: Reader, Writer, Formatter, CloseNotifier и т. д.

Есть несколько имен, и целесообразно учитывать их и имена их функций, которые они предоставляют. Например Read, Write, Close, Flush, String и т. п. имеют канонические сигнатуры и значения. Во избежание путаницы не давайте вашему методу одно из этих имен, если только оно не имеет такую же сигнатуру и значение. И наоборот, если ваш тип реализует метод с тем же значением, что и метод известного типа, дайте ему такое же имя и сигнатуру; назовите метод преобразования строк String, а не ToString.

MixedCaps

И наконец, соглашение Go о том, чтобы использовать MixedCaps или mixedCaps для написания имен состоящих из нескольких слов, вместо символов подчеркивания.

Источник: https://go.dev/doc/effective_go#names