summaryrefslogtreecommitdiff
path: root/content/pages/gostyleguide/google/decisions.md
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--content/pages/gostyleguide/google/decisions.md800
1 files changed, 381 insertions, 419 deletions
diff --git a/content/pages/gostyleguide/google/decisions.md b/content/pages/gostyleguide/google/decisions.md
index acb17b7..adce93d 100644
--- a/content/pages/gostyleguide/google/decisions.md
+++ b/content/pages/gostyleguide/google/decisions.md
@@ -1,16 +1,12 @@
---
-order: 2
-title: Google Go Style Guide — Решения
+weight: 20
+title: Решения
---
# Решения по стилю Go
Оригинал: https://google.github.io/styleguide/go/decisions
-[Обзор](https://neonxp.ru/pages/gostyleguide/google/) | [Руководство](https://neonxp.ru/pages/gostyleguide/google/guide) | [Решения](https://neonxp.ru/pages/gostyleguide/google/decisions) |
-[Лучшие практики](https://neonxp.ru/pages/gostyleguide/google/best-practices)
-
-
**Примечание:** Это часть серии документов, описывающих [Стиль Go](https://neonxp.ru/pages/gostyleguide/google/) в
Google. Этот документ является **[нормативным](https://neonxp.ru/pages/gostyleguide/google/#normative), но не
[каноническим](https://neonxp.ru/pages/gostyleguide/google/#canonical)** и подчиняется [основному руководству по
@@ -35,21 +31,21 @@ Google. Этот документ является **[нормативным](ht
Следующие разделы были перемещены из "Решений по стилю" в другие части
руководства:
-* **MixedCaps**: см. [guide#mixed-caps](https://neonxp.ru/pages/gostyleguide/google/guide/#mixed-caps) <a
- id="mixed-caps"></a>
+- **MixedCaps**: см. [guide#mixed-caps](https://neonxp.ru/pages/gostyleguide/google/guide/#mixed-caps) <a
+ id="mixed-caps"></a>
-* **Форматирование**: см. [guide#formatting](https://neonxp.ru/pages/gostyleguide/google/guide/#formatting) <a
- id="formatting"></a>
+- **Форматирование**: см. [guide#formatting](https://neonxp.ru/pages/gostyleguide/google/guide/#formatting) <a
+ id="formatting"></a>
-* **Длина строки**: см. [guide#line-length](https://neonxp.ru/pages/gostyleguide/google/guide/#line-length) <a
- id="line-length"></a>
+- **Длина строки**: см. [guide#line-length](https://neonxp.ru/pages/gostyleguide/google/guide/#line-length) <a
+ id="line-length"></a>
<a id="naming"></a>
## Именование
Общие рекомендации по именованию см. в разделе об именовании в [основном
-руководстве по стилю](https://neonxp.ru/pages/gostyleguide/google/guide/#naming). Следующие разделы дают дальнейшие
+руководстве по стилю](https://neonxp.ru/pages/gostyleguide/google/guide/#naming). Следующие разделы дают дальнейшие
разъяснения по конкретным областям именования.
<a id="underscores"></a>
@@ -98,18 +94,18 @@ Google. Этот документ является **[нормативным](ht
сгенерированным кодом, могут содержать подчеркивания. Конкретные примеры
включают:
-* Использование суффикса `_test` для модульных тестов, проверяющих только
- экспортированный API пакета (пакет `testing` называет это ["черным
- ящиком"](https://pkg.go.dev/testing)). Например, пакет `linkedlist` должен
- определять свои модульные тесты "черного ящика" в пакете с именем
- `linkedlist_test` (не `linked_list_test`)
+- Использование суффикса `_test` для модульных тестов, проверяющих только
+ экспортированный API пакета (пакет `testing` называет это ["черным
+ ящиком"](https://pkg.go.dev/testing)). Например, пакет `linkedlist` должен
+ определять свои модульные тесты "черного ящика" в пакете с именем
+ `linkedlist_test` (не `linked_list_test`)
-* Использование подчеркиваний и суффикса `_test` для пакетов, содержащих
- функциональные или интеграционные тесты. Например, интеграционный тест
- сервиса связного списка может называться `linked_list_service_test`
+- Использование подчеркиваний и суффикса `_test` для пакетов, содержащих
+ функциональные или интеграционные тесты. Например, интеграционный тест
+ сервиса связного списка может называться `linked_list_service_test`
-* Использование суффикса `_test` для [примеров документации на уровне
- пакета](https://go.dev/blog/examples)
+- Использование суффикса `_test` для [примеров документации на уровне
+ пакета](https://go.dev/blog/examples)
[`tabwriter`]: https://pkg.go.dev/text/tabwriter
[`k8s`]: https://pkg.go.dev/k8s.io/client-go/kubernetes
@@ -120,17 +116,17 @@ Google. Этот документ является **[нормативным](ht
`helper`, `model`, `testhelper` и т.д., которые могут побуждать пользователей
пакета [переименовывать его при импорте](#import-renaming). См.:
-* [Рекомендации по так называемым "служебным
- пакетам"](https://neonxp.ru/pages/gostyleguide/google/best-practices/#util-packages)
-* [Go Tip #97: Что в
- имени](https://google.github.io/styleguide/go/index.html#gotip)
-* [Go Tip #108: Сила хорошего имени
- пакета](https://google.github.io/styleguide/go/index.html#gotip)
+- [Рекомендации по так называемым "служебным
+ пакетам"](https://neonxp.ru/pages/gostyleguide/google/best-practices/#util-packages)
+- [Go Tip #97: Что в
+ имени](/pages/gostyleguide/google/index.html#gotip)
+- [Go Tip #108: Сила хорошего имени
+ пакета](/pages/gostyleguide/google/index.html#gotip)
Когда импортированный пакет переименовывается (например, `import foopb
"path/to/foo_go_proto"`), локальное имя пакета должно соответствовать правилам
выше, так как локальное имя определяет, как на символы в пакете ссылаются в
-файле. Если данный импорт переименован в нескольких файлах, особенно в одном и
+файле. Если данный импорт переименован в нескольких файлах, особенно в одном и
том же или соседних пакетах, по возможности следует использовать одно и то же
локальное имя для согласованности.
@@ -147,16 +143,16 @@ Google. Этот документ является **[нормативным](ht
Имена [получателей] (receiver) должны быть:
-* Краткими (обычно одна или две буквы)
-* Сокращениями для самого типа
-* Применяться последовательно для каждого получателя этого типа
+- Краткими (обычно одна или две буквы)
+- Сокращениями для самого типа
+- Применяться последовательно для каждого получателя этого типа
-Длинное имя | Лучшее имя
------------------------------ | -------------------------
-`func (tray Tray)` | `func (t Tray)`
-`func (info *ResearchInfo)` | `func (ri *ResearchInfo)`
-`func (this *ReportWriter)` | `func (w *ReportWriter)`
-`func (self *Scanner)` | `func (s *Scanner)`
+| Длинное имя | Лучшее имя |
+| --------------------------- | ------------------------- |
+| `func (tray Tray)` | `func (t Tray)` |
+| `func (info *ResearchInfo)` | `func (ri *ResearchInfo)` |
+| `func (this *ReportWriter)` | `func (w *ReportWriter)` |
+| `func (self *Scanner)` | `func (s *Scanner)` |
[получателей]: https://golang.org/ref/spec#Method_declarations
@@ -221,35 +217,34 @@ const (
правило, идентификаторы (например, `ID` и `DB`) также должны быть написаны с
заглавной буквы, аналогично их использованию в английской прозе.
-* В именах с несколькими аббревиатурами (например, `XMLAPI`, потому что оно
- содержит `XML` и `API`) каждая буква в данной аббревиатуре должна иметь один
- регистр, но каждая аббревиатура в имени не обязана иметь одинаковый регистр.
-* В именах с аббревиатурой, содержащей строчную букву (например, `DDoS`,
- `iOS`, `gRPC`), аббревиатура должна отображаться, как в стандартной прозе,
- если только вам не нужно изменить первую букву ради [экспортируемости
- (exportedness)]. В этих случаях вся аббревиатура должна быть в одном
- регистре (например, `ddos`, `IOS`, `GRPC`).
+- В именах с несколькими аббревиатурами (например, `XMLAPI`, потому что оно
+ содержит `XML` и `API`) каждая буква в данной аббревиатуре должна иметь один
+ регистр, но каждая аббревиатура в имени не обязана иметь одинаковый регистр.
+- В именах с аббревиатурой, содержащей строчную букву (например, `DDoS`,
+ `iOS`, `gRPC`), аббревиатура должна отображаться, как в стандартной прозе,
+ если только вам не нужно изменить первую букву ради [экспортируемости
+ (exportedness)]. В этих случаях вся аббревиатура должна быть в одном
+ регистре (например, `ddos`, `IOS`, `GRPC`).
-[экспортируемости (exportedness)]:
- https://golang.org/ref/spec#Exported_identifiers
+[экспортируемости (exportedness)]: https://golang.org/ref/spec#Exported_identifiers
<!-- Keep this table narrow. If it must grow wider, replace with a list. -->
-Использование в английском | Область видимости | Правильно | Неправильно
--------------------------- | ----------------- | --------- | --------------------------------------
-XML API | Экспортировано | `XMLAPI` | `XmlApi`, `XMLApi`, `XmlAPI`, `XMLapi`
-XML API | Не экспортировано | `xmlAPI` | `xmlapi`, `xmlApi`
-iOS | Экспортировано | `IOS` | `Ios`, `IoS`
-iOS | Не экспортировано | `iOS` | `ios`
-gRPC | Экспортировано | `GRPC` | `Grpc`
-gRPC | Не экспортировано | `gRPC` | `grpc`
-DDoS | Экспортировано | `DDoS` | `DDOS`, `Ddos`
-DDoS | Не экспортировано | `ddos` | `dDoS`, `dDOS`
-ID | Экспортировано | `ID` | `Id`
-ID | Не экспортировано | `id` | `iD`
-DB | Экспортировано | `DB` | `Db`
-DB | Не экспортировано | `db` | `dB`
-Txn | Экспортировано | `Txn` | `TXN`
+| Использование в английском | Область видимости | Правильно | Неправильно |
+| -------------------------- | ----------------- | --------- | -------------------------------------- |
+| XML API | Экспортировано | `XMLAPI` | `XmlApi`, `XMLApi`, `XmlAPI`, `XMLapi` |
+| XML API | Не экспортировано | `xmlAPI` | `xmlapi`, `xmlApi` |
+| iOS | Экспортировано | `IOS` | `Ios`, `IoS` |
+| iOS | Не экспортировано | `iOS` | `ios` |
+| gRPC | Экспортировано | `GRPC` | `Grpc` |
+| gRPC | Не экспортировано | `gRPC` | `grpc` |
+| DDoS | Экспортировано | `DDoS` | `DDOS`, `Ddos` |
+| DDoS | Не экспортировано | `ddos` | `dDoS`, `dDOS` |
+| ID | Экспортировано | `ID` | `Id` |
+| ID | Не экспортировано | `id` | `iD` |
+| DB | Экспортировано | `DB` | `Db` |
+| DB | Не экспортировано | `db` | `dB` |
+| Txn | Экспортировано | `Txn` | `TXN` |
<!--#include file="/go/g3doc/style/includes/special-name-exception.md"-->
@@ -289,14 +284,14 @@ Txn | Экспортировано | `Txn` | `TXN`
строгими правилами. Применяйте суждение, основанное на контексте, [ясности] и
[лаконичности].
-* Малая область видимости — это область, в которой выполняется одна или две
- небольшие операции, скажем, 1-7 строк.
-* Средняя область видимости — это несколько небольших или одна большая
- операция, скажем, 8-15 строк.
-* Большая область видимости — это одна или несколько больших операций, скажем,
- 15-25 строк.
-* Очень большая область видимости — это все, что занимает больше страницы
- (скажем, более 25 строк).
+- Малая область видимости — это область, в которой выполняется одна или две
+ небольшие операции, скажем, 1-7 строк.
+- Средняя область видимости — это несколько небольших или одна большая
+ операция, скажем, 8-15 строк.
+- Большая область видимости — это одна или несколько больших операций, скажем,
+ 15-25 строк.
+- Очень большая область видимости — это все, что занимает больше страницы
+ (скажем, более 25 строк).
[ясности]: guide#clarity
[лаконичности]: guide#concision
@@ -323,21 +318,21 @@ Txn | Экспортировано | `Txn` | `TXN`
В общем:
-* Однобуквенные имена, такие как `count` или `options`, — хорошая отправная
- точка.
-* Дополнительные слова могут быть добавлены для различения похожих имен,
- например `userCount` и `projectCount`.
-* Не просто выбрасывайте буквы, чтобы сэкономить на печати. Например,
- `Sandbox` предпочтительнее, чем `Sbx`, особенно для экспортируемых имен.
-* Опускайте [типы и слова, похожие на типы] из большинства имен переменных.
- * Для числа `userCount` — лучшее имя, чем `numUsers` или `usersInt`.
- * Для среза `users` — лучшее имя, чем `userSlice`.
- * Допустимо включать квалификатор, похожий на тип, если в области
- видимости есть две версии значения, например, у вас может быть ввод,
- сохраненный в `ageString`, и `age` для распарсенного значения.
-* Опускайте слова, которые ясны из [окружающего контекста]. Например, в
- реализации метода `UserCount` локальная переменная с именем `userCount`,
- вероятно, избыточна; `count`, `users` или даже `c` так же читаемы.
+- Однобуквенные имена, такие как `count` или `options`, — хорошая отправная
+ точка.
+- Дополнительные слова могут быть добавлены для различения похожих имен,
+ например `userCount` и `projectCount`.
+- Не просто выбрасывайте буквы, чтобы сэкономить на печати. Например,
+ `Sandbox` предпочтительнее, чем `Sbx`, особенно для экспортируемых имен.
+- Опускайте [типы и слова, похожие на типы] из большинства имен переменных.
+ - Для числа `userCount` — лучшее имя, чем `numUsers` или `usersInt`.
+ - Для среза `users` — лучшее имя, чем `userSlice`.
+ - Допустимо включать квалификатор, похожий на тип, если в области
+ видимости есть две версии значения, например, у вас может быть ввод,
+ сохраненный в `ageString`, и `age` для распарсенного значения.
+- Опускайте слова, которые ясны из [окружающего контекста]. Например, в
+ реализации метода `UserCount` локальная переменная с именем `userCount`,
+ вероятно, избыточна; `count`, `users` или даже `c` так же читаемы.
[типы и слова, похожие на типы]: #repetitive-with-type
[окружающего контекста]: #repetitive-in-context
@@ -353,17 +348,17 @@ Txn | Экспортировано | `Txn` | `TXN`
В общем:
-* Для [переменной-получателя метода] предпочтительно одно- или двухбуквенное
- имя.
-* Использование знакомых имен переменных для распространенных типов часто
- полезно:
- * `r` для `io.Reader` или `*http.Request`
- * `w` для `io.Writer` или `http.ResponseWriter`
-* Однобуквенные идентификаторы допустимы в качестве целочисленных переменных
- цикла, особенно для индексов (например, `i`) и координат (например, `x` и
- `y`).
-* Сокращения могут быть допустимыми идентификаторами цикла, если область
- видимости короткая, например `for _, n := range nodes { ... }`.
+- Для [переменной-получателя метода] предпочтительно одно- или двухбуквенное
+ имя.
+- Использование знакомых имен переменных для распространенных типов часто
+ полезно:
+ - `r` для `io.Reader` или `*http.Request`
+ - `w` для `io.Writer` или `http.ResponseWriter`
+- Однобуквенные идентификаторы допустимы в качестве целочисленных переменных
+ цикла, особенно для индексов (например, `i`) и координат (например, `x` и
+ `y`).
+- Сокращения могут быть допустимыми идентификаторами цикла, если область
+ видимости короткая, например `for _, n := range nodes { ... }`.
[переменной-получателя метода]: #receiver-names
@@ -396,28 +391,28 @@ Txn | Экспортировано | `Txn` | `TXN`
> **Примеры:** Повторяющееся имя -> Лучшее имя
>
-> * `widget.NewWidget` -> `widget.New`
-> * `widget.NewWidgetWithName` -> `widget.NewWithName`
-> * `db.LoadFromDatabase` -> `db.Load`
-> * `goatteleportutil.CountGoatsTeleported` -> `gtutil.CountGoatsTeleported`
-> или `goatteleport.Count`
-> * `myteampb.MyTeamMethodRequest` -> `mtpb.MyTeamMethodRequest` или
-> `myteampb.MethodRequest`
+> - `widget.NewWidget` -> `widget.New`
+> - `widget.NewWidgetWithName` -> `widget.NewWithName`
+> - `db.LoadFromDatabase` -> `db.Load`
+> - `goatteleportutil.CountGoatsTeleported` -> `gtutil.CountGoatsTeleported`
+> или `goatteleport.Count`
+> - `myteampb.MyTeamMethodRequest` -> `mtpb.MyTeamMethodRequest` или
+> `myteampb.MethodRequest`
<a id="repetitive-with-type"></a>
#### Имя переменной vs. тип
Компилятор всегда знает тип переменной, и в большинстве случаев читателю также
-понятен тип переменной по тому, как она используется. Уточнять тип переменной
+понятен тип переменной по тому, как она используется. Уточнять тип переменной
необходимо только если ее значение появляется дважды в одной и той же области
видимости.
-Повторяющееся имя | Лучшее имя
-------------------------------- | ----------------------
-`var numUsers int` | `var users int`
-`var nameString string` | `var name string`
-`var primaryProject *Project` | `var primary *Project`
+| Повторяющееся имя | Лучшее имя |
+| ----------------------------- | ---------------------- |
+| `var numUsers int` | `var users int` |
+| `var nameString string` | `var name string` |
+| `var primaryProject *Project` | `var primary *Project` |
Если значение появляется в нескольких формах, это можно уточнить либо с помощью
дополнительного слова, например `raw` и `parsed`, либо с помощью базового
@@ -524,7 +519,7 @@ func (db *DB) UserCount() (int, error) {
Соглашения, касающиеся комментариев (что комментировать, какой стиль
использовать, как предоставлять исполняемые примеры и т.д.), предназначены для
-поддержки удобства чтения документации публичного API. Подробнее см. [Effective
+поддержки удобства чтения документации публичного API. Подробнее см. [Effective
Go](http://golang.org/doc/effective_go.html#commentary).
Раздел о [соглашениях по документации] в документе о лучших практиках
@@ -539,7 +534,7 @@ Go](http://golang.org/doc/effective_go.html#commentary).
отступа, декорации, как правило, следует избегать.
[предпросмотр документации (doc preview)]: best-practices#documentation-preview
-[соглашениям по документации]: best-practices#documentation-conventions
+[соглашениям по документации]: best-practices#documentation-conventions
<a id="comment-line-length"></a>
@@ -551,12 +546,12 @@ Go](http://golang.org/doc/effective_go.html#commentary).
несколько однострочных комментариев. По возможности стремитесь к комментариям,
которые будут хорошо читаться на терминале шириной 80 колонок, однако это не
жесткий предел; в Go нет фиксированного ограничения длины строки для
-комментариев. Стандартная библиотека, например, часто предпочитает разрывать
+комментариев. Стандартная библиотека, например, часто предпочитает разрывать
комментарий по пунктуации, что иногда оставляет отдельные строки ближе к отметке
60-70 символов.
Существует множество существующего кода, в котором комментарии превышают 80
-символов в длину. Эти рекомендации не следует использовать как оправдание для
+символов в длину. Эти рекомендации не следует использовать как оправдание для
изменения такого кода в ходе проверки на читаемость (см.
[согласованность](https://neonxp.ru/pages/gostyleguide/google/guide/#consistency)), хотя командам рекомендуется использовать
возможность обновлять комментарии в соответствии с этим руководством в рамках
@@ -566,8 +561,7 @@ Go](http://golang.org/doc/effective_go.html#commentary).
Подробнее о комментариях см. в [этом посте из блога Go о документации].
-[этом посте из блога Go о документации]:
- https://blog.golang.org/godoc-documenting-go-code
+[этом посте из блога Go о документации]: https://blog.golang.org/godoc-documenting-go-code
```text
# Хорошо:
@@ -606,7 +600,7 @@ Go](http://golang.org/doc/effective_go.html#commentary).
Все экспортируемые имена верхнего уровня должны иметь документирующие
комментарии, как и неэкспортируемые объявления типов или функций с неочевидным
поведением или смыслом. Эти комментарии должны быть [полными предложениями],
-которые начинаются с имени описываемого объекта. Артикль ("a", "an", "the")
+которые начинаются с имени описываемого объекта. Артикль ("a", "an", "the")
может предшествовать имени, чтобы оно читалось более естественно.
```go
@@ -645,7 +639,7 @@ type Options struct {
**Лучшая практика:** Если у вас есть документирующие комментарии для
неэкспортируемого кода, следуйте тому же обычаю, как если бы он был
-экспортируемым (а именно, начиная комментарий с неэкспортируемого имени). Это
+экспортируемым (а именно, начиная комментарий с неэкспортируемого имени). Это
упрощает его экспорт позже простой заменой неэкспортируемого имени на новое
экспортируемое в комментариях и коде.
@@ -701,8 +695,7 @@ type Server struct {
[исполняемый пример]: http://blog.golang.org/examples
[Godoc]: https://pkg.go.dev/time#example-Duration
-[исходный код]:
- https://cs.opensource.google/go/go/+/HEAD:src/time/example_test.go
+[исходный код]: https://cs.opensource.google/go/go/+/HEAD:src/time/example_test.go
Если предоставить исполняемый пример нецелесообразно, пример кода может быть
предоставлен внутри комментариев к коду. Как и другие фрагменты кода и командной
@@ -716,7 +709,7 @@ type Server struct {
<a id="TOC-NamedResultParameters"></a>
При именовании параметров учитывайте, как сигнатуры функций отображаются в
-Godoc. Имя самой функции и тип возвращаемых параметров часто достаточно ясны.
+Godoc. Имя самой функции и тип возвращаемых параметров часто достаточно ясны.
```go
// Хорошо:
@@ -747,7 +740,7 @@ func WithTimeout(parent Context, d time.Duration) (ctx Context, cancel func())
```
В приведенном выше коде отмена — это конкретное действие, которое должна
-выполнить вызывающая сторона. Однако, если бы возвращаемые параметры были
+выполнить вызывающая сторона. Однако, если бы возвращаемые параметры были
записаны просто как `(Context, func())`, было бы неясно, что подразумевается под
"функцией отмены".
@@ -761,13 +754,13 @@ func (n *Node) Parent2() (node *Node, err error)
```
Не называйте возвращаемые параметры, чтобы избежать объявления переменной внутри
-функции. Эта практика приводит к излишней многословности API в обмен на
+функции. Эта практика приводит к излишней многословности API в обмен на
незначительную краткость реализации.
[Голые возвраты (Naked returns)] допустимы только в маленькой функции. Как
только это функция среднего размера, будьте явны со своими возвращаемыми
значениями. Аналогично, не называйте возвращаемые параметры только потому, что
-это позволяет вам использовать голые возвраты. [Ясность](https://neonxp.ru/pages/gostyleguide/google/guide/#clarity) всегда
+это позволяет вам использовать голые возвраты. [Ясность](https://neonxp.ru/pages/gostyleguide/google/guide/#clarity) всегда
важнее, чем сэкономить несколько строк в вашей функции.
Всегда приемлемо назвать возвращаемый параметр, если его значение должно быть
@@ -781,8 +774,7 @@ func (n *Node) Parent2() (node *Node, err error)
> документирования.
[Голые возвраты (Naked returns)]: https://tour.golang.org/basics/7
-[GoTip #38: Функции как именованные типы]:
- https://google.github.io/styleguide/go/index.html#gotip
+[GoTip #38: Функции как именованные типы]: /pages/gostyleguide/google/index.html#gotip
[`WithTimeout`]: https://pkg.go.dev/context#WithTimeout
[`CancelFunc`]: https://pkg.go.dev/context#CancelFunc
@@ -832,19 +824,19 @@ package main
Советы:
-* Примеры вызовов командной строки и использования API могут быть полезной
- документацией. Для форматирования Godoc сделайте отступ для строк
- комментария, содержащих код.
+- Примеры вызовов командной строки и использования API могут быть полезной
+ документацией. Для форматирования Godoc сделайте отступ для строк
+ комментария, содержащих код.
-* Если нет очевидного основного файла или если комментарий к пакету необычайно
- длинный, допустимо поместить документирующий комментарий в файл с именем
- `doc.go`, содержащий только комментарий и объявление пакета.
+- Если нет очевидного основного файла или если комментарий к пакету необычайно
+ длинный, допустимо поместить документирующий комментарий в файл с именем
+ `doc.go`, содержащий только комментарий и объявление пакета.
-* Многострочные комментарии могут использоваться вместо нескольких
- однострочных. Это в первую очередь полезно, если документация содержит
- разделы, которые могут быть полезны для копирования и вставки из исходного
- файла, как, например, примеры командной строки (для бинарников) и примеры
- шаблонов.
+- Многострочные комментарии могут использоваться вместо нескольких
+ однострочных. Это в первую очередь полезно, если документация содержит
+ разделы, которые могут быть полезны для копирования и вставки из исходного
+ файла, как, например, примеры командной строки (для бинарников) и примеры
+ шаблонов.
```go
// Хорошо:
@@ -857,9 +849,9 @@ package main
package template
```
-* Комментарии, предназначенные для сопровождающих и относящиеся ко всему
- файлу, обычно размещаются после объявлений импорта. Они не отображаются в
- Godoc и не подчиняются приведенным выше правилам для комментариев к пакетам.
+- Комментарии, предназначенные для сопровождающих и относящиеся ко всему
+ файлу, обычно размещаются после объявлений импорта. Они не отображаются в
+ Godoc и не подчиняются приведенным выше правилам для комментариев к пакетам.
<a id="imports"></a>
@@ -880,15 +872,15 @@ package main
[последовательными](https://neonxp.ru/pages/gostyleguide/google/guide/#consistency), всегда используя одно и то же локальное
имя для одного и того же импортированного пакета.
-Импортированный пакет *должен* быть переименован, чтобы избежать конфликта имен
+Импортированный пакет _должен_ быть переименован, чтобы избежать конфликта имен
с другими импортами. (Следствие из этого: [хорошие имена
пакетов](#package-names) не должны требовать переименования.) В случае конфликта
имен предпочтительнее переименовать наиболее локальный или специфичный для
проекта импорт.
-Сгенерированные пакеты протоколов буфера *должны* быть переименованы, чтобы
+Сгенерированные пакеты протоколов буфера _должны_ быть переименованы, чтобы
удалить подчеркивания из их имен, и их локальные имена должны иметь суффикс
-`pb`. Подробнее см. [лучшие практики для proto и заглушек
+`pb`. Подробнее см. [лучшие практики для proto и заглушек
(stubs)](https://neonxp.ru/pages/gostyleguide/google/best-practices/#import-protos).
```go
@@ -898,10 +890,10 @@ import (
)
```
-Наконец, импортированный, несгенерированный пакет *может* быть переименован,
+Наконец, импортированный, несгенерированный пакет _может_ быть переименован,
если он имеет неинформативное имя (например, `util` или `v1`) Делайте это
экономно: не переименовывайте пакет, если код, окружающий использование пакета,
-передает достаточно контекста. По возможности предпочитайте рефакторинг самого
+передает достаточно контекста. По возможности предпочитайте рефакторинг самого
пакета с более подходящим именем.
```go
@@ -915,7 +907,7 @@ import (
Если вам нужно импортировать пакет, имя которого конфликтует с распространенным
локальным именем переменной, которое вы хотите использовать (например, `url`,
`ssh`), и вы хотите переименовать пакет, предпочтительный способ сделать это —
-использовать суффикс `pkg` (например, `urlpkg`). Обратите внимание, что
+использовать суффикс `pkg` (например, `urlpkg`). Обратите внимание, что
возможно затенение пакета локальной переменной; это переименование необходимо
только если пакет все еще нужно использовать, когда такая переменная находится в
области видимости.
@@ -934,7 +926,7 @@ import (
1. Импорт для [побочных эффектов (side
effects)](https://go.dev/doc/effective_go#blank_import) (например, `_
- "path/to/package"`)
+"path/to/package"`)
```go
// Хорошо:
@@ -968,9 +960,9 @@ import (
Некоторые примеры таких пакетов:
-* [time/tzdata](https://pkg.go.dev/time/tzdata)
+- [time/tzdata](https://pkg.go.dev/time/tzdata)
-* [image/jpeg](https://pkg.go.dev/image/jpeg) в коде обработки изображений
+- [image/jpeg](https://pkg.go.dev/image/jpeg) в коде обработки изображений
Избегайте пустых импортов в библиотечных пакетах, даже если библиотека косвенно
зависит от них. Ограничение импортов с побочными эффектами главным пакетом
@@ -979,19 +971,18 @@ import (
Следующие исключения являются единственными для этого правила:
-* Вы можете использовать пустой импорт, чтобы обойти проверку на запрещенные
- импорты в [статическом анализаторе nogo].
+- Вы можете использовать пустой импорт, чтобы обойти проверку на запрещенные
+ импорты в [статическом анализаторе nogo].
-* Вы можете использовать пустой импорт пакета
- [embed](https://pkg.go.dev/embed) в исходном файле, который использует
- директиву компилятора `//go:embed`.
+- Вы можете использовать пустой импорт пакета
+ [embed](https://pkg.go.dev/embed) в исходном файле, который использует
+ директиву компилятора `//go:embed`.
**Совет:** Если вы создаете библиотечный пакет, который косвенно зависит от
импорта с побочным эффектом в продакшене, задокументируйте предполагаемое
использование.
-[статическом анализаторе nogo]:
- https://github.com/bazelbuild/rules_go/blob/master/go/nogo.rst
+[статическом анализаторе nogo]: https://github.com/bazelbuild/rules_go/blob/master/go/nogo.rst
<a id="import-dot"></a>
@@ -1001,7 +992,7 @@ import (
Форма `import .` — это языковая возможность, позволяющая переносить
идентификаторы, экспортированные из другого пакета, в текущий пакет без
-квалификации. Подробнее см. [спецификацию
+квалификации. Подробнее см. [спецификацию
языка](https://go.dev/ref/spec#Import_declarations).
Не **используйте** эту возможность в кодовой базе Google; это затрудняет
@@ -1068,9 +1059,9 @@ func GoodLookup() (*Result, error) {
```
Экспортируемые функции, возвращающие ошибки, должны возвращать их, используя тип
-`error`. Конкретные типы ошибок подвержены тонким ошибкам: конкретный `nil`
+`error`. Конкретные типы ошибок подвержены тонким ошибкам: конкретный `nil`
указатель может быть завернут в интерфейс и таким образом стать ненулевым
-значением (см. [FAQ по Go на эту тему][nil error]).
+значением (см. [FAQ по Go на эту тему][nil error]).
```go
// Плохо:
@@ -1123,13 +1114,13 @@ t.Errorf("Op(%q) failed unexpectedly; err=%v", args, err)
Код, который сталкивается с ошибкой, должен принять осознанное решение о том,
как ее обработать. Обычно нецелесообразно отбрасывать ошибки, используя
-переменные `_`. Если функция возвращает ошибку, сделайте одно из следующих
+переменные `_`. Если функция возвращает ошибку, сделайте одно из следующих
действий:
-* Обработайте и исправьте ошибку немедленно.
-* Верните ошибку вызывающей стороне.
-* В исключительных ситуациях вызовите [`log.Fatal`] или (если абсолютно
- необходимо) `panic`.
+- Обработайте и исправьте ошибку немедленно.
+- Верните ошибку вызывающей стороне.
+- В исключительных ситуациях вызовите [`log.Fatal`] или (если абсолютно
+ необходимо) `panic`.
**Примечание:** `log.Fatalf` здесь не из стандартной библиотеки log. См.
[#logging].
@@ -1146,7 +1137,7 @@ var b *bytes.Buffer
n, _ := b.Write(p) // никогда не возвращает ненулевую ошибку
```
-Для дальнейшего обсуждения и примеров обработки ошибок см. [Effective
+Для дальнейшего обсуждения и примеров обработки ошибок см. [Effective
Go](http://golang.org/doc/effective_go.html#errors) и [лучшие
практики](https://neonxp.ru/pages/gostyleguide/google/best-practices/.md#error-handling).
@@ -1179,7 +1170,7 @@ return Parse(Lookup(missingKey))
```
Поддержка Go нескольких возвращаемых значений предоставляет лучшее решение (см.
-[раздел Effective Go о множественных возвращаемых значениях]). Вместо того
+[раздел Effective Go о множественных возвращаемых значениях]). Вместо того
чтобы требовать от клиентов проверять значение ошибки "в потоке", функция должна
возвращать дополнительное значение, чтобы указать, являются ли ее другие
возвращаемые значения валидными. Это возвращаемое значение может быть ошибкой
@@ -1209,13 +1200,12 @@ return Parse(value)
```
Некоторые функции стандартной библиотеки, например в пакете `strings`,
-возвращают значения ошибок "в потоке". Это значительно упрощает код для
+возвращают значения ошибок "в потоке". Это значительно упрощает код для
манипуляций со строками за счет необходимости большей внимательности от
программиста. В целом, код Go в кодовой базе Google должен возвращать
дополнительные значения для ошибок.
-[раздел Effective Go о множественных возвращаемых значениях]:
- http://golang.org/doc/effective_go.html#multiple-returns
+[раздел Effective Go о множественных возвращаемых значениях]: http://golang.org/doc/effective_go.html#multiple-returns
<a id="indent-error-flow"></a>
@@ -1280,8 +1270,7 @@ if err != nil {
Complexity by Reducing
Nesting](https://testing.googleblog.com/2017/06/code-health-reduce-nesting-reduce.html).
-[Go Tip #1: Линия видимости (Line of Sight)]:
- https://google.github.io/styleguide/go/index.html#gotip
+[Go Tip #1: Линия видимости (Line of Sight)]: /pages/gostyleguide/google/index.html#gotip
<a id="language"></a>
@@ -1298,8 +1287,7 @@ Go обладает исключительно мощным [синтаксис
довольно хорошее, но существуют некоторые дополнительные правила для сохранения
читаемости и поддерживаемости этих литералов.
-[синтаксисом составных литералов]:
- https://golang.org/ref/spec#Composite_literals
+[синтаксисом составных литералов]: https://golang.org/ref/spec#Composite_literals
<a id="literal-field-names"></a>
@@ -1308,7 +1296,7 @@ Go обладает исключительно мощным [синтаксис
Литералы структур должны указывать **имена полей** для типов, определенных вне
текущего пакета.
-* Включайте имена полей для типов из других пакетов.
+- Включайте имена полей для типов из других пакетов.
```go
// Хорошо:
@@ -1330,7 +1318,7 @@ Go обладает исключительно мощным [синтаксис
r := csv.Reader{',', '#', 4, false, false, false, false}
```
-* Для локальных типов пакета имена полей не обязательны.
+- Для локальных типов пакета имена полей не обязательны.
```go
// Хорошо:
@@ -1342,7 +1330,7 @@ Go обладает исключительно мощным [синтаксис
очень распространено. Например, структуру с большим количеством полей почти
всегда следует инициализировать с указанием имен полей.
- <!-- TODO: Maybe a better example here that doesn't have many fields. -->
+ <!-- TODO: Maybe a better example here that doesn't have many fields. -->
```go
// Хорошо:
@@ -1406,9 +1394,9 @@ bad := []*Type{
литералов срезов и массивов допустимо только когда оба следующих условия
истинны.
-* [Отступы совпадают](#literal-matching-braces)
-* Внутренние значения также являются литералами или сборщиками protobuf (то
- есть не переменной или другим выражением)
+- [Отступы совпадают](#literal-matching-braces)
+- Внутренние значения также являются литералами или сборщиками protobuf (то
+ есть не переменной или другим выражением)
```go
// Хорошо:
@@ -1557,7 +1545,7 @@ ldb := leveldb.Open("/my/table", &db.Options{
когда тестовая структура нетривиальна. Это позволяет автору опускать поля с
нулевыми значениями полностью, когда рассматриваемые поля не относятся к
тестовому случаю. Например, успешные тестовые случаи должны опускать любые поля,
-связанные с ошибками или неудачами. В случаях, когда нулевое значение
+связанные с ошибками или неудачами. В случаях, когда нулевое значение
необходимо для понимания тестового случая, таких как тестирование нулевых или
`nil` входных данных, имена полей должны быть указаны.
@@ -1724,9 +1712,9 @@ if longCondition1 && longCondition2 &&
См. следующие разделы для конкретных рекомендаций и примеров:
-* [Форматирование функций](#func-formatting)
-* [Условные операторы и циклы](#conditional-formatting)
-* [Форматирование литералов](#literal-formatting)
+- [Форматирование функций](#func-formatting)
+- [Условные операторы и циклы](#conditional-formatting)
+- [Форматирование литералов](#literal-formatting)
<a id="func-formatting"></a>
@@ -1776,7 +1764,7 @@ bad := foo.Call(long, list, of, parameters,
```
По возможности избегайте добавления встроенных комментариев к конкретным
-аргументам функций. Вместо этого используйте [структуру опций (option
+аргументам функций. Вместо этого используйте [структуру опций (option
struct)](https://neonxp.ru/pages/gostyleguide/google/best-practices/#option-structure) или добавьте больше деталей в
документацию функции.
@@ -1814,9 +1802,9 @@ canvas.RenderHeptagon(fillColor,
определенную границу столбца, а группируются на основе координат вершин и цвета.
Длинные строковые литералы внутри функций не должны разбиваться ради длины
-строки. Для функций, включающих такие строки, разрыв строки можно добавить
+строки. Для функций, включающих такие строки, разрыв строки можно добавить
после формата строки, а аргументы могут быть предоставлены на следующей или
-последующих строках. Решение о том, где должны быть разрывы строк, лучше всего
+последующих строках. Решение о том, где должны быть разрывы строк, лучше всего
принимать на основе семантических групп входных данных, а не исключительно на
основе длины строки.
@@ -2206,13 +2194,13 @@ ch <- 13 // panic
произвольное время может привести к непредсказуемому использованию памяти.
Параллельный код должен быть написан так, чтобы время жизни горутин было
-очевидным. Обычно это означает сохранение кода, связанного с синхронизацией, в
+очевидным. Обычно это означает сохранение кода, связанного с синхронизацией, в
пределах области видимости функции и вынесение логики в [синхронные функции].
Если параллелизм все еще не очевиден, важно задокументировать, когда и почему
горутины завершаются.
Код, следующий лучшим практикам использования контекста, часто помогает
-прояснить это. Обычно это управляется с помощью [`context.Context`]:
+прояснить это. Обычно это управляется с помощью [`context.Context`]:
```go
// Хорошо:
@@ -2255,31 +2243,28 @@ func (w *Worker) Run() {
Этот код может выглядеть нормально, но у него есть несколько скрытых проблем:
-* Код, вероятно, имеет неопределенное поведение в продакшене, и программа
- может не завершиться чисто, даже если операционная система освободит
- ресурсы.
+- Код, вероятно, имеет неопределенное поведение в продакшене, и программа
+ может не завершиться чисто, даже если операционная система освободит
+ ресурсы.
-* Код трудно осмысленно протестировать из-за неопределенного жизненного цикла.
+- Код трудно осмысленно протестировать из-за неопределенного жизненного цикла.
-* Код может подтекать ресурсами, как описано выше.
+- Код может подтекать ресурсами, как описано выше.
См. также:
-* [Никогда не запускайте горутину, не зная, как она остановится][cheney-stop]
-* Переосмысление классических паттернов параллелизма:
- [слайды][rethinking-slides], [видео][rethinking-video]
-* [Когда программы на Go завершаются]
-* [Соглашения по документации: Контексты]
+- [Никогда не запускайте горутину, не зная, как она остановится][cheney-stop]
+- Переосмысление классических паттернов параллелизма:
+ [слайды][rethinking-slides], [видео][rethinking-video]
+- [Когда программы на Go завершаются]
+- [Соглашения по документации: Контексты]
[синхронные функции]: #synchronous-functions
-[cheney-stop]:
- https://dave.cheney.net/2016/12/22/never-start-a-goroutine-without-knowing-how-it-will-stop
-[rethinking-slides]:
- https://drive.google.com/file/d/1nPdvhB0PutEJzdCq5ms6UI58dp50fcAN/view
+[cheney-stop]: https://dave.cheney.net/2016/12/22/never-start-a-goroutine-without-knowing-how-it-will-stop
+[rethinking-slides]: https://drive.google.com/file/d/1nPdvhB0PutEJzdCq5ms6UI58dp50fcAN/view
[rethinking-video]: https://www.youtube.com/watch?v=5zXAHh5tJqQ
[Когда программы на Go завершаются]: https://changelog.com/gotime/165
-[Соглашения по документации: Контексты]:
- best-practices.md#documentation-conventions-contexts
+[Соглашения по документации: Контексты]: best-practices.md#documentation-conventions-contexts
<a id="interfaces"></a>
@@ -2287,9 +2272,9 @@ func (w *Worker) Run() {
<a id="TOC-Interfaces"></a>
-Интерфейсы Go обычно принадлежат пакету, который *потребляет* значения типа
-интерфейса, а не пакету, который *реализует* тип интерфейса. Реализующий пакет
-должен возвращать конкретные (обычно указатель или структура) типы. Таким
+Интерфейсы Go обычно принадлежат пакету, который _потребляет_ значения типа
+интерфейса, а не пакету, который _реализует_ тип интерфейса. Реализующий пакет
+должен возвращать конкретные (обычно указатель или структура) типы. Таким
образом, новые методы могут быть добавлены к реализациям без необходимости
обширного рефакторинга. Подробнее см. [GoTip #49: Принимайте интерфейсы,
возвращайте конкретные типы].
@@ -2297,7 +2282,7 @@ func (w *Worker) Run() {
Не экспортируйте [тестовый дубль (test double)][double types] реализации
интерфейса из API, который его потребляет. Вместо этого спроектируйте API так,
чтобы его можно было тестировать с помощью [публичного API] [реальной
-реализации]. См. [GoTip #42: Создание заглушки для тестирования] для
+реализации]. См. [GoTip #42: Создание заглушки для тестирования] для
подробностей. Даже когда нецелесообразно использовать реальную реализацию, может
не потребоваться вводить интерфейс, полностью покрывающий все методы в реальном
типе; потребитель может создать интерфейс, содержащий только нужные ему методы,
@@ -2308,7 +2293,7 @@ func (w *Worker) Run() {
внутренняя практика Google — получить реальное клиентское соединение с локальным
[тестовым дублем] с использованием внутреннего пакета rpctest (скоро будет!).
-Не определяйте интерфейсы до того, как они используются (см. [TotT: Code
+Не определяйте интерфейсы до того, как они используются (см. [TotT: Code
Health: Eliminate YAGNI Smells][tott-438] ). Без реалистичного примера
использования слишком сложно увидеть, нужен ли интерфейс вообще, не говоря уже о
том, какие методы он должен содержать.
@@ -2321,21 +2306,14 @@ Health: Eliminate YAGNI Smells][tott-438] ). Без реалистичного
**TODO:** Написать более подробный документ об интерфейсах и дать на него ссылку
здесь.
-[GoTip #42: Создание заглушки для тестирования]:
- https://google.github.io/styleguide/go/index.html#gotip
-[GoTip #49: Принимайте интерфейсы, возвращайте конкретные типы]:
- https://google.github.io/styleguide/go/index.html#gotip
-[GoTip #78: Минимально жизнеспособные интерфейсы]:
- https://google.github.io/styleguide/go/index.html#gotip
+[GoTip #42: Создание заглушки для тестирования]: /pages/gostyleguide/google/index.html#gotip
+[GoTip #49: Принимайте интерфейсы, возвращайте конкретные типы]: /pages/gostyleguide/google/index.html#gotip
+[GoTip #78: Минимально жизнеспособные интерфейсы]: /pages/gostyleguide/google/index.html#gotip
[реальной реализации]: best-practices#use-real-transports
-[публичному API]:
- https://abseil.io/resources/swe-book/html/ch12.html#test_via_public_apis
-[double types]:
- https://abseil.io/resources/swe-book/html/ch13.html#techniques_for_using_test_doubles
-[тестовым дублем]:
- https://abseil.io/resources/swe-book/html/ch13.html#basic_concepts
-[tott-438]:
- https://testing.googleblog.com/2017/08/code-health-eliminate-yagni-smells.html
+[публичному API]: https://abseil.io/resources/swe-book/html/ch12.html#test_via_public_apis
+[double types]: https://abseil.io/resources/swe-book/html/ch13.html#techniques_for_using_test_doubles
+[тестовым дублем]: https://abseil.io/resources/swe-book/html/ch13.html#basic_concepts
+[tott-438]: https://testing.googleblog.com/2017/08/code-health-eliminate-yagni-smells.html
```go
// Хорошо:
@@ -2396,39 +2374,38 @@ mechanism)](https://neonxp.ru/pages/gostyleguide/google/guide/#least-mechanism).
Не используйте дженерики только потому, что вы реализуете алгоритм или структуру
данных, которой не важен тип элементов. Если на практике инстанцируется только
один тип, начните с того, чтобы ваш код работал с этим типом без использования
-дженериков вообще. Добавить полиморфизм позже будет проще по сравнению с
+дженериков вообще. Добавить полиморфизм позже будет проще по сравнению с
удалением абстракции, которая оказывается ненужной.
Не используйте дженерики для создания предметно-ориентированных языков (DSL). В
частности, воздержитесь от введения фреймворков обработки ошибок, которые могут
значительно обременять читателей. Вместо этого предпочитайте установленные
-методы [обработки ошибок](#errors). Для тестирования особенно остерегайтесь
+методы [обработки ошибок](#errors). Для тестирования особенно остерегайтесь
введения [библиотек утверждений (assertion libraries)](#assert) или фреймворков,
которые приводят к менее полезным [сообщениям об ошибках
тестов](#useful-test-failures).
В общем:
-* [Пишите код, не проектируйте типы]. Из выступления на GopherCon от Роберта
- Грисемера и Яна Лэнса Тейлора.
-* Если у вас есть несколько типов, которые разделяют полезный объединяющий
- интерфейс, рассмотрите моделирование решения с использованием этого
- интерфейса. Дженерики могут не понадобиться.
-* В противном случае вместо того, чтобы полагаться на тип `any` и чрезмерное
- [переключение типов (type switching)](https://tour.golang.org/methods/16),
- рассмотрите дженерики.
+- [Пишите код, не проектируйте типы]. Из выступления на GopherCon от Роберта
+ Грисемера и Яна Лэнса Тейлора.
+- Если у вас есть несколько типов, которые разделяют полезный объединяющий
+ интерфейс, рассмотрите моделирование решения с использованием этого
+ интерфейса. Дженерики могут не понадобиться.
+- В противном случае вместо того, чтобы полагаться на тип `any` и чрезмерное
+ [переключение типов (type switching)](https://tour.golang.org/methods/16),
+ рассмотрите дженерики.
См. также:
-* [Использование дженериков в Go], выступление Яна Лэнса Тейлора
+- [Использование дженериков в Go], выступление Яна Лэнса Тейлора
-* [Учебник по дженерикам] на сайте Go
+- [Учебник по дженерикам] на сайте Go
[Учебник по дженерикам]: https://go.dev/doc/tutorial/generics
[Параметрами типа]: https://go.dev/design/43651-type-parameters
[Использование дженериков в Go]: https://www.youtube.com/watch?v=nr8EpUO9jhw
-[Пишите код, не проектируйте типы]:
- https://www.youtube.com/watch?v=Pa_e9EeCdy8&t=1250s
+[Пишите код, не проектируйте типы]: https://www.youtube.com/watch?v=Pa_e9EeCdy8&t=1250s
<a id="pass-values"></a>
@@ -2471,8 +2448,8 @@ mechanism)](https://neonxp.ru/pages/gostyleguide/google/guide/#least-mechanism).
Список ниже подробно описывает каждый случай:
-* Если получатель является срезом и метод не переслаивает (reslice) и не
- перераспределяет (reallocate) срез, используйте значение, а не указатель.
+- Если получатель является срезом и метод не переслаивает (reslice) и не
+ перераспределяет (reallocate) срез, используйте значение, а не указатель.
```go
// Хорошо:
@@ -2481,7 +2458,7 @@ mechanism)](https://neonxp.ru/pages/gostyleguide/google/guide/#least-mechanism).
func (b Buffer) Len() int { return len(b) }
```
-* Если методу нужно мутировать получателя, получатель должен быть указателем.
+- Если методу нужно мутировать получателя, получатель должен быть указателем.
```go
// Хорошо:
@@ -2495,9 +2472,9 @@ mechanism)](https://neonxp.ru/pages/gostyleguide/google/guide/#least-mechanism).
func (q *Queue) Push(x Item) { *q = append([]Item{x}, *q...) }
```
-* Если получатель является структурой, содержащей поля, которые [не могут быть
- безопасно скопированы](#copying), используйте получатель-указатель.
- Распространенные примеры — [`sync.Mutex`] и другие типы синхронизации.
+- Если получатель является структурой, содержащей поля, которые [не могут быть
+ безопасно скопированы](#copying), используйте получатель-указатель.
+ Распространенные примеры — [`sync.Mutex`] и другие типы синхронизации.
```go
// Хорошо:
@@ -2516,21 +2493,21 @@ mechanism)](https://neonxp.ru/pages/gostyleguide/google/guide/#least-mechanism).
**Совет:** Проверьте [Godoc] типа для информации о том, безопасно ли или
небезопасно его копировать.
-* Если получатель является "большой" структурой или массивом,
- получатель-указатель может быть более эффективным. Передача структуры
- эквивалентна передаче всех ее полей или элементов в качестве аргументов
- методу. Если это кажется слишком большим для [передачи по
- значению](#pass-values), указатель — хороший выбор.
+- Если получатель является "большой" структурой или массивом,
+ получатель-указатель может быть более эффективным. Передача структуры
+ эквивалентна передаче всех ее полей или элементов в качестве аргументов
+ методу. Если это кажется слишком большим для [передачи по
+ значению](#pass-values), указатель — хороший выбор.
-* Для методов, которые будут вызываться или выполняться параллельно с другими
- функциями, которые изменяют получателя, используйте значение, если эти
- изменения не должны быть видны вашему методу; в противном случае используйте
- указатель.
+- Для методов, которые будут вызываться или выполняться параллельно с другими
+ функциями, которые изменяют получателя, используйте значение, если эти
+ изменения не должны быть видны вашему методу; в противном случае используйте
+ указатель.
-* Если получатель является структурой или массивом, любой элемент которого
- является указателем на что-то, что может быть изменено, предпочтите
- получателя-указателя, чтобы сделать намерение изменяемости понятным для
- читателя.
+- Если получатель является структурой или массивом, любой элемент которого
+ является указателем на что-то, что может быть изменено, предпочтите
+ получателя-указателя, чтобы сделать намерение изменяемости понятным для
+ читателя.
```go
// Хорошо:
@@ -2543,8 +2520,8 @@ mechanism)](https://neonxp.ru/pages/gostyleguide/google/guide/#least-mechanism).
}
```
-* Если получатель является [встроенным типом], таким как целое число или
- строка, который не нужно изменять, используйте значение.
+- Если получатель является [встроенным типом], таким как целое число или
+ строка, который не нужно изменять, используйте значение.
```go
// Хорошо:
@@ -2553,8 +2530,8 @@ mechanism)](https://neonxp.ru/pages/gostyleguide/google/guide/#least-mechanism).
func (u User) String() { return string(u) }
```
-* Если получатель является картой (map), функцией или каналом, используйте
- значение, а не указатель.
+- Если получатель является картой (map), функцией или каналом, используйте
+ значение, а не указатель.
```go
// Хорошо:
@@ -2564,9 +2541,9 @@ mechanism)](https://neonxp.ru/pages/gostyleguide/google/guide/#least-mechanism).
func (h Header) Add(key, value string) { /* опущено */ }
```
-* Если получатель является "маленьким" массивом или структурой, которые
- естественным образом являются типом значения без изменяемых полей и без
- указателей, получатель по значению обычно является правильным выбором.
+- Если получатель является "маленьким" массивом или структурой, которые
+ естественным образом являются типом значения без изменяемых полей и без
+ указателей, получатель по значению обычно является правильным выбором.
```go
// Хорошо:
@@ -2576,7 +2553,7 @@ mechanism)](https://neonxp.ru/pages/gostyleguide/google/guide/#least-mechanism).
func (t Time) Add(d Duration) Time { /* опущено */ }
```
-* В случае сомнений используйте получатель-указатель.
+- В случае сомнений используйте получатель-указатель.
В качестве общего руководства предпочитайте, чтобы методы для типа были либо все
указательными методами, либо всеми методами по значению.
@@ -2676,8 +2653,8 @@ default:
См. также:
-* "Переосмысление классических паттернов параллелизма", выступление Брайана
- Миллса: [слайды][rethinking-slides], [видео][rethinking-video]
+- "Переосмысление классических паттернов параллелизма", выступление Брайана
+ Миллса: [слайды][rethinking-slides], [видео][rethinking-video]
<a id="type-aliases"></a>
@@ -2685,7 +2662,7 @@ default:
<a id="TOC-TypeAliases"></a>
-Используйте *определение типа*, `type T1 T2`, чтобы определить новый тип.
+Используйте _определение типа_, `type T1 T2`, чтобы определить новый тип.
Используйте [*псевдоним типа*], `type T1 = T2`, чтобы ссылаться на существующий
тип без определения нового типа. Псевдонимы типов редки; их основное
использование — помочь в переносе пакетов в новые места исходного кода. Не
@@ -2730,8 +2707,7 @@ Go 1.18 вводит тип `any` как [псевдоним] для `interface{
легко взаимозаменяем через явное преобразование. Предпочитайте использовать
`any` в новом коде.
-[псевдоним]:
- https://go.googlesource.com/proposal/+/master/design/18130-type-alias.md
+[псевдоним]: https://go.googlesource.com/proposal/+/master/design/18130-type-alias.md
## Общие библиотеки
@@ -2782,11 +2758,11 @@ var (
См. также:
-* [Tip of the Week #45: Avoid Flags, Especially in Library Code][totw-45]
-* [Go Tip #10: Configuration Structs and
- Flags](https://google.github.io/styleguide/go/index.html#gotip)
-* [Go Tip #80: Dependency Injection
- Principles](https://google.github.io/styleguide/go/index.html#gotip)
+- [Tip of the Week #45: Avoid Flags, Especially in Library Code][totw-45]
+- [Go Tip #10: Configuration Structs and
+ Flags](/pages/gostyleguide/google/index.html#gotip)
+- [Go Tip #80: Dependency Injection
+ Principles](/pages/gostyleguide/google/index.html#gotip)
[стандартного пакета `flag`]: https://golang.org/pkg/flag/
[mixed caps]: guide#mixed-caps
@@ -2813,11 +2789,11 @@ var (
См. также:
-* Лучшие практики по [логированию ошибок](https://neonxp.ru/pages/gostyleguide/google/best-practices/#error-logging) и
- [пользовательским уровням детализации (verbosity
- levels)](https://neonxp.ru/pages/gostyleguide/google/best-practices/#vlog)
-* Когда и как использовать пакет log для [остановки
- программы](https://neonxp.ru/pages/gostyleguide/google/best-practices/#checks-and-panics)
+- Лучшие практики по [логированию ошибок](https://neonxp.ru/pages/gostyleguide/google/best-practices/#error-logging) и
+ [пользовательским уровням детализации (verbosity
+ levels)](https://neonxp.ru/pages/gostyleguide/google/best-practices/#vlog)
+- Когда и как использовать пакет log для [остановки
+ программы](https://neonxp.ru/pages/gostyleguide/google/best-practices/#checks-and-panics)
[`log`]: https://pkg.go.dev/log
[`log/slog`]: https://pkg.go.dev/log/slog
@@ -2832,7 +2808,7 @@ var (
<a id="TOC-Contexts"></a>
Значения типа [`context.Context`] несут учетные данные безопасности, информацию
-трассировки, сроки и сигналы отмены через границы API и процессов. В отличие от
+трассировки, сроки и сигналы отмены через границы API и процессов. В отличие от
C++ и Java, которые в кодовой базе Google используют локальное хранилище потоков
(thread-local storage), программы Go передают контексты явно вдоль всей цепочки
вызовов функций от входящих RPC и HTTP запросов к исходящим запросам.
@@ -2848,25 +2824,24 @@ func F(ctx context.Context /* другие аргументы */) {}
Исключения:
-* В HTTP обработчике, где контекст берется из
- [`req.Context()`](https://pkg.go.dev/net/http#Request.Context).
-* В потоковых RPC методах, где контекст берется из потока.
+- В HTTP обработчике, где контекст берется из
+ [`req.Context()`](https://pkg.go.dev/net/http#Request.Context).
+- В потоковых RPC методах, где контекст берется из потока.
Код, использующий потоковый gRPC, получает контекст из метода `Context()` в
сгенерированном типе сервера, который реализует `grpc.ServerStream`. См.
[документацию по сгенерированному коду
gRPC](https://grpc.io/docs/languages/go/generated-code/).
-* В точках входа (entrypoint functions) (см. ниже примеры таких функций)
- используйте [`context.Background()`] или, для тестов,
- [`tb.Context()`](https://pkg.go.dev/testing#TB.Context).
-
- * В бинарных целях: `main`
- * В общем коде и библиотеках: `init`
- * В тестах: `TestXXX`, `BenchmarkXXX`, `FuzzXXX`
+- В точках входа (entrypoint functions) (см. ниже примеры таких функций)
+ используйте [`context.Background()`] или, для тестов,
+ [`tb.Context()`](https://pkg.go.dev/testing#TB.Context).
+ - В бинарных целях: `main`
+ - В общем коде и библиотеках: `init`
+ - В тестах: `TestXXX`, `BenchmarkXXX`, `FuzzXXX`
> **Примечание**: Очень редко код в середине цепочки вызовов требует создания
-> базового контекста самостоятельно с помощью [`context.Background()`]. Всегда
+> базового контекста самостоятельно с помощью [`context.Background()`]. Всегда
> предпочитайте брать контекст у вашего вызывающего, если это не неправильный
> контекст.
>
@@ -2881,7 +2856,7 @@ func F(ctx context.Context /* другие аргументы */) {}
> Если вы не реализуете серверный фреймворк, вы не должны создавать контексты с
> помощью [`context.Background()`] в библиотечном коде. Вместо этого
> предпочитайте использование отсоединения контекста (context detachment),
-> которое упоминается ниже, если доступен существующий контекст. Если вы
+> которое упоминается ниже, если доступен существующий контекст. Если вы
> думаете, что вам действительно нужно [`context.Background()`] вне функций
> точек входа, обсудите это со списком рассылки Google Go style, прежде чем
> приступать к реализации.
@@ -2922,7 +2897,7 @@ context в каждый метод типа, которому нужно пер
См. также:
-* [Контексты и структуры]
+- [Контексты и структуры]
[`context.Background()`]: https://pkg.go.dev/context/#Background
[Контексты и структуры]: https://go.dev/blog/context-and-structs
@@ -2943,7 +2918,7 @@ context в каждый метод типа, которому нужно пер
Если у вас есть данные приложения для передачи, поместите их в параметр, в
получателе, в глобальных переменных или в значении `Context`, если они
-действительно принадлежат там. Создание вашего собственного типа контекста
+действительно принадлежат там. Создание вашего собственного типа контекста
неприемлемо, поскольку оно подрывает способность команды Go заставить программы
Go правильно работать в продакшене.
@@ -2991,13 +2966,13 @@ func Key() string {
<a id="TOC-UsefulTestFailures"></a>
Должна быть возможность диагностировать неудачу теста без чтения исходного кода
-теста. Тесты должны завершаться неудачей с полезными сообщениями,
+теста. Тесты должны завершаться неудачей с полезными сообщениями,
детализирующими:
-* Что вызвало неудачу
-* Какие входные данные привели к ошибке
-* Фактический результат
-* Что ожидалось
+- Что вызвало неудачу
+- Какие входные данные привели к ошибке
+- Фактический результат
+- Что ожидалось
Конкретные соглашения для достижения этой цели изложены ниже.
@@ -3052,7 +3027,7 @@ func StringEq(t *testing.T, name, got, want string) {
библиотеку утверждений использовать, какой стиль формата вывода она должна
выдавать и т.д.? Фрагментация создает ненужную путаницу, особенно для
сопровождающих библиотек и авторов крупномасштабных изменений, которые отвечают
-за исправление потенциальных поломок вниз по течению. Вместо создания
+за исправление потенциальных поломок вниз по течению. Вместо создания
предметно-ориентированного языка для тестирования используйте сам Go.
Библиотеки утверждений часто выносят сравнения и проверки равенства.
@@ -3095,11 +3070,11 @@ func TestBlogPost_VeritableRant(t *testing.T) {
См. также:
-* [Сравнение равенства и разницы (diffs)](#types-of-equality)
-* [Печать разниц (diffs)](#print-diffs)
-* Подробнее о различии между тестовыми помощниками и помощниками утверждений
- см. [лучшие практики](https://neonxp.ru/pages/gostyleguide/google/best-practices/#test-functions)
-* Раздел [Go FAQ] о [фреймворках тестирования] и их мнение об их отсутствии
+- [Сравнение равенства и разницы (diffs)](#types-of-equality)
+- [Печать разниц (diffs)](#print-diffs)
+- Подробнее о различии между тестовыми помощниками и помощниками утверждений
+ см. [лучшие практики](https://neonxp.ru/pages/gostyleguide/google/best-practices/#test-functions)
+- Раздел [Go FAQ] о [фреймворках тестирования] и их мнение об их отсутствии
[полезные сообщения об ошибках]: #useful-test-failures
[`fmt`]: https://golang.org/pkg/fmt/
@@ -3136,7 +3111,7 @@ func TestBlogPost_VeritableRant(t *testing.T) {
предпочитайте использовать слова "got" и "want" соответственно.
Для разниц (diffs) направленность менее очевидна, и поэтому важно включить ключ,
-чтобы помочь в интерпретации неудачи. См. [раздел о печати разниц]. Независимо
+чтобы помочь в интерпретации неудачи. См. [раздел о печати разниц]. Независимо
от порядка diff, который вы используете в своих сообщениях об ошибках, вы должны
явно указать его как часть сообщения об ошибке, поскольку существующий код
непоследователен в порядке.
@@ -3186,8 +3161,7 @@ if tail != `Fran & Freddie's Diner"` {
[глубокого сравнения (deep comparison)]: #types-of-equality
[`cmpopts`]: https://pkg.go.dev/github.com/google/go-cmp/cmp/cmpopts
-[`cmpopts.IgnoreInterfaces`]:
- https://pkg.go.dev/github.com/google/go-cmp/cmp/cmpopts#IgnoreInterfaces
+[`cmpopts.IgnoreInterfaces`]: https://pkg.go.dev/github.com/google/go-cmp/cmp/cmpopts#IgnoreInterfaces
<a id="compare-stable-results"></a>
@@ -3239,7 +3213,7 @@ if diff := cmp.Diff(wantVariance, gotVariance); diff != "" {
Вызов `t.Fatal` в первую очередь полезен для сообщения о неожиданном условии
(таком как ошибка или несоответствие вывода), когда последующие неудачи были бы
бессмысленны или даже вводили бы исследователя в заблуждение. Обратите внимание,
-как код ниже вызывает `t.Fatalf` и *затем* `t.Errorf`:
+как код ниже вызывает `t.Fatalf` и _затем_ `t.Errorf`:
```go
// Хорошо:
@@ -3259,10 +3233,10 @@ if gotDecoded != input {
Для табличных тестов рассмотрите использование подтестов и используйте `t.Fatal`
вместо `t.Error` и `continue`. См. также [GoTip #25: Subtests: Making Your Tests
-Lean](https://google.github.io/styleguide/go/index.html#gotip).
+Lean](/pages/gostyleguide/google/index.html#gotip).
**Лучшая практика:** Для дальнейшего обсуждения о том, когда следует
-использовать `t.Fatal`, см. [лучшие практики](https://neonxp.ru/pages/gostyleguide/google/best-practices/#t-fatal).
+использовать `t.Fatal`, см. [лучшие практики](https://neonxp.ru/pages/gostyleguide/google/best-practices/#t-fatal).
<a id="types-of-equality"></a>
@@ -3307,30 +3281,29 @@ if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" {
Хотя пакет `cmp` не является частью стандартной библиотеки Go, он поддерживается
командой Go и должен обеспечивать стабильные результаты равенства с течением
-времени. Он настраивается пользователем и должен удовлетворять большинству
+времени. Он настраивается пользователем и должен удовлетворять большинству
потребностей в сравнении.
[определенные языком сравнения]: http://golang.org/ref/spec#Comparison_operators
[`cmp`]: https://pkg.go.dev/github.com/google/go-cmp/cmp
[`cmp.Equal`]: https://pkg.go.dev/github.com/google/go-cmp/cmp#Equal
[`cmp.Diff`]: https://pkg.go.dev/github.com/google/go-cmp/cmp#Diff
-[`protocmp.Transform`]:
- https://pkg.go.dev/google.golang.org/protobuf/testing/protocmp#Transform
+[`protocmp.Transform`]: https://pkg.go.dev/google.golang.org/protobuf/testing/protocmp#Transform
Существующий код может использовать следующие более старые библиотеки и может
продолжать использовать их для согласованности:
-* [`pretty`] создает эстетически приятные отчеты о различиях. Однако он
- довольно намеренно считает значения, имеющие одинаковое визуальное
- представление, равными. В частности, `pretty` не улавливает различия между
- nil срезами и пустыми, не чувствителен к разным реализациям интерфейсов с
- идентичными полями, и возможно использовать вложенную карту в качестве
- основы для сравнения со значением структуры. Он также сериализует все
- значение в строку перед созданием diff, и, как таковой, не является хорошим
- выбором для сравнения больших значений. По умолчанию он сравнивает
- неэкспортируемые поля, что делает его чувствительным к изменениям в деталях
- реализации в ваших зависимостях. По этой причине нецелесообразно
- использовать `pretty` на сообщениях protobuf.
+- [`pretty`] создает эстетически приятные отчеты о различиях. Однако он
+ довольно намеренно считает значения, имеющие одинаковое визуальное
+ представление, равными. В частности, `pretty` не улавливает различия между
+ nil срезами и пустыми, не чувствителен к разным реализациям интерфейсов с
+ идентичными полями, и возможно использовать вложенную карту в качестве
+ основы для сравнения со значением структуры. Он также сериализует все
+ значение в строку перед созданием diff, и, как таковой, не является хорошим
+ выбором для сравнения больших значений. По умолчанию он сравнивает
+ неэкспортируемые поля, что делает его чувствительным к изменениям в деталях
+ реализации в ваших зависимостях. По этой причине нецелесообразно
+ использовать `pretty` на сообщениях protobuf.
[`pretty`]: https://pkg.go.dev/github.com/kylelemons/godebug/pretty
@@ -3344,7 +3317,7 @@ if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" {
быть обновлен до одной из вышеупомянутых библиотек.
**Примечание:** Пакет `cmp` предназначен для тестирования, а не для
-использования в продакшене. Как таковой, он может вызывать панику, когда
+использования в продакшене. Как таковой, он может вызывать панику, когда
подозревает, что сравнение выполнено неправильно, чтобы дать инструкции
пользователям, как улучшить тест, чтобы он был менее хрупким. Учитывая
склонность cmp к панике, он непригоден для кода, который используется в
@@ -3358,19 +3331,19 @@ if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" {
`YourFunc(%v) = %v, want %v`. Однако бывают случаи, которые могут потребовать
больше или меньше деталей:
-* Тесты, выполняющие сложные взаимодействия, должны также описывать
- взаимодействия. Например, если один и тот же `YourFunc` вызывается
- несколько раз, идентифицируйте, какой вызов провалил тест. Если важно знать
- любое дополнительное состояние системы, включите это в вывод ошибки (или
- хотя бы в логи).
-* Если данные представляют собой сложную структуру со значительным шаблонным
- кодом, допустимо описать только важные части в сообщении, но не чрезмерно
- затемняйте данные.
-* Ошибки настройки не требуют такого же уровня детализации. Если тестовый
- помощник заполняет таблицу Spanner, но Spanner был выключен, вам, вероятно,
- не нужно включать, какие тестовые входные данные вы собирались сохранить в
- базе данных. `t.Fatalf("Setup: Failed to set up test database: %s", err)`
- обычно достаточно полезно, чтобы решить проблему.
+- Тесты, выполняющие сложные взаимодействия, должны также описывать
+ взаимодействия. Например, если один и тот же `YourFunc` вызывается
+ несколько раз, идентифицируйте, какой вызов провалил тест. Если важно знать
+ любое дополнительное состояние системы, включите это в вывод ошибки (или
+ хотя бы в логи).
+- Если данные представляют собой сложную структуру со значительным шаблонным
+ кодом, допустимо описать только важные части в сообщении, но не чрезмерно
+ затемняйте данные.
+- Ошибки настройки не требуют такого же уровня детализации. Если тестовый
+ помощник заполняет таблицу Spanner, но Spanner был выключен, вам, вероятно,
+ не нужно включать, какие тестовые входные данные вы собирались сохранить в
+ базе данных. `t.Fatalf("Setup: Failed to set up test database: %s", err)`
+ обычно достаточно полезно, чтобы решить проблему.
**Совет:** Заставьте ваш режим отказа срабатывать во время разработки.
Просмотрите, как выглядит сообщение об ошибке, и может ли сопровождающий
@@ -3379,11 +3352,11 @@ if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" {
Существуют некоторые методы для ясного воспроизведения тестовых входов и
выходов:
-* При выводе строковых данных [`%q` часто полезен](#use-percent-q) для
- выделения важности значения и более легкого обнаружения плохих значений.
-* При выводе (маленьких) структур `%+v` может быть полезнее, чем `%v`.
-* Когда проверка больших значений завершается неудачей, [печать разницы
- (diff)](#print-diffs) может облегчить понимание неудачи.
+- При выводе строковых данных [`%q` часто полезен](#use-percent-q) для
+ выделения важности значения и более легкого обнаружения плохих значений.
+- При выводе (маленьких) структур `%+v` может быть полезнее, чем `%v`.
+- Когда проверка больших значений завершается неудачей, [печать разницы
+ (diff)](#print-diffs) может облегчить понимание неудачи.
<a id="print-diffs"></a>
@@ -3398,9 +3371,9 @@ if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" {
См. [типы равенства] для рекомендаций относительно сильных и слабых сторон
каждой функции.
-* [`cmp.Diff`]
+- [`cmp.Diff`]
-* [`pretty.Compare`]
+- [`pretty.Compare`]
Вы можете использовать пакет [`diff`] для сравнения многострочных строк или
списков строк. Вы можете использовать это как строительный блок для других видов
@@ -3408,8 +3381,7 @@ if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" {
[типы равенства]: #types-of-equality
[`diff`]: https://pkg.go.dev/github.com/kylelemons/godebug/diff
-[`pretty.Compare`]:
- https://pkg.go.dev/github.com/kylelemons/godebug/pretty#Compare
+[`pretty.Compare`]: https://pkg.go.dev/github.com/kylelemons/godebug/pretty#Compare
Добавьте некоторый текст в ваше сообщение об ошибке, объясняющий направление
diff.
@@ -3423,17 +3395,17 @@ order to use is also intentional, as there is no consensus which is
-->
-* Что-то вроде `diff (-want +got)` хорошо, когда вы используете пакеты `cmp`,
- `pretty` и `diff` (если вы передаете `(want, got)` в функцию), потому что
- `-` и `+`, которые вы добавляете в строку формата, будут соответствовать `-`
- и `+`, которые фактически появляются в начале строк diff. Если вы передаете
- `(got, want)` в вашу функцию, правильным ключом будет `(-got +want)` вместо
- этого.
+- Что-то вроде `diff (-want +got)` хорошо, когда вы используете пакеты `cmp`,
+ `pretty` и `diff` (если вы передаете `(want, got)` в функцию), потому что
+ `-` и `+`, которые вы добавляете в строку формата, будут соответствовать `-`
+ и `+`, которые фактически появляются в начале строк diff. Если вы передаете
+ `(got, want)` в вашу функцию, правильным ключом будет `(-got +want)` вместо
+ этого.
-* Пакет `messagediff` использует другой формат вывода, поэтому сообщение `diff
- (want -> got)` уместно, когда вы его используете (если вы передаете `(want,
- got)` в функцию), потому что направление стрелки будет соответствовать
- направлению стрелки в строках "modified".
+- Пакет `messagediff` использует другой формат вывода, поэтому сообщение `diff
+(want -> got)` уместно, когда вы его используете (если вы передаете `(want,
+got)` в функцию), потому что направление стрелки будет соответствовать
+ направлению стрелки в строках "modified".
Diff будет занимать несколько строк, поэтому вы должны напечатать новую строку
перед печатью diff.
@@ -3458,7 +3430,7 @@ Diff будет занимать несколько строк, поэтому
Тесты должны стремиться тестировать только семантическую информацию, которую
можно надежно наблюдать, а не отображаемую информацию, предназначенную для
отладки человеком, поскольку последняя часто подвержена будущим изменениям.
-Рекомендации по созданию ошибок со смысловым значением см. [лучшие практики
+Рекомендации по созданию ошибок со смысловым значением см. [лучшие практики
относительно ошибок](https://neonxp.ru/pages/gostyleguide/google/best-practices/#error-handling). Если ошибка с недостаточной
семантической информацией исходит из зависимости вне вашего контроля,
рассмотрите возможность создания отчета об ошибке (bug) владельцу, чтобы помочь
@@ -3485,12 +3457,10 @@ Diff будет занимать несколько строк, поэтому
> ```
См. также [GoTip #13: Designing Errors for
-Checking](https://google.github.io/styleguide/go/index.html#gotip).
+Checking](/pages/gostyleguide/google/index.html#gotip).
-[tott-350]:
- https://testing.googleblog.com/2015/01/testing-on-toilet-change-detector-tests.html
-[`cmpopts.EquateErrors`]:
- https://pkg.go.dev/github.com/google/go-cmp/cmp/cmpopts#EquateErrors
+[tott-350]: https://testing.googleblog.com/2015/01/testing-on-toilet-change-detector-tests.html
+[`cmpopts.EquateErrors`]: https://pkg.go.dev/github.com/google/go-cmp/cmp/cmpopts#EquateErrors
[`errors.Is`]: https://pkg.go.dev/errors#Is
<a id="test-structure"></a>
@@ -3503,8 +3473,8 @@ Checking](https://google.github.io/styleguide/go/index.html#gotip).
Стандартная библиотека тестирования Go предоставляет возможность [определять
подтесты]. Это позволяет гибкость в настройке и очистке, управлении
-параллелизмом и фильтрации тестов. Подтесты могут быть полезны (особенно для
-табличных тестов), но их использование не обязательно. См. также [пост в блоге
+параллелизмом и фильтрации тестов. Подтесты могут быть полезны (особенно для
+табличных тестов), но их использование не обязательно. См. также [пост в блоге
Go о подтестах](https://blog.golang.org/subtests).
Подтесты не должны зависеть от выполнения других случаев для успеха или
@@ -3512,8 +3482,7 @@ Go о подтестах](https://blog.golang.org/subtests).
индивидуально с использованием флагов `go test -run` или выражений [фильтра
тестов] Bazel.
-[определять подтесты]:
- https://pkg.go.dev/testing#hdr-Subtests_and_Sub_benchmarks
+[определять подтесты]: https://pkg.go.dev/testing#hdr-Subtests_and_Sub_benchmarks
[фильтра тестов]: https://bazel.build/docs/user-manual#test-filter
<a id="subtest-names"></a>
@@ -3523,9 +3492,9 @@ Go о подтестах](https://blog.golang.org/subtests).
Назовите ваш подтест так, чтобы он был читаем в выводе теста и полезен в
командной строке для пользователей фильтрации тестов. Когда вы используете
`t.Run` для создания подтеста, первый аргумент используется как описательное имя
-для теста. Чтобы гарантировать, что результаты тестов читаемы для людей,
+для теста. Чтобы гарантировать, что результаты тестов читаемы для людей,
читающих логи, выбирайте имена подтестов, которые останутся полезными и
-читаемыми после экранирования. Думайте об именах подтестов скорее как об
+читаемыми после экранирования. Думайте об именах подтестов скорее как об
идентификаторе функции, чем о прозаическом описании.
Тестовый раннер заменяет пробелы подчеркиваниями и экранирует непечатаемые
@@ -3591,12 +3560,11 @@ t.Run("AM/PM confusion", ...)
```
См. также [Go Tip #117: Subtest
-Names](https://google.github.io/styleguide/go/index.html#gotip).
+Names](/pages/gostyleguide/google/index.html#gotip).
[Go test runner]: https://golang.org/cmd/go/#hdr-Testing_flags
[идентифицировать входные данные]: #identify-the-input
-[особое значение для фильтров тестов]:
- https://blog.golang.org/subtests#:~:text=Perhaps%20a%20bit,match%20any%20tests
+[особое значение для фильтров тестов]: https://blog.golang.org/subtests#:~:text=Perhaps%20a%20bit,match%20any%20tests
<a id="table-driven-tests"></a>
@@ -3605,19 +3573,17 @@ Names](https://google.github.io/styleguide/go/index.html#gotip).
Используйте табличные тесты, когда множество различных тестовых случаев могут
быть протестированы с помощью сходной тестовой логики.
-* При тестировании того, равен ли фактический вывод функции ожидаемому выводу.
- Например, множество [тестов `fmt.Sprintf`] или минимальный фрагмент ниже.
-* При тестировании того, соответствуют ли выводы функции всегда одному и тому
- же набору инвариантов. Например, [тесты для `net.Dial`].
+- При тестировании того, равен ли фактический вывод функции ожидаемому выводу.
+ Например, множество [тестов `fmt.Sprintf`] или минимальный фрагмент ниже.
+- При тестировании того, соответствуют ли выводы функции всегда одному и тому
+ же набору инвариантов. Например, [тесты для `net.Dial`].
-[тестов `fmt.Sprintf`]:
- https://cs.opensource.google/go/go/+/master:src/fmt/fmt_test.go
-[тестов для `net.Dial`]:
- https://cs.opensource.google/go/go/+/master:src/net/dial_test.go;l=318;drc=5b606a9d2b7649532fe25794fa6b99bd24e7697c
+[тестов `fmt.Sprintf`]: https://cs.opensource.google/go/go/+/master:src/fmt/fmt_test.go
+[тестов для `net.Dial`]: https://cs.opensource.google/go/go/+/master:src/net/dial_test.go;l=318;drc=5b606a9d2b7649532fe25794fa6b99bd24e7697c
Вот минимальная структура табличного теста. При необходимости вы можете
использовать другие имена или добавить дополнительные средства, такие как
-подтесты или функции настройки и очистки. Всегда помните о [полезных сообщениях
+подтесты или функции настройки и очистки. Всегда помните о [полезных сообщениях
об ошибках тестов](#useful-test-failures).
```go
@@ -3664,7 +3630,7 @@ func TestCompare(t *testing.T) {
Когда дополнительные тестовые случаи просты (например, базовая проверка ошибок)
и не вводят условный поток кода в теле цикла табличного теста, допустимо
включить этот случай в существующий тест, хотя будьте осторожны, используя такую
-логику. То, что начинается просто сегодня, может органически вырасти во что-то
+логику. То, что начинается просто сегодня, может органически вырасти во что-то
неподдерживаемое.
Например:
@@ -3727,8 +3693,7 @@ func TestDivide(t *testing.T) {
лучшим подходом является написание двух отдельных табличных тестовых функций:
одну для обычных не-ошибочных выводов, и одну для ошибочных выводов.
-[GoTip #50: Disjoint Table Tests]:
- https://google.github.io/styleguide/go/index.html#gotip
+[GoTip #50: Disjoint Table Tests]: /pages/gostyleguide/google/index.html#gotip
<a id="table-tests-data-driven"></a>
@@ -3860,7 +3825,7 @@ for i, d := range tests {
```
Добавьте описание теста в вашу тестовую структуру и печатайте его вместе с
-сообщениями об ошибках. При использовании подтестов имя вашего подтеста должно
+сообщениями об ошибках. При использовании подтестов имя вашего подтеста должно
эффективно идентифицировать строку.
**Важно:** Хотя `t.Run` ограничивает область вывода и выполнения, вы должны
@@ -3874,7 +3839,7 @@ for i, d := range tests {
### Тестовые помощники (Test helpers)
-Тестовый помощник — это функция, выполняющая задачу настройки или очистки. Все
+Тестовый помощник — это функция, выполняющая задачу настройки или очистки. Все
ошибки, возникающие в тестовых помощниках, должны быть ошибками окружения (а не
кода под тестом) — например, когда тестовая база данных не может быть запущена
потому что на этой машине не осталось свободных портов.
@@ -3930,9 +3895,9 @@ func readFile(t *testing.T, filename string) string {
Чтобы написать тест в том же пакете:
-* Поместите тесты в файл `foo_test.go`
-* Используйте `package foo` для тестового файла
-* Не импортируйте явно тестируемый пакет
+- Поместите тесты в файл `foo_test.go`
+- Используйте `package foo` для тестового файла
+- Не импортируйте явно тестируемый пакет
```build
# Хорошо:
@@ -3956,12 +3921,11 @@ go_test(
```
Тест в том же пакете может обращаться к неэкспортированным идентификаторам в
-пакете. Это может обеспечить лучшее покрытие тестами и более лаконичные тесты.
+пакете. Это может обеспечить лучшее покрытие тестами и более лаконичные тесты.
Имейте в виду, что любые [примеры], объявленные в тесте, не будут иметь имен
пакетов, которые понадобятся пользователю в их коде.
-[`library`]:
- https://github.com/bazelbuild/rules_go/blob/master/docs/go/core/rules.md#go_library
+[`library`]: https://github.com/bazelbuild/rules_go/blob/master/docs/go/core/rules.md#go_library
[примеры]: #examples
<a id="test-different-package"></a>
@@ -3969,12 +3933,12 @@ go_test(
#### Тесты в другом пакете
Не всегда уместно или даже возможно определить тест в том же пакете, что и
-тестируемый код. В этих случаях используйте имя пакета с суффиксом `_test`. Это
+тестируемый код. В этих случаях используйте имя пакета с суффиксом `_test`. Это
исключение из правила "без подчеркиваний" для [имен пакетов](#package-names).
Например:
-* Если интеграционный тест не имеет очевидной библиотеки, к которой он
- принадлежит
+- Если интеграционный тест не имеет очевидной библиотеки, к которой он
+ принадлежит
```go
// Хорошо:
@@ -3983,7 +3947,7 @@ go_test(
import "testing"
```
-* Если определение тестов в том же пакете приводит к циклическим зависимостям
+- Если определение тестов в том же пакете приводит к циклическим зависимостям
```go
// Хорошо:
@@ -4007,12 +3971,12 @@ go_test(
Пакет `testing` предоставляет минимальный, но полный набор функциональности для
написания хороших тестов:
-* Тесты верхнего уровня
-* Бенчмарки
-* [Исполняемые примеры](https://blog.golang.org/examples)
-* Подтесты
-* Логирование
-* Ошибки и фатальные ошибки
+- Тесты верхнего уровня
+- Бенчмарки
+- [Исполняемые примеры](https://blog.golang.org/examples)
+- Подтесты
+- Логирование
+- Ошибки и фатальные ошибки
Они разработаны для слаженной работы с основными языковыми возможностями, такими
как [составные литералы] и [if с инициализатором], чтобы позволить авторам
@@ -4031,17 +3995,17 @@ go_test(
мнения. Тем не менее, вот несколько вещей, по которым сообщество читаемости
ранее спорило и не достигло консенсуса.
-* **Локальная инициализация переменных нулевым значением**. `var i int` и `i
- := 0` эквивалентны. См. также [лучшие практики инициализации].
-* **Пустой составной литерал vs. `new` или `make`**. `&File{}` и `new(File)`
- эквивалентны. Так же `map[string]bool{}` и `make(map[string]bool)`. См.
- также [лучшие практики составных объявлений].
-* **Порядок аргументов got, want в вызовах cmp.Diff**. Будьте локально
- последовательны и [включите легенду](#print-diffs) в ваше сообщение об
- ошибке.
-* **`errors.New` vs `fmt.Errorf` на неформатированных строках**.
- `errors.New("foo")` и `fmt.Errorf("foo")` могут использоваться
- взаимозаменяемо.
+- **Локальная инициализация переменных нулевым значением**. `var i int` и `i
+:= 0` эквивалентны. См. также [лучшие практики инициализации].
+- **Пустой составной литерал vs. `new` или `make`**. `&File{}` и `new(File)`
+ эквивалентны. Так же `map[string]bool{}` и `make(map[string]bool)`. См.
+ также [лучшие практики составных объявлений].
+- **Порядок аргументов got, want в вызовах cmp.Diff**. Будьте локально
+ последовательны и [включите легенду](#print-diffs) в ваше сообщение об
+ ошибке.
+- **`errors.New` vs `fmt.Errorf` на неформатированных строках**.
+ `errors.New("foo")` и `fmt.Errorf("foo")` могут использоваться
+ взаимозаменяемо.
Если возникнут особые обстоятельства, наставник по читаемости может сделать
необязательный комментарий, но в целом автор волен выбирать предпочитаемый им
@@ -4051,7 +4015,5 @@ go_test(
дополнительного обсуждения, авторы могут спросить — либо в конкретном ревью,
либо на внутренних досках сообщений.
-[лучшие практики составных объявлений]:
- https://google.github.io/styleguide/go/best-practices#vardeclcomposite
-[лучшие практики инициализации]:
- https://google.github.io/styleguide/go/best-practices#vardeclinitialization
+[лучшие практики составных объявлений]: /pages/gostyleguide/google/best-practices#vardeclcomposite
+[лучшие практики инициализации]: /pages/gostyleguide/google/best-practices#vardeclinitialization