Эффективный GO. Имена
Имена так же важны в Go, как и в любом другом языке. Они даже имеют семантический эффект: видимость имени вне пакета определяется тем, является ли его первый символ заглавным. Поэтому стоит потратить немного времени на обсуждение соглашений об именах в программах Go.
Имена пакетов
Когда пакет импортируется, имя пакета становится средством доступа к содержимому.
пакет импорта может говорить о 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