[
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: \"gomod\"\n    directory: \"/tools\"\n    schedule:\n      interval: \"daily\"\n\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non:\n  push:\n    branches: [ main ]\n  pull_request_target:\n    branches: [ '*' ]\n\njobs:\n  stitchmd:\n    name: Check or update style.md\n    runs-on: ubuntu-latest\n\n    # Needed to give the job permission\n    # to push to branches.\n    permissions:\n      contents: write\n\n    steps:\n    - name: Check out repository\n      uses: actions/checkout@v4\n      with:\n        # Check out the pull request repository and branch.\n        # If the PR is made from a fork, this will check out the fork.\n        # This is necessary for git-auto-commit-action to update PRs made by forks.\n        # See \n        # https://github.com/stefanzweifel/git-auto-commit-action#use-in-forks-from-public-repositories\n        repository: ${{ github.event.pull_request.head.repo.full_name }}\n        ref: ${{ github.head_ref }}\n\n    - name: Check or update style.md\n      uses: abhinav/stitchmd-action@v1\n      with:\n        # For pull requests, run in 'write' mode so that edits made\n        # directly in the GitHub UI get propagated to style.md\n        # without a local checkout.\n        #\n        # Otherwise, run in 'check' mode to fail CI if style.md is out-of-date.\n        mode: ${{ github.event_name == 'pull_request_target' && 'write' || 'check' }}\n        summary: src/SUMMARY.md\n        preface: src/preface.txt\n        output: style.md\n\n    - uses: stefanzweifel/git-auto-commit-action@v5\n      if: ${{ github.event_name == 'pull_request_target' }}\n      with:\n        file_pattern: style.md\n        commit_message: 'Auto-update style.md'\n"
  },
  {
    "path": ".gitignore",
    "content": "/bin\n"
  },
  {
    "path": ".golangci.yml",
    "content": "# Refer to golangci-lint's example config file for more options and information:\n# https://github.com/golangci/golangci-lint/blob/master/.golangci.reference.yml\n\nrun:\n  timeout: 5m\n  modules-download-mode: readonly\n\nlinters:\n  enable:\n    - errcheck\n    - goimports\n    - golint\n    - govet\n    - staticcheck\n\nissues:\n  exclude-use-default: false\n  max-issues-per-linter: 0\n  max-same-issues: 0\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# 2023-05-09\n\n- Test tables: Discourage tables with complex, branching test bodies.\n\n# 2023-04-13\n\n- Errors: Add guidance on handling errors only once.\n\n# 2023-03-03\n\n- Receivers and Interfaces: Clarify subtlety with pointer receivers and values.\n\n# 2022-10-18\n\n- Add guidance on managing goroutine lifecycles.\n\n# 2022-03-30\n\n- Add guidance on using field tags in marshaled structs.\n\n# 2021-11-16\n\n- Add guidance on use of `%w` vs `%v` with `fmt.Errorf`, and where to use\n  `errors.New` or custom error types.\n\n# 2021-11-12\n\n- Add soft line length limit of 99 characters.\n\n# 2021-04-19\n\n- Programs should exit only in `main()`, preferably at most once.\n\n# 2021-03-15\n\n- Add guidance on omitting zero-value fields during struct initialization.\n- Add guidance on `Foo{}` versus `var` form for initialization of empty\n  structs.\n- Add new section for Initializing Structs, moving relevant guidances into\n  subsections of it.\n\n# 2020-06-10\n\n- Add guidance on avoiding `init()`.\n- Add guidance to avoid using built-in names.\n- Add reminder that nil slices are not always the same as empty slices.\n\n# 2020-02-24\n\n- Add guidance on verifying interface compliance with compile-time checks.\n\n# 2020-01-30\n\n- Recommend using the `time` package when dealing with time.\n\n# 2020-01-25\n\n- Add guidance against embedding types in public structs.\n\n# 2019-12-17\n\n- Functional Options: Recommend struct implementations of `Option` interface\n  instead of capturing values with a closure.\n\n# 2019-11-26\n\n- Add guidance against mutating global variables.\n\n# 2019-10-21\n\n- Add section on remaining consistent with existing practices.\n- Add guidance on map initialization and size hints.\n\n# 2019-10-11\n\n- Suggest succinct context for error messages.\n\n# 2019-10-10\n\n- Initial release.\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, sex characteristics, gender identity and expression,\nlevel of experience, education, socio-economic status, nationality, personal\nappearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\n advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at oss-conduct@uber.com. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see\nhttps://www.contributor-covenant.org/faq\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nBefore making any changes,\nplease discuss your plans on GitHub\nand get agreement on the general direction of the change.\n\n## Making changes\n\n- style.md is generated from the contents of the src/ folder.\n  All changes must be made to files in the src/ folder.\n- For new entries, create a new file with a short name\n  (see [File names](#file-names)) and add it to [SUMMARY.md](src/SUMMARY.md).\n  The file must have a single level 1 heading and any number of subsections.\n- Use tables for side-by-side code samples.\n- Link to other sections with their file names (`[..](foo.md)`).\n\n## Writing style\n\n### Line breaks\n\nUse [semantic line breaks](https://sembr.org/) in your writing.\nThis keeps the Markdown files easily reviewable and editable.\n\n### File names\n\nFiles in src/ follow a rough naming convention of:\n\n    {subject}-{desc}.md\n\nWhere `{subject}` is the **singular form** of subject that the entry is about\n(e.g `string`, `struct`, `time`, `var`, `error`)\nand `{desc}` is a short one or two word description of the topic.\nFor subjects where their name is enough, the `-{desc}` may be omitted.\n\n### Code samples\n\nUse two spaces to indent code samples.\nHorizontal space is limited in side-by-side samples.\n\n### Side-by-side samples\n\nCreate side-by-side code samples with the following template:\n\n~~~\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nBAD CODE GOES HERE\n```\n\n</td><td>\n\n```go\nGOOD CODE GOES HERE\n```\n\n</td></tr>\n</tbody></table>\n~~~\n\nThe empty lines between the HTML tags and code samples are necessary.\n\nIf you need to add labels or descriptions below the code samples,\nadd another row before the `</tbody></table>` line.\n\n~~~\n<tr>\n<td>DESCRIBE BAD CODE</td>\n<td>DESCRIBE GOOD CODE</td>\n</tr>\n~~~\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n"
  },
  {
    "path": "Makefile",
    "content": "SHELL = /bin/bash\n\n# Setting GOBIN makes 'go install' put the binary in the bin/ directory.\nexport GOBIN ?= $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/bin\n\nSTITCHMD = $(GOBIN)/stitchmd\n\n# Keep these options in-sync with .github/workflows/ci.yml.\nSTITCHMD_ARGS = -o style.md -preface src/preface.txt src/SUMMARY.md\n\n.PHONY: all\nall: style.md\n\n.PHONY: lint\nlint: $(STITCHMD)\n\t@DIFF=$$($(STITCHMD) -d $(STITCHMD_ARGS)); \\\n\tif [[ -n \"$$DIFF\" ]]; then \\\n\t\techo \"style.md is out of date:\"; \\\n\t\techo \"$$DIFF\"; \\\n\t\tfalse; \\\n\tfi\n\nstyle.md: $(STITCHMD) $(wildcard src/*)\n\t$(STITCHMD) $(STITCHMD_ARGS)\n\n$(STITCHMD):\n\tgo install go.abhg.dev/stitchmd@latest\n"
  },
  {
    "path": "README.md",
    "content": "This repository holds the [Uber Go Style Guide](style.md), which documents\npatterns and conventions used in Go code at Uber.\n\n## Style Guide\n\nSee [Uber Go Style Guide](style.md) for the style guide.\n\n## Translations\n\nWe are aware of the following translations of this guide by the Go community.\n\n- **中文翻译** (Chinese): [xxjwxc/uber_go_guide_cn](https://github.com/xxjwxc/uber_go_guide_cn)\n- **繁體中文** （Traditional Chinese）：[ianchen0119/uber_go_guide_tw](https://github.com/ianchen0119/uber_go_guide_tw)\n- **한국어 번역** (Korean): [TangoEnSkai/uber-go-style-guide-kr](https://github.com/TangoEnSkai/uber-go-style-guide-kr)\n- **日本語訳** (Japanese): [knsh14/uber-style-guide-ja](https://github.com/knsh14/uber-style-guide-ja)\n- **Traducción al Español** (Spanish): [friendsofgo/uber-go-guide-es](https://github.com/friendsofgo/uber-go-guide-es)\n- **แปลภาษาไทย** (Thai): [pallat/uber-go-style-guide-th](https://github.com/pallat/uber-go-style-guide-th)\n- **Tradução em português** (Portuguese): [lucassscaravelli/uber-go-guide-pt](https://github.com/lucassscaravelli/uber-go-guide-pt)\n- **Tradução em português** (Portuguese BR): [alcir-junior-caju/uber-go-style-guide-pt-br](https://github.com/alcir-junior-caju/uber-go-style-guide-pt-br)\n- **Tłumaczenie polskie** (Polish): [DamianSkrzypczak/uber-go-guide-pl](https://github.com/DamianSkrzypczak/uber-go-guide-pl)\n- **Русский перевод** (Russian): [sau00/uber-go-guide-ru](https://github.com/sau00/uber-go-guide-ru)\n- **Français** (French): [rm3l/uber-go-style-guide-fr](https://github.com/rm3l/uber-go-style-guide-fr)\n- **Türkçe** (Turkish): [ksckaan1/uber-go-style-guide-tr](https://github.com/ksckaan1/uber-go-style-guide-tr)\n- **Український переклад** (Ukrainian): [vorobeyme/uber-go-style-guide-uk](https://github.com/vorobeyme/uber-go-style-guide-uk)\n- **ترجمه فارسی** (Persian): [jamalkaksouri/uber-go-guide-ir](https://github.com/jamalkaksouri/uber-go-guide-ir)\n- **Tiếng việt** (Vietnamese): [nc-minh/uber-go-guide-vi](https://github.com/nc-minh/uber-go-guide-vi)\n- **العربية** (Arabic): [anqorithm/uber-go-guide-ar](https://github.com/anqorithm/uber-go-guide-ar)\n- **Bahasa Indonesia** (Indonesian): [stanleydv12/uber-go-guide-id](https://github.com/stanleydv12/uber-go-guide-id)\n\nIf you have a translation, feel free to submit a PR adding it to the list.\n"
  },
  {
    "path": "src/README.md",
    "content": "The contents of this directory are used to generate the top-level style.md.\nThe layout is controlled by SUMMARY.md.\n"
  },
  {
    "path": "src/SUMMARY.md",
    "content": "# Uber Go Style Guide\n\n- [Introduction](intro.md)\n- Guidelines\n  - [Pointers to Interfaces](interface-pointer.md)\n  - [Verify Interface Compliance](interface-compliance.md)\n  - [Receivers and Interfaces](interface-receiver.md)\n  - [Zero-value Mutexes are Valid](mutex-zero-value.md)\n  - [Copy Slices and Maps at Boundaries](container-copy.md)\n  - [Defer to Clean Up](defer-clean.md)\n  - [Channel Size is One or None](channel-size.md)\n  - [Start Enums at One](enum-start.md)\n  - [Use `\"time\"` to handle time](time.md)\n  - Errors\n    - [Error Types](error-type.md)\n    - [Error Wrapping](error-wrap.md)\n    - [Error Naming](error-name.md)\n    - [Handle Errors Once](error-once.md)\n  - [Handle Type Assertion Failures](type-assert.md)\n  - [Don't Panic](panic.md)\n  - [Use go.uber.org/atomic](atomic.md)\n  - [Avoid Mutable Globals](global-mut.md)\n  - [Avoid Embedding Types in Public Structs](embed-public.md)\n  - [Avoid Using Built-In Names](builtin-name.md)\n  - [Avoid `init()`](init.md)\n  - [Exit in Main](exit-main.md)\n    - [Exit Once](exit-once.md)\n  - [Use field tags in marshaled structs](struct-tag.md)\n  - [Don't fire-and-forget goroutines](goroutine-forget.md)\n    - [Wait for goroutines to exit](goroutine-exit.md)\n    - [No goroutines in `init()`](goroutine-init.md)\n- [Performance](performance.md)\n  - [Prefer strconv over fmt](strconv.md)\n  - [Avoid repeated string-to-byte conversions](string-byte-slice.md)\n  - [Prefer Specifying Container Capacity](container-capacity.md)\n- Style\n  - [Avoid overly long lines](line-length.md)\n  - [Be Consistent](consistency.md)\n  - [Group Similar Declarations](decl-group.md)\n  - [Import Group Ordering](import-group.md)\n  - [Package Names](package-name.md)\n  - [Function Names](function-name.md)\n  - [Import Aliasing](import-alias.md)\n  - [Function Grouping and Ordering](function-order.md)\n  - [Reduce Nesting](nest-less.md)\n  - [Unnecessary Else](else-unnecessary.md)\n  - [Top-level Variable Declarations](global-decl.md)\n  - [Prefix Unexported Globals with _](global-name.md)\n  - [Embedding in Structs](struct-embed.md)\n  - [Local Variable Declarations](var-decl.md)\n  - [nil is a valid slice](slice-nil.md)\n  - [Reduce Scope of Variables](var-scope.md)\n  - [Avoid Naked Parameters](param-naked.md)\n  - [Use Raw String Literals to Avoid Escaping](string-escape.md)\n  - Initializing Structs\n    - [Use Field Names to Initialize Structs](struct-field-key.md)\n    - [Omit Zero Value Fields in Structs](struct-field-zero.md)\n    - [Use `var` for Zero Value Structs](struct-zero.md)\n    - [Initializing Struct References](struct-pointer.md)\n  - [Initializing Maps](map-init.md)\n  - [Format Strings outside Printf](printf-const.md)\n  - [Naming Printf-style Functions](printf-name.md)\n- Patterns\n  - [Test Tables](test-table.md)\n  - [Functional Options](functional-option.md)\n- [Linting](lint.md)\n"
  },
  {
    "path": "src/atomic.md",
    "content": "# Use go.uber.org/atomic\n\nAtomic operations with the [sync/atomic] package operate on the raw types\n(`int32`, `int64`, etc.) so it is easy to forget to use the atomic operation to\nread or modify the variables.\n\n[go.uber.org/atomic] adds type safety to these operations by hiding the\nunderlying type. Additionally, it includes a convenient `atomic.Bool` type.\n\n  [go.uber.org/atomic]: https://pkg.go.dev/go.uber.org/atomic\n  [sync/atomic]: https://pkg.go.dev/sync/atomic\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype foo struct {\n  running int32  // atomic\n}\n\nfunc (f* foo) start() {\n  if atomic.SwapInt32(&f.running, 1) == 1 {\n     // already running…\n     return\n  }\n  // start the Foo\n}\n\nfunc (f *foo) isRunning() bool {\n  return f.running == 1  // race!\n}\n```\n\n</td><td>\n\n```go\ntype foo struct {\n  running atomic.Bool\n}\n\nfunc (f *foo) start() {\n  if f.running.Swap(true) {\n     // already running…\n     return\n  }\n  // start the Foo\n}\n\nfunc (f *foo) isRunning() bool {\n  return f.running.Load()\n}\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/builtin-name.md",
    "content": "# Avoid Using Built-In Names\n\nThe Go [language specification] outlines several built-in,\n[predeclared identifiers] that should not be used as names within Go programs.\n\nDepending on context, reusing these identifiers as names will either shadow\nthe original within the current lexical scope (and any nested scopes) or make\naffected code confusing. In the best case, the compiler will complain; in the\nworst case, such code may introduce latent, hard-to-grep bugs.\n\n  [language specification]: https://go.dev/ref/spec\n  [predeclared identifiers]: https://go.dev/ref/spec#Predeclared_identifiers\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nvar error string\n// `error` shadows the builtin\n\n// or\n\nfunc handleErrorMessage(error string) {\n    // `error` shadows the builtin\n}\n```\n\n</td><td>\n\n```go\nvar errorMessage string\n// `error` refers to the builtin\n\n// or\n\nfunc handleErrorMessage(msg string) {\n    // `error` refers to the builtin\n}\n```\n\n</td></tr>\n<tr><td>\n\n```go\ntype Foo struct {\n    // While these fields technically don't\n    // constitute shadowing, grepping for\n    // `error` or `string` strings is now\n    // ambiguous.\n    error  error\n    string string\n}\n\nfunc (f Foo) Error() error {\n    // `error` and `f.error` are\n    // visually similar\n    return f.error\n}\n\nfunc (f Foo) String() string {\n    // `string` and `f.string` are\n    // visually similar\n    return f.string\n}\n```\n\n</td><td>\n\n```go\ntype Foo struct {\n    // `error` and `string` strings are\n    // now unambiguous.\n    err error\n    str string\n}\n\nfunc (f Foo) Error() error {\n    return f.err\n}\n\nfunc (f Foo) String() string {\n    return f.str\n}\n```\n\n</td></tr>\n</tbody></table>\n\nNote that the compiler will not generate errors when using predeclared\nidentifiers, but tools such as `go vet` should correctly point out these and\nother cases of shadowing.\n"
  },
  {
    "path": "src/channel-size.md",
    "content": "# Channel Size is One or None\n\nChannels should usually have a size of one or be unbuffered. By default,\nchannels are unbuffered and have a size of zero. Any other size\nmust be subject to a high level of scrutiny. Consider how the size is\ndetermined, what prevents the channel from filling up under load and blocking\nwriters, and what happens when this occurs.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// Ought to be enough for anybody!\nc := make(chan int, 64)\n```\n\n</td><td>\n\n```go\n// Size of one\nc := make(chan int, 1) // or\n// Unbuffered channel, size of zero\nc := make(chan int)\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/consistency.md",
    "content": "# Be Consistent\n\nSome of the guidelines outlined in this document can be evaluated objectively;\nothers are situational, contextual, or subjective.\n\nAbove all else, **be consistent**.\n\nConsistent code is easier to maintain, is easier to rationalize, requires less\ncognitive overhead, and is easier to migrate or update as new conventions emerge\nor classes of bugs are fixed.\n\nConversely, having multiple disparate or conflicting styles within a single\ncodebase causes maintenance overhead, uncertainty, and cognitive dissonance,\nall of which can directly contribute to lower velocity, painful code reviews,\nand bugs.\n\nWhen applying these guidelines to a codebase, it is recommended that changes\nare made at a package (or larger) level: application at a sub-package level\nviolates the above concern by introducing multiple styles into the same code.\n"
  },
  {
    "path": "src/container-capacity.md",
    "content": "# Prefer Specifying Container Capacity\n\nSpecify container capacity where possible in order to allocate memory for the\ncontainer up front. This minimizes subsequent allocations (by copying and\nresizing of the container) as elements are added.\n\n## Specifying Map Capacity Hints\n\nWhere possible, provide capacity hints when initializing\nmaps with `make()`.\n\n```go\nmake(map[T1]T2, hint)\n```\n\nProviding a capacity hint to `make()` tries to right-size the\nmap at initialization time, which reduces the need for growing\nthe map and allocations as elements are added to the map.\n\nNote that, unlike slices, map capacity hints do not guarantee complete,\npreemptive allocation, but are used to approximate the number of hashmap buckets\nrequired. Consequently, allocations may still occur when adding elements to the\nmap, even up to the specified capacity.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfiles, _ := os.ReadDir(\"./files\")\n\nm := make(map[string]os.DirEntry)\nfor _, f := range files {\n    m[f.Name()] = f\n}\n```\n\n</td><td>\n\n```go\n\nfiles, _ := os.ReadDir(\"./files\")\n\nm := make(map[string]os.DirEntry, len(files))\nfor _, f := range files {\n    m[f.Name()] = f\n}\n```\n\n</td></tr>\n<tr><td>\n\n`m` is created without a size hint; the map will resize \ndynamically, causing multiple allocations as it grows.\n\n</td><td>\n\n`m` is created with a size hint; there may be fewer\nallocations at assignment time.\n\n</td></tr>\n</tbody></table>\n\n## Specifying Slice Capacity\n\nWhere possible, provide capacity hints when initializing slices with `make()`,\nparticularly when appending.\n\n```go\nmake([]T, length, capacity)\n```\n\nUnlike maps, slice capacity is not a hint: the compiler will allocate enough\nmemory for the capacity of the slice as provided to `make()`, which means that\nsubsequent `append()` operations will incur zero allocations (until the length\nof the slice matches the capacity, after which any appends will require a resize\nto hold additional elements).\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfor n := 0; n < b.N; n++ {\n  data := make([]int, 0)\n  for k := 0; k < size; k++{\n    data = append(data, k)\n  }\n}\n```\n\n</td><td>\n\n```go\nfor n := 0; n < b.N; n++ {\n  data := make([]int, 0, size)\n  for k := 0; k < size; k++{\n    data = append(data, k)\n  }\n}\n```\n\n</td></tr>\n<tr><td>\n\n```plain\nBenchmarkBad-4    100000000    2.48s\n```\n\n</td><td>\n\n```plain\nBenchmarkGood-4   100000000    0.21s\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/container-copy.md",
    "content": "# Copy Slices and Maps at Boundaries\n\nSlices and maps contain pointers to the underlying data so be wary of scenarios\nwhen they need to be copied.\n\n## Receiving Slices and Maps\n\nKeep in mind that users can modify a map or slice you received as an argument\nif you store a reference to it.\n\n<table>\n<thead><tr><th>Bad</th> <th>Good</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```go\nfunc (d *Driver) SetTrips(trips []Trip) {\n  d.trips = trips\n}\n\ntrips := ...\nd1.SetTrips(trips)\n\n// Did you mean to modify d1.trips?\ntrips[0] = ...\n```\n\n</td>\n<td>\n\n```go\nfunc (d *Driver) SetTrips(trips []Trip) {\n  d.trips = make([]Trip, len(trips))\n  copy(d.trips, trips)\n}\n\ntrips := ...\nd1.SetTrips(trips)\n\n// We can now modify trips[0] without affecting d1.trips.\ntrips[0] = ...\n```\n\n</td>\n</tr>\n\n</tbody>\n</table>\n\n## Returning Slices and Maps\n\nSimilarly, be wary of user modifications to maps or slices exposing internal\nstate.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype Stats struct {\n  mu sync.Mutex\n  counters map[string]int\n}\n\n// Snapshot returns the current stats.\nfunc (s *Stats) Snapshot() map[string]int {\n  s.mu.Lock()\n  defer s.mu.Unlock()\n\n  return s.counters\n}\n\n// snapshot is no longer protected by the mutex, so any\n// access to the snapshot is subject to data races.\nsnapshot := stats.Snapshot()\n```\n\n</td><td>\n\n```go\ntype Stats struct {\n  mu sync.Mutex\n  counters map[string]int\n}\n\nfunc (s *Stats) Snapshot() map[string]int {\n  s.mu.Lock()\n  defer s.mu.Unlock()\n\n  result := make(map[string]int, len(s.counters))\n  for k, v := range s.counters {\n    result[k] = v\n  }\n  return result\n}\n\n// Snapshot is now a copy.\nsnapshot := stats.Snapshot()\n```\n\n</td></tr>\n</tbody></table>\n\n\n"
  },
  {
    "path": "src/decl-group.md",
    "content": "# Group Similar Declarations\n\nGo supports grouping similar declarations.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nimport \"a\"\nimport \"b\"\n```\n\n</td><td>\n\n```go\nimport (\n  \"a\"\n  \"b\"\n)\n```\n\n</td></tr>\n</tbody></table>\n\nThis also applies to constants, variables, and type declarations.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n\nconst a = 1\nconst b = 2\n\n\n\nvar a = 1\nvar b = 2\n\n\n\ntype Area float64\ntype Volume float64\n```\n\n</td><td>\n\n```go\nconst (\n  a = 1\n  b = 2\n)\n\nvar (\n  a = 1\n  b = 2\n)\n\ntype (\n  Area float64\n  Volume float64\n)\n```\n\n</td></tr>\n</tbody></table>\n\nOnly group related declarations. Do not group declarations that are unrelated.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype Operation int\n\nconst (\n  Add Operation = iota + 1\n  Subtract\n  Multiply\n  EnvVar = \"MY_ENV\"\n)\n```\n\n</td><td>\n\n```go\ntype Operation int\n\nconst (\n  Add Operation = iota + 1\n  Subtract\n  Multiply\n)\n\nconst EnvVar = \"MY_ENV\"\n```\n\n</td></tr>\n</tbody></table>\n\nGroups are not limited in where they can be used. For example, you can use them\ninside of functions.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc f() string {\n  red := color.New(0xff0000)\n  green := color.New(0x00ff00)\n  blue := color.New(0x0000ff)\n\n  // ...\n}\n```\n\n</td><td>\n\n```go\nfunc f() string {\n  var (\n    red   = color.New(0xff0000)\n    green = color.New(0x00ff00)\n    blue  = color.New(0x0000ff)\n  )\n\n  // ...\n}\n```\n\n</td></tr>\n</tbody></table>\n\nException: Variable declarations, particularly inside functions, should be\ngrouped together if declared adjacent to other variables. Do this for variables\ndeclared together even if they are unrelated.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc (c *client) request() {\n  caller := c.name\n  format := \"json\"\n  timeout := 5*time.Second\n  var err error\n\n  // ...\n}\n```\n\n</td><td>\n\n```go\nfunc (c *client) request() {\n  var (\n    caller  = c.name\n    format  = \"json\"\n    timeout = 5*time.Second\n    err error\n  )\n\n  // ...\n}\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/defer-clean.md",
    "content": "# Defer to Clean Up\n\nUse defer to clean up resources such as files and locks.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\np.Lock()\nif p.count < 10 {\n  p.Unlock()\n  return p.count\n}\n\np.count++\nnewCount := p.count\np.Unlock()\n\nreturn newCount\n\n// easy to miss unlocks due to multiple returns\n```\n\n</td><td>\n\n```go\np.Lock()\ndefer p.Unlock()\n\nif p.count < 10 {\n  return p.count\n}\n\np.count++\nreturn p.count\n\n// more readable\n```\n\n</td></tr>\n</tbody></table>\n\nDefer has an extremely small overhead and should be avoided only if you can\nprove that your function execution time is in the order of nanoseconds. The\nreadability win of using defers is worth the miniscule cost of using them. This\nis especially true for larger methods that have more than simple memory\naccesses, where the other computations are more significant than the `defer`.\n"
  },
  {
    "path": "src/else-unnecessary.md",
    "content": "# Unnecessary Else\n\nIf a variable is set in both branches of an if, it can be replaced with a\nsingle if.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nvar a int\nif b {\n  a = 100\n} else {\n  a = 10\n}\n```\n\n</td><td>\n\n```go\na := 10\nif b {\n  a = 100\n}\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/embed-public.md",
    "content": "# Avoid Embedding Types in Public Structs\n\nThese embedded types leak implementation details, inhibit type evolution, and\nobscure documentation.\n\nAssuming you have implemented a variety of list types using a shared\n`AbstractList`, avoid embedding the `AbstractList` in your concrete list\nimplementations.\nInstead, hand-write only the methods to your concrete list that will delegate\nto the abstract list.\n\n```go\ntype AbstractList struct {}\n\n// Add adds an entity to the list.\nfunc (l *AbstractList) Add(e Entity) {\n  // ...\n}\n\n// Remove removes an entity from the list.\nfunc (l *AbstractList) Remove(e Entity) {\n  // ...\n}\n```\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// ConcreteList is a list of entities.\ntype ConcreteList struct {\n  *AbstractList\n}\n```\n\n</td><td>\n\n```go\n// ConcreteList is a list of entities.\ntype ConcreteList struct {\n  list *AbstractList\n}\n\n// Add adds an entity to the list.\nfunc (l *ConcreteList) Add(e Entity) {\n  l.list.Add(e)\n}\n\n// Remove removes an entity from the list.\nfunc (l *ConcreteList) Remove(e Entity) {\n  l.list.Remove(e)\n}\n```\n\n</td></tr>\n</tbody></table>\n\nGo allows [type embedding] as a compromise between inheritance and composition.\nThe outer type gets implicit copies of the embedded type's methods.\nThese methods, by default, delegate to the same method of the embedded\ninstance.\n\n  [type embedding]: https://go.dev/doc/effective_go#embedding\n\nThe struct also gains a field by the same name as the type.\nSo, if the embedded type is public, the field is public.\nTo maintain backward compatibility, every future version of the outer type must\nkeep the embedded type.\n\nAn embedded type is rarely necessary.\nIt is a convenience that helps you avoid writing tedious delegate methods.\n\nEven embedding a compatible AbstractList *interface*, instead of the struct,\nwould offer the developer more flexibility to change in the future, but still\nleak the detail that the concrete lists use an abstract implementation.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// AbstractList is a generalized implementation\n// for various kinds of lists of entities.\ntype AbstractList interface {\n  Add(Entity)\n  Remove(Entity)\n}\n\n// ConcreteList is a list of entities.\ntype ConcreteList struct {\n  AbstractList\n}\n```\n\n</td><td>\n\n```go\n// ConcreteList is a list of entities.\ntype ConcreteList struct {\n  list AbstractList\n}\n\n// Add adds an entity to the list.\nfunc (l *ConcreteList) Add(e Entity) {\n  l.list.Add(e)\n}\n\n// Remove removes an entity from the list.\nfunc (l *ConcreteList) Remove(e Entity) {\n  l.list.Remove(e)\n}\n```\n\n</td></tr>\n</tbody></table>\n\nEither with an embedded struct or an embedded interface, the embedded type\nplaces limits on the evolution of the type.\n\n- Adding methods to an embedded interface is a breaking change.\n- Removing methods from an embedded struct is a breaking change.\n- Removing the embedded type is a breaking change.\n- Replacing the embedded type, even with an alternative that satisfies the same\n  interface, is a breaking change.\n\nAlthough writing these delegate methods is tedious, the additional effort hides\nan implementation detail, leaves more opportunities for change, and also\neliminates indirection for discovering the full List interface in\ndocumentation.\n"
  },
  {
    "path": "src/enum-start.md",
    "content": "# Start Enums at One\n\nThe standard way of introducing enumerations in Go is to declare a custom type\nand a `const` group with `iota`. Since variables have a 0 default value, you\nshould usually start your enums on a non-zero value.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype Operation int\n\nconst (\n  Add Operation = iota\n  Subtract\n  Multiply\n)\n\n// Add=0, Subtract=1, Multiply=2\n```\n\n</td><td>\n\n```go\ntype Operation int\n\nconst (\n  Add Operation = iota + 1\n  Subtract\n  Multiply\n)\n\n// Add=1, Subtract=2, Multiply=3\n```\n\n</td></tr>\n</tbody></table>\n\nThere are cases where using the zero value makes sense, for example when the\nzero value case is the desirable default behavior.\n\n```go\ntype LogOutput int\n\nconst (\n  LogToStdout LogOutput = iota\n  LogToFile\n  LogToRemote\n)\n\n// LogToStdout=0, LogToFile=1, LogToRemote=2\n```\n\n<!-- TODO: section on String methods for enums -->\n"
  },
  {
    "path": "src/error-name.md",
    "content": "# Error Naming\n\nFor error values stored as global variables,\nuse the prefix `Err` or `err` depending on whether they're exported.\nThis guidance supersedes the [Prefix Unexported Globals with _](global-name.md).\n\n```go\nvar (\n  // The following two errors are exported\n  // so that users of this package can match them\n  // with errors.Is.\n\n  ErrBrokenLink = errors.New(\"link is broken\")\n  ErrCouldNotOpen = errors.New(\"could not open\")\n\n  // This error is not exported because\n  // we don't want to make it part of our public API.\n  // We may still use it inside the package\n  // with errors.Is.\n\n  errNotFound = errors.New(\"not found\")\n)\n```\n\nFor custom error types, use the suffix `Error` instead.\n\n```go\n// Similarly, this error is exported\n// so that users of this package can match it\n// with errors.As.\n\ntype NotFoundError struct {\n  File string\n}\n\nfunc (e *NotFoundError) Error() string {\n  return fmt.Sprintf(\"file %q not found\", e.File)\n}\n\n// And this error is not exported because\n// we don't want to make it part of the public API.\n// We can still use it inside the package\n// with errors.As.\n\ntype resolveError struct {\n  Path string\n}\n\nfunc (e *resolveError) Error() string {\n  return fmt.Sprintf(\"resolve %q\", e.Path)\n}\n```\n"
  },
  {
    "path": "src/error-once.md",
    "content": "# Handle Errors Once\n\nWhen a caller receives an error from a callee,\nit can handle it in a variety of different ways\ndepending on what it knows about the error.\n\nThese include, but not are limited to:\n\n- if the callee contract defines specific errors,\n  matching the error with `errors.Is` or `errors.As`\n  and handling the branches differently\n- if the error is recoverable,\n  logging the error and degrading gracefully\n- if the error represents a domain-specific failure condition,\n  returning a well-defined error\n- returning the error, either [wrapped](error-wrap.md) or verbatim\n\nRegardless of how the caller handles the error,\nit should typically handle each error only once.\nThe caller should not, for example, log the error and then return it,\nbecause *its* callers may handle the error as well.\n\nFor example, consider the following cases:\n\n<table>\n<thead><tr><th>Description</th><th>Code</th></tr></thead>\n<tbody>\n<tr><td>\n\n**Bad**: Log the error and return it\n\nCallers further up the stack will likely take a similar action with the error.\nDoing so makes a lot of noise in the application logs for little value.\n\n</td><td>\n\n```go\nu, err := getUser(id)\nif err != nil {\n  // BAD: See description\n  log.Printf(\"Could not get user %q: %v\", id, err)\n  return err\n}\n```\n\n</td></tr>\n<tr><td>\n\n**Good**: Wrap the error and return it\n\nCallers further up the stack will handle the error.\nUse of `%w` ensures they can match the error with `errors.Is` or `errors.As`\nif relevant.\n\n</td><td>\n\n```go\nu, err := getUser(id)\nif err != nil {\n  return fmt.Errorf(\"get user %q: %w\", id, err)\n}\n```\n\n</td></tr>\n<tr><td>\n\n**Good**: Log the error and degrade gracefully\n\nIf the operation isn't strictly necessary,\nwe can provide a degraded but unbroken experience\nby recovering from it.\n\n</td><td>\n\n```go\nif err := emitMetrics(); err != nil {\n  // Failure to write metrics should not\n  // break the application.\n  log.Printf(\"Could not emit metrics: %v\", err)\n}\n\n```\n\n</td></tr>\n<tr><td>\n\n**Good**: Match the error and degrade gracefully\n\nIf the callee defines a specific error in its contract,\nand the failure is recoverable,\nmatch on that error case and degrade gracefully.\nFor all other cases, wrap the error and return it.\n\nCallers further up the stack will handle other errors.\n\n</td><td>\n\n```go\ntz, err := getUserTimeZone(id)\nif err != nil {\n  if errors.Is(err, ErrUserNotFound) {\n    // User doesn't exist. Use UTC.\n    tz = time.UTC\n  } else {\n    return fmt.Errorf(\"get user %q: %w\", id, err)\n  }\n}\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/error-type.md",
    "content": "# Error Types\n\nThere are few options for declaring errors.\nConsider the following before picking the option best suited for your use case.\n\n- Does the caller need to match the error so that they can handle it?\n  If yes, we must support the [`errors.Is`] or [`errors.As`] functions\n  by declaring a top-level error variable or a custom type.\n- Is the error message a static string,\n  or is it a dynamic string that requires contextual information?\n  For the former, we can use [`errors.New`], but for the latter we must\n  use [`fmt.Errorf`] or a custom error type.\n- Are we propagating a new error returned by a downstream function?\n  If so, see the [section on error wrapping](error-wrap.md).\n\n[`errors.Is`]: https://pkg.go.dev/errors#Is\n[`errors.As`]: https://pkg.go.dev/errors#As\n\n| Error matching? | Error Message | Guidance                            |\n|-----------------|---------------|-------------------------------------|\n| No              | static        | [`errors.New`]                      |\n| No              | dynamic       | [`fmt.Errorf`]                      |\n| Yes             | static        | top-level `var` with [`errors.New`] |\n| Yes             | dynamic       | custom `error` type                 |\n\n[`errors.New`]: https://pkg.go.dev/errors#New\n[`fmt.Errorf`]: https://pkg.go.dev/fmt#Errorf\n\nFor example,\nuse [`errors.New`] for an error with a static string.\nExport this error as a variable to support matching it with `errors.Is`\nif the caller needs to match and handle this error.\n\n<table>\n<thead><tr><th>No error matching</th><th>Error matching</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// package foo\n\nfunc Open() error {\n  return errors.New(\"could not open\")\n}\n\n// package bar\n\nif err := foo.Open(); err != nil {\n  // Can't handle the error.\n  panic(\"unknown error\")\n}\n```\n\n</td><td>\n\n```go\n// package foo\n\nvar ErrCouldNotOpen = errors.New(\"could not open\")\n\nfunc Open() error {\n  return ErrCouldNotOpen\n}\n\n// package bar\n\nif err := foo.Open(); err != nil {\n  if errors.Is(err, foo.ErrCouldNotOpen) {\n    // handle the error\n  } else {\n    panic(\"unknown error\")\n  }\n}\n```\n\n</td></tr>\n</tbody></table>\n\nFor an error with a dynamic string,\nuse [`fmt.Errorf`] if the caller does not need to match it,\nand a custom `error` if the caller does need to match it.\n\n<table>\n<thead><tr><th>No error matching</th><th>Error matching</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// package foo\n\nfunc Open(file string) error {\n  return fmt.Errorf(\"file %q not found\", file)\n}\n\n// package bar\n\nif err := foo.Open(\"testfile.txt\"); err != nil {\n  // Can't handle the error.\n  panic(\"unknown error\")\n}\n```\n\n</td><td>\n\n```go\n// package foo\n\ntype NotFoundError struct {\n  File string\n}\n\nfunc (e *NotFoundError) Error() string {\n  return fmt.Sprintf(\"file %q not found\", e.File)\n}\n\nfunc Open(file string) error {\n  return &NotFoundError{File: file}\n}\n\n\n// package bar\n\nif err := foo.Open(\"testfile.txt\"); err != nil {\n  var notFound *NotFoundError\n  if errors.As(err, &notFound) {\n    // handle the error\n  } else {\n    panic(\"unknown error\")\n  }\n}\n```\n\n</td></tr>\n</tbody></table>\n\nNote that if you export error variables or types from a package,\nthey will become part of the public API of the package.\n"
  },
  {
    "path": "src/error-wrap.md",
    "content": "# Error Wrapping\n\nThere are three main options for propagating errors if a call fails:\n\n- return the original error as-is\n- add context with `fmt.Errorf` and the `%w` verb\n- add context with `fmt.Errorf` and the `%v` verb\n\nReturn the original error as-is if there is no additional context to add.\nThis maintains the original error type and message.\nThis is well suited for cases when the underlying error message\nhas sufficient information to track down where it came from.\n\nOtherwise, add context to the error message where possible\nso that instead of a vague error such as \"connection refused\",\nyou get more useful errors such as \"call service foo: connection refused\".\n\nUse `fmt.Errorf` to add context to your errors,\npicking between the `%w` or `%v` verbs\nbased on whether the caller should be able to\nmatch and extract the underlying cause.\n\n- Use `%w` if the caller should have access to the underlying error.\n  This is a good default for most wrapped errors,\n  but be aware that callers may begin to rely on this behavior.\n  So for cases where the wrapped error is a known `var` or type,\n  document and test it as part of your function's contract.\n- Use `%v` to obfuscate the underlying error.\n  Callers will be unable to match it,\n  but you can switch to `%w` in the future if needed.\n\nWhen adding context to returned errors, keep the context succinct by avoiding\nphrases like \"failed to\", which state the obvious and pile up as the error\npercolates up through the stack:\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ns, err := store.New()\nif err != nil {\n    return fmt.Errorf(\n        \"failed to create new store: %w\", err)\n}\n```\n\n</td><td>\n\n```go\ns, err := store.New()\nif err != nil {\n    return fmt.Errorf(\n        \"new store: %w\", err)\n}\n```\n\n</td></tr><tr><td>\n\n```plain\nfailed to x: failed to y: failed to create new store: the error\n```\n\n</td><td>\n\n```plain\nx: y: new store: the error\n```\n\n</td></tr>\n</tbody></table>\n\nHowever once the error is sent to another system, it should be clear the\nmessage is an error (e.g. an `err` tag or \"Failed\" prefix in logs).\n\nSee also [Don't just check errors, handle them gracefully].\n\n  [Don't just check errors, handle them gracefully]: https://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully\n"
  },
  {
    "path": "src/exit-main.md",
    "content": "# Exit in Main\n\nGo programs use [`os.Exit`] or [`log.Fatal*`] to exit immediately. (Panicking\nis not a good way to exit programs, please [don't panic](panic.md).)\n\n  [`os.Exit`]: https://pkg.go.dev/os#Exit\n  [`log.Fatal*`]: https://pkg.go.dev/log#Fatal\n\nCall one of `os.Exit` or `log.Fatal*` **only in `main()`**. All other\nfunctions should return errors to signal failure.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc main() {\n  body := readFile(path)\n  fmt.Println(body)\n}\n\nfunc readFile(path string) string {\n  f, err := os.Open(path)\n  if err != nil {\n    log.Fatal(err)\n  }\n\n  b, err := io.ReadAll(f)\n  if err != nil {\n    log.Fatal(err)\n  }\n\n  return string(b)\n}\n```\n\n</td><td>\n\n```go\nfunc main() {\n  body, err := readFile(path)\n  if err != nil {\n    log.Fatal(err)\n  }\n  fmt.Println(body)\n}\n\nfunc readFile(path string) (string, error) {\n  f, err := os.Open(path)\n  if err != nil {\n    return \"\", err\n  }\n\n  b, err := io.ReadAll(f)\n  if err != nil {\n    return \"\", err\n  }\n\n  return string(b), nil\n}\n```\n\n</td></tr>\n</tbody></table>\n\nRationale: Programs with multiple functions that exit present a few issues:\n\n- Non-obvious control flow: Any function can exit the program so it becomes\n  difficult to reason about the control flow.\n- Difficult to test: A function that exits the program will also exit the test\n  calling it. This makes the function difficult to test and introduces risk of\n  skipping other tests that have not yet been run by `go test`.\n- Skipped cleanup: When a function exits the program, it skips function calls\n  enqueued with `defer` statements. This adds risk of skipping important\n  cleanup tasks.\n"
  },
  {
    "path": "src/exit-once.md",
    "content": "# Exit Once\n\nIf possible, prefer to call `os.Exit` or `log.Fatal` **at most once** in your\n`main()`. If there are multiple error scenarios that halt program execution,\nput that logic under a separate function and return errors from it.\n\nThis has the effect of shortening your `main()` function and putting all key\nbusiness logic into a separate, testable function.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\npackage main\n\nfunc main() {\n  args := os.Args[1:]\n  if len(args) != 1 {\n    log.Fatal(\"missing file\")\n  }\n  name := args[0]\n\n  f, err := os.Open(name)\n  if err != nil {\n    log.Fatal(err)\n  }\n  defer f.Close()\n\n  // If we call log.Fatal after this line,\n  // f.Close will not be called.\n\n  b, err := io.ReadAll(f)\n  if err != nil {\n    log.Fatal(err)\n  }\n\n  // ...\n}\n```\n\n</td><td>\n\n```go\npackage main\n\nfunc main() {\n  if err := run(); err != nil {\n    log.Fatal(err)\n  }\n}\n\nfunc run() error {\n  args := os.Args[1:]\n  if len(args) != 1 {\n    return errors.New(\"missing file\")\n  }\n  name := args[0]\n\n  f, err := os.Open(name)\n  if err != nil {\n    return err\n  }\n  defer f.Close()\n\n  b, err := io.ReadAll(f)\n  if err != nil {\n    return err\n  }\n\n  // ...\n}\n```\n\n</td></tr>\n</tbody></table>\n\nThe example above uses `log.Fatal`, but the guidance also applies to\n`os.Exit` or any library code that calls `os.Exit`.\n\n```go\nfunc main() {\n  if err := run(); err != nil {\n    fmt.Fprintln(os.Stderr, err)\n    os.Exit(1)\n  }\n}\n```\n\nYou may alter the signature of `run()` to fit your needs.\nFor example, if your program must exit with specific exit codes for failures,\n`run()` may return the exit code instead of an error.\nThis allows unit tests to verify this behavior directly as well.\n\n```go\nfunc main() {\n  os.Exit(run(args))\n}\n\nfunc run() (exitCode int) {\n  // ...\n}\n```\n\nMore generally, note that the `run()` function used in these examples\nis not intended to be prescriptive.\nThere's flexibility in the name, signature, and setup of the `run()` function.\nAmong other things, you may:\n\n- accept unparsed command line arguments (e.g., `run(os.Args[1:])`)\n- parse command line arguments in `main()` and pass them onto `run`\n- use a custom error type to carry the exit code back to `main()`\n- put business logic in a different layer of abstraction from `package main`\n\nThis guidance only requires that there's a single place in your `main()`\nresponsible for actually exiting the process.\n"
  },
  {
    "path": "src/function-name.md",
    "content": "# Function Names\n\nWe follow the Go community's convention of using [MixedCaps for function\nnames]. An exception is made for test functions, which may contain underscores\nfor the purpose of grouping related test cases, e.g.,\n`TestMyFunction_WhatIsBeingTested`.\n\n  [MixedCaps for function names]: https://go.dev/doc/effective_go#mixed-caps\n"
  },
  {
    "path": "src/function-order.md",
    "content": "# Function Grouping and Ordering\n\n- Functions should be sorted in rough call order.\n- Functions in a file should be grouped by receiver.\n\nTherefore, exported functions should appear first in a file, after\n`struct`, `const`, `var` definitions.\n\nA `newXYZ()`/`NewXYZ()` may appear after the type is defined, but before the\nrest of the methods on the receiver.\n\nSince functions are grouped by receiver, plain utility functions should appear\ntowards the end of the file.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc (s *something) Cost() {\n  return calcCost(s.weights)\n}\n\ntype something struct{ ... }\n\nfunc calcCost(n []int) int {...}\n\nfunc (s *something) Stop() {...}\n\nfunc newSomething() *something {\n    return &something{}\n}\n```\n\n</td><td>\n\n```go\ntype something struct{ ... }\n\nfunc newSomething() *something {\n    return &something{}\n}\n\nfunc (s *something) Cost() {\n  return calcCost(s.weights)\n}\n\nfunc (s *something) Stop() {...}\n\nfunc calcCost(n []int) int {...}\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/functional-option.md",
    "content": "# Functional Options\n\nFunctional options is a pattern in which you declare an opaque `Option` type\nthat records information in some internal struct. You accept a variadic number\nof these options and act upon the full information recorded by the options on\nthe internal struct.\n\nUse this pattern for optional arguments in constructors and other public APIs\nthat you foresee needing to expand, especially if you already have three or\nmore arguments on those functions.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// package db\n\nfunc Open(\n  addr string,\n  cache bool,\n  logger *zap.Logger\n) (*Connection, error) {\n  // ...\n}\n```\n\n</td><td>\n\n```go\n// package db\n\ntype Option interface {\n  // ...\n}\n\nfunc WithCache(c bool) Option {\n  // ...\n}\n\nfunc WithLogger(log *zap.Logger) Option {\n  // ...\n}\n\n// Open creates a connection.\nfunc Open(\n  addr string,\n  opts ...Option,\n) (*Connection, error) {\n  // ...\n}\n```\n\n</td></tr>\n<tr><td>\n\nThe cache and logger parameters must always be provided, even if the user\nwants to use the default.\n\n```go\ndb.Open(addr, db.DefaultCache, zap.NewNop())\ndb.Open(addr, db.DefaultCache, log)\ndb.Open(addr, false /* cache */, zap.NewNop())\ndb.Open(addr, false /* cache */, log)\n```\n\n</td><td>\n\nOptions are provided only if needed.\n\n```go\ndb.Open(addr)\ndb.Open(addr, db.WithLogger(log))\ndb.Open(addr, db.WithCache(false))\ndb.Open(\n  addr,\n  db.WithCache(false),\n  db.WithLogger(log),\n)\n```\n\n</td></tr>\n</tbody></table>\n\nOur suggested way of implementing this pattern is with an `Option` interface\nthat holds an unexported method, recording options on an unexported `options`\nstruct.\n\n```go\ntype options struct {\n  cache  bool\n  logger *zap.Logger\n}\n\ntype Option interface {\n  apply(*options)\n}\n\ntype cacheOption bool\n\nfunc (c cacheOption) apply(opts *options) {\n  opts.cache = bool(c)\n}\n\nfunc WithCache(c bool) Option {\n  return cacheOption(c)\n}\n\ntype loggerOption struct {\n  Log *zap.Logger\n}\n\nfunc (l loggerOption) apply(opts *options) {\n  opts.logger = l.Log\n}\n\nfunc WithLogger(log *zap.Logger) Option {\n  return loggerOption{Log: log}\n}\n\n// Open creates a connection.\nfunc Open(\n  addr string,\n  opts ...Option,\n) (*Connection, error) {\n  options := options{\n    cache:  defaultCache,\n    logger: zap.NewNop(),\n  }\n\n  for _, o := range opts {\n    o.apply(&options)\n  }\n\n  // ...\n}\n```\n\nNote that there's a method of implementing this pattern with closures but we\nbelieve that the pattern above provides more flexibility for authors and is\neasier to debug and test for users. In particular, it allows options to be\ncompared against each other in tests and mocks, versus closures where this is\nimpossible. Further, it lets options implement other interfaces, including\n`fmt.Stringer` which allows for user-readable string representations of the\noptions.\n\nSee also,\n\n- [Self-referential functions and the design of options]\n- [Functional options for friendly APIs]\n\n  [Self-referential functions and the design of options]: https://commandcenter.blogspot.com/2014/01/self-referential-functions-and-design.html\n  [Functional options for friendly APIs]: https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis\n\n<!-- TODO: replace this with parameter structs and functional options, when to\nuse one vs other -->\n"
  },
  {
    "path": "src/global-decl.md",
    "content": "# Top-level Variable Declarations\n\nAt the top level, use the standard `var` keyword. Do not specify the type,\nunless it is not the same type as the expression.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nvar _s string = F()\n\nfunc F() string { return \"A\" }\n```\n\n</td><td>\n\n```go\nvar _s = F()\n// Since F already states that it returns a string, we don't need to specify\n// the type again.\n\nfunc F() string { return \"A\" }\n```\n\n</td></tr>\n</tbody></table>\n\nSpecify the type if the type of the expression does not match the desired type\nexactly.\n\n```go\ntype myError struct{}\n\nfunc (myError) Error() string { return \"error\" }\n\nfunc F() myError { return myError{} }\n\nvar _e error = F()\n// F returns an object of type myError but we want error.\n```\n"
  },
  {
    "path": "src/global-mut.md",
    "content": "# Avoid Mutable Globals\n\nAvoid mutating global variables, instead opting for dependency injection.\nThis applies to function pointers as well as other kinds of values.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// sign.go\n\nvar _timeNow = time.Now\n\nfunc sign(msg string) string {\n  now := _timeNow()\n  return signWithTime(msg, now)\n}\n```\n\n</td><td>\n\n```go\n// sign.go\n\ntype signer struct {\n  now func() time.Time\n}\n\nfunc newSigner() *signer {\n  return &signer{\n    now: time.Now,\n  }\n}\n\nfunc (s *signer) Sign(msg string) string {\n  now := s.now()\n  return signWithTime(msg, now)\n}\n```\n\n</td></tr>\n<tr><td>\n\n```go\n// sign_test.go\n\nfunc TestSign(t *testing.T) {\n  oldTimeNow := _timeNow\n  _timeNow = func() time.Time {\n    return someFixedTime\n  }\n  defer func() { _timeNow = oldTimeNow }()\n\n  assert.Equal(t, want, sign(give))\n}\n```\n\n</td><td>\n\n```go\n// sign_test.go\n\nfunc TestSigner(t *testing.T) {\n  s := newSigner()\n  s.now = func() time.Time {\n    return someFixedTime\n  }\n\n  assert.Equal(t, want, s.Sign(give))\n}\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/global-name.md",
    "content": "# Prefix Unexported Globals with _\n\nPrefix unexported top-level `var`s and `const`s with `_` to make it clear when\nthey are used that they are global symbols.\n\nRationale: Top-level variables and constants have a package scope. Using a\ngeneric name makes it easy to accidentally use the wrong value in a different\nfile.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// foo.go\n\nconst (\n  defaultPort = 8080\n  defaultUser = \"user\"\n)\n\n// bar.go\n\nfunc Bar() {\n  defaultPort := 9090\n  ...\n  fmt.Println(\"Default port\", defaultPort)\n\n  // We will not see a compile error if the first line of\n  // Bar() is deleted.\n}\n```\n\n</td><td>\n\n```go\n// foo.go\n\nconst (\n  _defaultPort = 8080\n  _defaultUser = \"user\"\n)\n```\n\n</td></tr>\n</tbody></table>\n\n**Exception**: Unexported error values may use the prefix `err` without the underscore.\nSee [Error Naming](error-name.md).\n"
  },
  {
    "path": "src/goroutine-exit.md",
    "content": "# Wait for goroutines to exit\n\nGiven a goroutine spawned by the system,\nthere must be a way to wait for the goroutine to exit.\nThere are two popular ways to do this:\n\n- Use a `sync.WaitGroup` to wait for multiple goroutines to complete.\n  Do this if there are multiple goroutines that you want to wait for.\n\n    ```go\n    var wg sync.WaitGroup\n    for i := 0; i < N; i++ {\n      wg.Go(...)\n    }\n\n    // To wait for all to finish:\n    wg.Wait()\n    ```\n\n- Add another `chan struct{}` that the goroutine closes when it's done.\n  Do this if there's only one goroutine.\n\n    ```go\n    done := make(chan struct{})\n    go func() {\n      defer close(done)\n      // ...\n    }()\n\n    // To wait for the goroutine to finish:\n    <-done\n    ```\n"
  },
  {
    "path": "src/goroutine-forget.md",
    "content": "# Don't fire-and-forget goroutines\n\nGoroutines are lightweight, but they're not free:\nat minimum, they cost memory for their stack and CPU to be scheduled.\nWhile these costs are small for typical uses of goroutines,\nthey can cause significant performance issues\nwhen spawned in large numbers without controlled lifetimes.\nGoroutines with unmanaged lifetimes can also cause other issues\nlike preventing unused objects from being garbage collected\nand holding onto resources that are otherwise no longer used.\n\nTherefore, do not leak goroutines in production code.\nUse [go.uber.org/goleak](https://pkg.go.dev/go.uber.org/goleak)\nto test for goroutine leaks inside packages that may spawn goroutines.\n\nIn general, every goroutine:\n\n- must have a predictable time at which it will stop running; or\n- there must be a way to signal to the goroutine that it should stop\n\nIn both cases, there must be a way for code to block and wait for the goroutine to\nfinish.\n\nFor example:\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ngo func() {\n  for {\n    flush()\n    time.Sleep(delay)\n  }\n}()\n```\n\n</td><td>\n\n```go\nvar (\n  stop = make(chan struct{}) // tells the goroutine to stop\n  done = make(chan struct{}) // tells us that the goroutine exited\n)\ngo func() {\n  defer close(done)\n\n  ticker := time.NewTicker(delay)\n  defer ticker.Stop()\n  for {\n    select {\n    case <-ticker.C:\n      flush()\n    case <-stop:\n      return\n    }\n  }\n}()\n\n// Elsewhere...\nclose(stop)  // signal the goroutine to stop\n<-done       // and wait for it to exit\n```\n\n</td></tr>\n<tr><td>\n\nThere's no way to stop this goroutine.\nThis will run until the application exits.\n\n</td><td>\n\nThis goroutine can be stopped with `close(stop)`,\nand we can wait for it to exit with `<-done`.\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/goroutine-init.md",
    "content": "# No goroutines in `init()`\n\n`init()` functions should not spawn goroutines.\nSee also [Avoid init()](init.md).\n\nIf a package has need of a background goroutine,\nit must expose an object that is responsible for managing a goroutine's\nlifetime.\nThe object must provide a method (`Close`, `Stop`, `Shutdown`, etc)\nthat signals the background goroutine to stop, and waits for it to exit.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc init() {\n  go doWork()\n}\n\nfunc doWork() {\n  for {\n    // ...\n  }\n}\n```\n\n</td><td>\n\n```go\ntype Worker struct{ /* ... */ }\n\nfunc NewWorker(...) *Worker {\n  w := &Worker{\n    stop: make(chan struct{}),\n    done: make(chan struct{}),\n    // ...\n  }\n  go w.doWork()\n  return w\n}\n\nfunc (w *Worker) doWork() {\n  defer close(w.done)\n  for {\n    // ...\n    case <-w.stop:\n      return\n  }\n}\n\n// Shutdown tells the worker to stop\n// and waits until it has finished.\nfunc (w *Worker) Shutdown() {\n  close(w.stop)\n  <-w.done\n}\n```\n\n</td></tr>\n<tr><td>\n\nSpawns a background goroutine unconditionally when the user exports this package.\nThe user has no control over the goroutine or a means of stopping it.\n\n</td><td>\n\nSpawns the worker only if the user requests it.\nProvides a means of shutting down the worker so that the user can free up\nresources used by the worker.\n\nNote that you should use `WaitGroup`s if the worker manages multiple\ngoroutines.\nSee [Wait for goroutines to exit](goroutine-exit.md).\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/import-alias.md",
    "content": "# Import Aliasing\n\nImport aliasing must be used if the package name does not match the last\nelement of the import path.\n\n```go\nimport (\n  \"net/http\"\n\n  client \"example.com/client-go\"\n  trace \"example.com/trace/v2\"\n)\n```\n\nIn all other scenarios, import aliases should be avoided unless there is a\ndirect conflict between imports.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nimport (\n  \"fmt\"\n  \"os\"\n  runtimetrace \"runtime/trace\"\n\n  nettrace \"golang.net/x/trace\"\n)\n```\n\n</td><td>\n\n```go\nimport (\n  \"fmt\"\n  \"os\"\n  \"runtime/trace\"\n\n  nettrace \"golang.net/x/trace\"\n)\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/import-group.md",
    "content": "# Import Group Ordering\n\nThere should be two import groups:\n\n- Standard library\n- Everything else\n\nThis is the grouping applied by goimports by default.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nimport (\n  \"fmt\"\n  \"os\"\n  \"go.uber.org/atomic\"\n  \"golang.org/x/sync/errgroup\"\n)\n```\n\n</td><td>\n\n```go\nimport (\n  \"fmt\"\n  \"os\"\n\n  \"go.uber.org/atomic\"\n  \"golang.org/x/sync/errgroup\"\n)\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/init.md",
    "content": "# Avoid `init()`\n\nAvoid `init()` where possible. When `init()` is unavoidable or desirable, code\nshould attempt to:\n\n1. Be completely deterministic, regardless of program environment or invocation.\n2. Avoid depending on the ordering or side-effects of other `init()` functions.\n   While `init()` ordering is well-known, code can change, and thus\n   relationships between `init()` functions can make code brittle and\n   error-prone.\n3. Avoid accessing or manipulating global or environment state, such as machine\n   information, environment variables, working directory, program\n   arguments/inputs, etc.\n4. Avoid I/O, including both filesystem, network, and system calls.\n\nCode that cannot satisfy these requirements likely belongs as a helper to be\ncalled as part of `main()` (or elsewhere in a program's lifecycle), or be\nwritten as part of `main()` itself. In particular, libraries that are intended\nto be used by other programs should take special care to be completely\ndeterministic and not perform \"init magic\".\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype Foo struct {\n    // ...\n}\n\nvar _defaultFoo Foo\n\nfunc init() {\n    _defaultFoo = Foo{\n        // ...\n    }\n}\n```\n\n</td><td>\n\n```go\nvar _defaultFoo = Foo{\n    // ...\n}\n\n// or, better, for testability:\n\nvar _defaultFoo = defaultFoo()\n\nfunc defaultFoo() Foo {\n    return Foo{\n        // ...\n    }\n}\n```\n\n</td></tr>\n<tr><td>\n\n```go\ntype Config struct {\n    // ...\n}\n\nvar _config Config\n\nfunc init() {\n    // Bad: based on current directory\n    cwd, _ := os.Getwd()\n\n    // Bad: I/O\n    raw, _ := os.ReadFile(\n        path.Join(cwd, \"config\", \"config.yaml\"),\n    )\n\n    yaml.Unmarshal(raw, &_config)\n}\n```\n\n</td><td>\n\n```go\ntype Config struct {\n    // ...\n}\n\nfunc loadConfig() Config {\n    cwd, err := os.Getwd()\n    // handle err\n\n    raw, err := os.ReadFile(\n        path.Join(cwd, \"config\", \"config.yaml\"),\n    )\n    // handle err\n\n    var config Config\n    yaml.Unmarshal(raw, &config)\n\n    return config\n}\n```\n\n</td></tr>\n</tbody></table>\n\nConsidering the above, some situations in which `init()` may be preferable or\nnecessary might include:\n\n- Complex expressions that cannot be represented as single assignments.\n- Pluggable hooks, such as `database/sql` dialects, encoding type registries, etc.\n- Optimizations to [Google Cloud Functions] and other forms of deterministic\n  precomputation.\n\n  [Google Cloud Functions]: https://cloud.google.com/functions/docs/bestpractices/tips#use_global_variables_to_reuse_objects_in_future_invocations\n"
  },
  {
    "path": "src/interface-compliance.md",
    "content": "# Verify Interface Compliance\n\nVerify interface compliance at compile time where appropriate. This includes:\n\n- Exported types that are required to implement specific interfaces as part of\n  their API contract\n- Exported or unexported types that are part of a collection of types\n  implementing the same interface\n- Other cases where violating an interface would break users\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype Handler struct {\n  // ...\n}\n\n\n\nfunc (h *Handler) ServeHTTP(\n  w http.ResponseWriter,\n  r *http.Request,\n) {\n  ...\n}\n```\n\n</td><td>\n\n```go\ntype Handler struct {\n  // ...\n}\n\nvar _ http.Handler = (*Handler)(nil)\n\nfunc (h *Handler) ServeHTTP(\n  w http.ResponseWriter,\n  r *http.Request,\n) {\n  // ...\n}\n```\n\n</td></tr>\n</tbody></table>\n\nThe statement `var _ http.Handler = (*Handler)(nil)` will fail to compile if\n`*Handler` ever stops matching the `http.Handler` interface.\n\nThe right hand side of the assignment should be the zero value of the asserted\ntype. This is `nil` for pointer types (like `*Handler`), slices, and maps, and\nan empty struct for struct types.\n\n```go\ntype LogHandler struct {\n  h   http.Handler\n  log *zap.Logger\n}\n\nvar _ http.Handler = LogHandler{}\n\nfunc (h LogHandler) ServeHTTP(\n  w http.ResponseWriter,\n  r *http.Request,\n) {\n  // ...\n}\n```\n"
  },
  {
    "path": "src/interface-pointer.md",
    "content": "# Pointers to Interfaces\n\nYou almost never need a pointer to an interface. You should be passing\ninterfaces as values—the underlying data can still be a pointer.\n\nAn interface is two fields:\n\n1. A pointer to some type-specific information. You can think of this as\n  \"type.\"\n2. Data pointer. If the data stored is a pointer, it’s stored directly. If\n  the data stored is a value, then a pointer to the value is stored.\n\nIf you want interface methods to modify the underlying data, you must use a\npointer.\n"
  },
  {
    "path": "src/interface-receiver.md",
    "content": "# Receivers and Interfaces\n\nMethods with value receivers can be called on pointers as well as values.\nMethods with pointer receivers can only be called on pointers or [addressable values].\n\n  [addressable values]: https://go.dev/ref/spec#Method_values\n\nFor example,\n\n```go\ntype S struct {\n  data string\n}\n\nfunc (s S) Read() string {\n  return s.data\n}\n\nfunc (s *S) Write(str string) {\n  s.data = str\n}\n\n// We cannot get pointers to values stored in maps, because they are not\n// addressable values.\nsVals := map[int]S{1: {\"A\"}}\n\n// We can call Read on values stored in the map because Read\n// has a value receiver, which does not require the value to\n// be addressable.\nsVals[1].Read()\n\n// We cannot call Write on values stored in the map because Write\n// has a pointer receiver, and it's not possible to get a pointer\n// to a value stored in a map.\n//\n//  sVals[1].Write(\"test\")\n\nsPtrs := map[int]*S{1: {\"A\"}}\n\n// You can call both Read and Write if the map stores pointers,\n// because pointers are intrinsically addressable.\nsPtrs[1].Read()\nsPtrs[1].Write(\"test\")\n```\n\nSimilarly, an interface can be satisfied by a pointer, even if the method has a\nvalue receiver.\n\n```go\ntype F interface {\n  f()\n}\n\ntype S1 struct{}\n\nfunc (s S1) f() {}\n\ntype S2 struct{}\n\nfunc (s *S2) f() {}\n\ns1Val := S1{}\ns1Ptr := &S1{}\ns2Val := S2{}\ns2Ptr := &S2{}\n\nvar i F\ni = s1Val\ni = s1Ptr\ni = s2Ptr\n\n// The following doesn't compile, since s2Val is a value, and there is no value receiver for f.\n//   i = s2Val\n```\n\nEffective Go has a good write up on [Pointers vs. Values].\n\n  [Pointers vs. Values]: https://go.dev/doc/effective_go#pointers_vs_values\n"
  },
  {
    "path": "src/intro.md",
    "content": "# Introduction\n\nStyles are the conventions that govern our code. The term style is a bit of a\nmisnomer, since these conventions cover far more than just source file\nformatting—gofmt handles that for us.\n\nThe goal of this guide is to manage this complexity by describing in detail the\nDos and Don'ts of writing Go code at Uber. These rules exist to keep the code\nbase manageable while still allowing engineers to use Go language features\nproductively.\n\nThis guide was originally created by [Prashant Varanasi] and [Simon Newton] as\na way to bring some colleagues up to speed with using Go. Over the years it has\nbeen amended based on feedback from others.\n\n  [Prashant Varanasi]: https://github.com/prashantv\n  [Simon Newton]: https://github.com/nomis52\n\nThis documents idiomatic conventions in Go code that we follow at Uber. A lot\nof these are general guidelines for Go, while others extend upon external\nresources:\n\n1. [Effective Go](https://go.dev/doc/effective_go)\n2. [Go Common Mistakes](https://go.dev/wiki/CommonMistakes)\n3. [Go Code Review Comments](https://go.dev/wiki/CodeReviewComments)\n\nWe aim for the code samples to be accurate for the two most recent minor versions\nof Go [releases](https://go.dev/doc/devel/release).\n\nAll code should be error-free when run through `golint` and `go vet`. We\nrecommend setting up your editor to:\n\n- Run `goimports` on save\n- Run `golint` and `go vet` to check for errors\n\nYou can find information in editor support for Go tools here:\n<https://go.dev/wiki/IDEsAndTextEditorPlugins>\n"
  },
  {
    "path": "src/line-length.md",
    "content": "# Avoid overly long lines\n\nAvoid lines of code that require readers to scroll horizontally\nor turn their heads too much.\n\nWe recommend a soft line length limit of **99 characters**.\nAuthors should aim to wrap lines before hitting this limit,\nbut it is not a hard limit.\nCode is allowed to exceed this limit.\n"
  },
  {
    "path": "src/lint.md",
    "content": "# Linting\n\nMore importantly than any \"blessed\" set of linters, lint consistently across a\ncodebase.\n\nWe recommend using the following linters at a minimum, because we feel that they\nhelp to catch the most common issues and also establish a high bar for code\nquality without being unnecessarily prescriptive:\n\n- [errcheck] to ensure that errors are handled\n- [goimports] to format code and manage imports\n- [revive] to point out common style mistakes\n- [govet] to analyze code for common mistakes\n- [staticcheck] to do various static analysis checks\n\n  [errcheck]: https://github.com/kisielk/errcheck\n  [goimports]: https://pkg.go.dev/golang.org/x/tools/cmd/goimports\n  [revive]: https://github.com/mgechev/revive\n  [govet]: https://pkg.go.dev/cmd/vet\n  [staticcheck]: https://staticcheck.dev\n\n  > **Note**: [revive] is the modern, faster successor to the now-deprecated [golint].\n\n## Lint Runners\n\nWe recommend [golangci-lint] as the go-to lint runner for Go code, largely due\nto its performance in larger codebases and ability to configure and use many\ncanonical linters at once. This repo has an example [.golangci.yml] config file\nwith recommended linters and settings.\n\ngolangci-lint has [various linters] available for use. The above linters are\nrecommended as a base set, and we encourage teams to add any additional linters\nthat make sense for their projects.\n\n  [golangci-lint]: https://github.com/golangci/golangci-lint\n  [.golangci.yml]: https://github.com/uber-go/guide/blob/master/.golangci.yml\n  [various linters]: https://golangci-lint.run/usage/linters/\n  [golint]: https://github.com/golang/lint\n  \n"
  },
  {
    "path": "src/map-init.md",
    "content": "# Initializing Maps\n\nPrefer `make(..)` for empty maps, and maps populated\nprogrammatically. This makes map initialization visually\ndistinct from declaration, and it makes it easy to add size\nhints later if available.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nvar (\n  // m1 is safe to read and write;\n  // m2 will panic on writes.\n  m1 = map[T1]T2{}\n  m2 map[T1]T2\n)\n```\n\n</td><td>\n\n```go\nvar (\n  // m1 is safe to read and write;\n  // m2 will panic on writes.\n  m1 = make(map[T1]T2)\n  m2 map[T1]T2\n)\n```\n\n</td></tr>\n<tr><td>\n\nDeclaration and initialization are visually similar.\n\n</td><td>\n\nDeclaration and initialization are visually distinct.\n\n</td></tr>\n</tbody></table>\n\nWhere possible, provide capacity hints when initializing\nmaps with `make()`. See\n[Specifying Map Capacity Hints](container-capacity.md#specifying-map-capacity-hints)\nfor more information.\n\nOn the other hand, if the map holds a fixed list of elements,\nuse map literals to initialize the map.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nm := make(map[T1]T2, 3)\nm[k1] = v1\nm[k2] = v2\nm[k3] = v3\n```\n\n</td><td>\n\n```go\nm := map[T1]T2{\n  k1: v1,\n  k2: v2,\n  k3: v3,\n}\n```\n\n</td></tr>\n</tbody></table>\n\nThe basic rule of thumb is to use map literals when adding a fixed set of\nelements at initialization time, otherwise use `make` (and specify a size hint\nif available).\n"
  },
  {
    "path": "src/mutex-zero-value.md",
    "content": "# Zero-value Mutexes are Valid\n\nThe zero-value of `sync.Mutex` and `sync.RWMutex` is valid, so you almost\nnever need a pointer to a mutex.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nmu := new(sync.Mutex)\nmu.Lock()\n```\n\n</td><td>\n\n```go\nvar mu sync.Mutex\nmu.Lock()\n```\n\n</td></tr>\n</tbody></table>\n\nIf you use a struct by pointer, then the mutex should be a non-pointer field on\nit. Do not embed the mutex on the struct, even if the struct is not exported.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype SMap struct {\n  sync.Mutex\n\n  data map[string]string\n}\n\nfunc NewSMap() *SMap {\n  return &SMap{\n    data: make(map[string]string),\n  }\n}\n\nfunc (m *SMap) Get(k string) string {\n  m.Lock()\n  defer m.Unlock()\n\n  return m.data[k]\n}\n```\n\n</td><td>\n\n```go\ntype SMap struct {\n  mu sync.Mutex\n\n  data map[string]string\n}\n\nfunc NewSMap() *SMap {\n  return &SMap{\n    data: make(map[string]string),\n  }\n}\n\nfunc (m *SMap) Get(k string) string {\n  m.mu.Lock()\n  defer m.mu.Unlock()\n\n  return m.data[k]\n}\n```\n\n</td></tr>\n\n<tr><td>\n\nThe `Mutex` field, and the `Lock` and `Unlock` methods are unintentionally part\nof the exported API of `SMap`.\n\n</td><td>\n\nThe mutex and its methods are implementation details of `SMap` hidden from its\ncallers.\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/nest-less.md",
    "content": "# Reduce Nesting\n\nCode should reduce nesting where possible by handling error cases/special\nconditions first and returning early or continuing the loop. Reduce the amount\nof code that is nested multiple levels.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfor _, v := range data {\n  if v.F1 == 1 {\n    v = process(v)\n    if err := v.Call(); err == nil {\n      v.Send()\n    } else {\n      return err\n    }\n  } else {\n    log.Printf(\"Invalid v: %v\", v)\n  }\n}\n```\n\n</td><td>\n\n```go\nfor _, v := range data {\n  if v.F1 != 1 {\n    log.Printf(\"Invalid v: %v\", v)\n    continue\n  }\n\n  v = process(v)\n  if err := v.Call(); err != nil {\n    return err\n  }\n  v.Send()\n}\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/package-name.md",
    "content": "# Package Names\n\nWhen naming packages, choose a name that is:\n\n- All lower-case. No capitals or underscores.\n- Does not need to be renamed using named imports at most call sites.\n- Short and succinct. Remember that the name is identified in full at every call\n  site.\n- Not plural. For example, `net/url`, not `net/urls`.\n- Not \"common\", \"util\", \"shared\", or \"lib\". These are bad, uninformative names.\n\nSee also [Package Names] and [Style guideline for Go packages].\n\n  [Package Names]: https://go.dev/blog/package-names\n  [Style guideline for Go packages]: https://rakyll.org/style-packages/\n"
  },
  {
    "path": "src/panic.md",
    "content": "# Don't Panic\n\nCode running in production must avoid panics. Panics are a major source of\n[cascading failures]. If an error occurs, the function must return an error and\nallow the caller to decide how to handle it.\n\n  [cascading failures]: https://en.wikipedia.org/wiki/Cascading_failure\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc run(args []string) {\n  if len(args) == 0 {\n    panic(\"an argument is required\")\n  }\n  // ...\n}\n\nfunc main() {\n  run(os.Args[1:])\n}\n```\n\n</td><td>\n\n```go\nfunc run(args []string) error {\n  if len(args) == 0 {\n    return errors.New(\"an argument is required\")\n  }\n  // ...\n  return nil\n}\n\nfunc main() {\n  if err := run(os.Args[1:]); err != nil {\n    fmt.Fprintln(os.Stderr, err)\n    os.Exit(1)\n  }\n}\n```\n\n</td></tr>\n</tbody></table>\n\nPanic/recover is not an error handling strategy. A program must panic only when\nsomething irrecoverable happens such as a nil dereference. An exception to this is\nprogram initialization: bad things at program startup that should abort the\nprogram may cause panic.\n\n```go\nvar _statusTemplate = template.Must(template.New(\"name\").Parse(\"_statusHTML\"))\n```\n\nEven in tests, prefer `t.Fatal` or `t.FailNow` over panics to ensure that the\ntest is marked as failed.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// func TestFoo(t *testing.T)\n\nf, err := os.CreateTemp(\"\", \"test\")\nif err != nil {\n  panic(\"failed to set up test\")\n}\n```\n\n</td><td>\n\n```go\n// func TestFoo(t *testing.T)\n\nf, err := os.CreateTemp(\"\", \"test\")\nif err != nil {\n  t.Fatal(\"failed to set up test\")\n}\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/param-naked.md",
    "content": "# Avoid Naked Parameters\n\nNaked parameters in function calls can hurt readability. Add C-style comments\n(`/* ... */`) for parameter names when their meaning is not obvious.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// func printInfo(name string, isLocal, done bool)\n\nprintInfo(\"foo\", true, true)\n```\n\n</td><td>\n\n```go\n// func printInfo(name string, isLocal, done bool)\n\nprintInfo(\"foo\", true /* isLocal */, true /* done */)\n```\n\n</td></tr>\n</tbody></table>\n\nBetter yet, replace naked `bool` types with custom types for more readable and\ntype-safe code. This allows more than just two states (true/false) for that\nparameter in the future.\n\n```go\ntype Region int\n\nconst (\n  UnknownRegion Region = iota\n  Local\n)\n\ntype Status int\n\nconst (\n  StatusReady Status = iota + 1\n  StatusDone\n  // Maybe we will have a StatusInProgress in the future.\n)\n\nfunc printInfo(name string, region Region, status Status)\n```\n"
  },
  {
    "path": "src/performance.md",
    "content": "# Performance\n\nPerformance-specific guidelines apply only to the hot path.\n"
  },
  {
    "path": "src/preface.txt",
    "content": "<!--\n  This file was generated by stitchmd. DO NOT EDIT.\n  To make changes, edit the files in the \"src\" directory.\n-->\n\n<!-- markdownlint-disable MD033 -->\n\n"
  },
  {
    "path": "src/printf-const.md",
    "content": "# Format Strings outside Printf\n\nIf you declare format strings for `Printf`-style functions outside a string\nliteral, make them `const` values.\n\nThis helps `go vet` perform static analysis of the format string.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nmsg := \"unexpected values %v, %v\\n\"\nfmt.Printf(msg, 1, 2)\n```\n\n</td><td>\n\n```go\nconst msg = \"unexpected values %v, %v\\n\"\nfmt.Printf(msg, 1, 2)\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/printf-name.md",
    "content": "# Naming Printf-style Functions\n\nWhen you declare a `Printf`-style function, make sure that `go vet` can detect\nit and check the format string.\n\nThis means that you should use predefined `Printf`-style function\nnames if possible. `go vet` will check these by default. See [Printf family]\nfor more information.\n\n  [Printf family]: https://pkg.go.dev/cmd/vet#hdr-Printf_family\n\nIf using the predefined names is not an option, end the name you choose with\nf: `Wrapf`, not `Wrap`. `go vet` can be asked to check specific `Printf`-style\nnames but they must end with f.\n\n```shell\ngo vet -printfuncs=wrapf,statusf\n```\n\nSee also [go vet: Printf family check].\n\n  [go vet: Printf family check]: https://kuzminva.wordpress.com/2017/11/07/go-vet-printf-family-check/\n"
  },
  {
    "path": "src/slice-nil.md",
    "content": "# nil is a valid slice\n\n`nil` is a valid slice of length 0. This means that,\n\n- You should not return a slice of length zero explicitly. Return `nil`\n  instead.\n\n  <table>\n  <thead><tr><th>Bad</th><th>Good</th></tr></thead>\n  <tbody>\n  <tr><td>\n\n  ```go\n  if x == \"\" {\n    return []int{}\n  }\n  ```\n\n  </td><td>\n\n  ```go\n  if x == \"\" {\n    return nil\n  }\n  ```\n\n  </td></tr>\n  </tbody></table>\n\n- To check if a slice is empty, always use `len(s) == 0`. Do not check for\n  `nil`.\n\n  <table>\n  <thead><tr><th>Bad</th><th>Good</th></tr></thead>\n  <tbody>\n  <tr><td>\n\n  ```go\n  func isEmpty(s []string) bool {\n    return s == nil\n  }\n  ```\n\n  </td><td>\n\n  ```go\n  func isEmpty(s []string) bool {\n    return len(s) == 0\n  }\n  ```\n\n  </td></tr>\n  </tbody></table>\n\n- The zero value (a slice declared with `var`) is usable immediately without\n  `make()`.\n\n  <table>\n  <thead><tr><th>Bad</th><th>Good</th></tr></thead>\n  <tbody>\n  <tr><td>\n\n  ```go\n  nums := []int{}\n  // or, nums := make([]int)\n\n  if add1 {\n    nums = append(nums, 1)\n  }\n\n  if add2 {\n    nums = append(nums, 2)\n  }\n  ```\n\n  </td><td>\n\n  ```go\n  var nums []int\n\n  if add1 {\n    nums = append(nums, 1)\n  }\n\n  if add2 {\n    nums = append(nums, 2)\n  }\n  ```\n\n  </td></tr>\n  </tbody></table>\n\nRemember that, while it is a valid slice, a nil slice is not equivalent to an\nallocated slice of length 0 - one is nil and the other is not - and the two may\nbe treated differently in different situations (such as serialization).\n"
  },
  {
    "path": "src/strconv.md",
    "content": "# Prefer strconv over fmt\n\nWhen converting primitives to/from strings, `strconv` is faster than\n`fmt`.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfor i := 0; i < b.N; i++ {\n  s := fmt.Sprint(rand.Int())\n}\n```\n\n</td><td>\n\n```go\nfor i := 0; i < b.N; i++ {\n  s := strconv.Itoa(rand.Int())\n}\n```\n\n</td></tr>\n<tr><td>\n\n```plain\nBenchmarkFmtSprint-4    143 ns/op    2 allocs/op\n```\n\n</td><td>\n\n```plain\nBenchmarkStrconv-4    64.2 ns/op    1 allocs/op\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/string-byte-slice.md",
    "content": "# Avoid repeated string-to-byte conversions\n\nDo not create byte slices from a fixed string repeatedly. Instead, perform the\nconversion once and capture the result.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfor i := 0; i < b.N; i++ {\n  w.Write([]byte(\"Hello world\"))\n}\n```\n\n</td><td>\n\n```go\ndata := []byte(\"Hello world\")\nfor i := 0; i < b.N; i++ {\n  w.Write(data)\n}\n```\n\n</td></tr>\n<tr><td>\n\n```plain\nBenchmarkBad-4   50000000   22.2 ns/op\n```\n\n</td><td>\n\n```plain\nBenchmarkGood-4  500000000   3.25 ns/op\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/string-escape.md",
    "content": "# Use Raw String Literals to Avoid Escaping\n\nGo supports [raw string literals](https://go.dev/ref/spec#raw_string_lit),\nwhich can span multiple lines and include quotes. Use these to avoid\nhand-escaped strings which are much harder to read.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nwantError := \"unknown name:\\\"test\\\"\"\n```\n\n</td><td>\n\n```go\nwantError := `unknown error:\"test\"`\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/struct-embed.md",
    "content": "# Embedding in Structs\n\nEmbedded types should be at the top of the field list of a\nstruct, and there must be an empty line separating embedded fields from regular\nfields.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype Client struct {\n  version int\n  http.Client\n}\n```\n\n</td><td>\n\n```go\ntype Client struct {\n  http.Client\n\n  version int\n}\n```\n\n</td></tr>\n</tbody></table>\n\nEmbedding should provide tangible benefit, like adding or augmenting\nfunctionality in a semantically-appropriate way. It should do this with zero\nadverse user-facing effects (see also: [Avoid Embedding Types in Public Structs](embed-public.md)).\n\nException: Mutexes should not be embedded, even on unexported types. See also: [Zero-value Mutexes are Valid](mutex-zero-value.md).\n\nEmbedding **should not**:\n\n- Be purely cosmetic or convenience-oriented.\n- Make outer types more difficult to construct or use.\n- Affect outer types' zero values. If the outer type has a useful zero value, it\n  should still have a useful zero value after embedding the inner type.\n- Expose unrelated functions or fields from the outer type as a side-effect of\n  embedding the inner type.\n- Expose unexported types.\n- Affect outer types' copy semantics.\n- Change the outer type's API or type semantics.\n- Embed a non-canonical form of the inner type.\n- Expose implementation details of the outer type.\n- Allow users to observe or control type internals.\n- Change the general behavior of inner functions through wrapping in a way that\n  would reasonably surprise users.\n\nSimply put, embed consciously and intentionally. A good litmus test is, \"would\nall of these exported inner methods/fields be added directly to the outer type\";\nif the answer is \"some\" or \"no\", don't embed the inner type - use a field\ninstead.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype A struct {\n    // Bad: A.Lock() and A.Unlock() are\n    //      now available, provide no\n    //      functional benefit, and allow\n    //      users to control details about\n    //      the internals of A.\n    sync.Mutex\n}\n```\n\n</td><td>\n\n```go\ntype countingWriteCloser struct {\n    // Good: Write() is provided at this\n    //       outer layer for a specific\n    //       purpose, and delegates work\n    //       to the inner type's Write().\n    io.WriteCloser\n\n    count int\n}\n\nfunc (w *countingWriteCloser) Write(bs []byte) (int, error) {\n    w.count += len(bs)\n    return w.WriteCloser.Write(bs)\n}\n```\n\n</td></tr>\n<tr><td>\n\n```go\ntype Book struct {\n    // Bad: pointer changes zero value usefulness\n    io.ReadWriter\n\n    // other fields\n}\n\n// later\n\nvar b Book\nb.Read(...)  // panic: nil pointer\nb.String()   // panic: nil pointer\nb.Write(...) // panic: nil pointer\n```\n\n</td><td>\n\n```go\ntype Book struct {\n    // Good: has useful zero value\n    bytes.Buffer\n\n    // other fields\n}\n\n// later\n\nvar b Book\nb.Read(...)  // ok\nb.String()   // ok\nb.Write(...) // ok\n```\n\n</td></tr>\n<tr><td>\n\n```go\ntype Client struct {\n    sync.Mutex\n    sync.WaitGroup\n    bytes.Buffer\n    url.URL\n}\n```\n\n</td><td>\n\n```go\ntype Client struct {\n    mtx sync.Mutex\n    wg  sync.WaitGroup\n    buf bytes.Buffer\n    url url.URL\n}\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/struct-field-key.md",
    "content": "# Use Field Names to Initialize Structs\n\nYou should almost always specify field names when initializing structs. This is\nnow enforced by [`go vet`].\n\n  [`go vet`]: https://pkg.go.dev/cmd/vet\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nk := User{\"John\", \"Doe\", true}\n```\n\n</td><td>\n\n```go\nk := User{\n    FirstName: \"John\",\n    LastName: \"Doe\",\n    Admin: true,\n}\n```\n\n</td></tr>\n</tbody></table>\n\nException: Field names *may* be omitted in test tables when there are 3 or\nfewer fields.\n\n```go\ntests := []struct{\n  op Operation\n  want string\n}{\n  {Add, \"add\"},\n  {Subtract, \"subtract\"},\n}\n```\n"
  },
  {
    "path": "src/struct-field-zero.md",
    "content": "# Omit Zero Value Fields in Structs\n\nWhen initializing structs with field names, omit fields that have zero values\nunless they provide meaningful context. Otherwise, let Go set these to zero\nvalues automatically.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nuser := User{\n  FirstName: \"John\",\n  LastName: \"Doe\",\n  MiddleName: \"\",\n  Admin: false,\n}\n```\n\n</td><td>\n\n```go\nuser := User{\n  FirstName: \"John\",\n  LastName: \"Doe\",\n}\n```\n\n</td></tr>\n</tbody></table>\n\nThis helps reduce noise for readers by omitting values that are default in\nthat context. Only meaningful values are specified.\n\nInclude zero values where field names provide meaningful context. For example,\ntest cases in [Test Tables](test-table.md) can benefit from names of fields\neven when they are zero-valued.\n\n```go\ntests := []struct{\n  give string\n  want int\n}{\n  {give: \"0\", want: 0},\n  // ...\n}\n```\n"
  },
  {
    "path": "src/struct-pointer.md",
    "content": "# Initializing Struct References\n\nUse `&T{}` instead of `new(T)` when initializing struct references so that it\nis consistent with the struct initialization.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nsval := T{Name: \"foo\"}\n\n// inconsistent\nsptr := new(T)\nsptr.Name = \"bar\"\n```\n\n</td><td>\n\n```go\nsval := T{Name: \"foo\"}\n\nsptr := &T{Name: \"bar\"}\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/struct-tag.md",
    "content": "# Use field tags in marshaled structs\n\nAny struct field that is marshaled into JSON, YAML,\nor other formats that support tag-based field naming\nshould be annotated with the relevant tag.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype Stock struct {\n  Price int\n  Name  string\n}\n\nbytes, err := json.Marshal(Stock{\n  Price: 137,\n  Name:  \"UBER\",\n})\n```\n\n</td><td>\n\n```go\ntype Stock struct {\n  Price int    `json:\"price\"`\n  Name  string `json:\"name\"`\n  // Safe to rename Name to Symbol.\n}\n\nbytes, err := json.Marshal(Stock{\n  Price: 137,\n  Name:  \"UBER\",\n})\n```\n\n</td></tr>\n</tbody></table>\n\nRationale:\nThe serialized form of the structure is a contract between different systems.\nChanges to the structure of the serialized form--including field names--break\nthis contract. Specifying field names inside tags makes the contract explicit,\nand it guards against accidentally breaking the contract by refactoring or\nrenaming fields.\n"
  },
  {
    "path": "src/struct-zero.md",
    "content": "# Use `var` for Zero Value Structs\n\nWhen all the fields of a struct are omitted in a declaration, use the `var`\nform to declare the struct.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nuser := User{}\n```\n\n</td><td>\n\n```go\nvar user User\n```\n\n</td></tr>\n</tbody></table>\n\nThis differentiates zero valued structs from those with non-zero fields\nsimilar to the distinction created for [map initialization](map-init.md), and matches how\nwe prefer to [declare empty slices].\n\n  [declare empty slices]: https://go.dev/wiki/CodeReviewComments#declaring-empty-slices\n"
  },
  {
    "path": "src/test-table.md",
    "content": "# Test Tables\n\nTable-driven tests with [subtests] can be a helpful pattern for writing tests\nto avoid duplicating code when the core test logic is repetitive.\n\nIf a system under test needs to be tested against _multiple conditions_ where\ncertain parts of the inputs and outputs change, a table-driven test should\nbe used to reduce redundancy and improve readability.\n\n  [subtests]: https://go.dev/blog/subtests\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// func TestSplitHostPort(t *testing.T)\n\nhost, port, err := net.SplitHostPort(\"192.0.2.0:8000\")\nrequire.NoError(t, err)\nassert.Equal(t, \"192.0.2.0\", host)\nassert.Equal(t, \"8000\", port)\n\nhost, port, err = net.SplitHostPort(\"192.0.2.0:http\")\nrequire.NoError(t, err)\nassert.Equal(t, \"192.0.2.0\", host)\nassert.Equal(t, \"http\", port)\n\nhost, port, err = net.SplitHostPort(\":8000\")\nrequire.NoError(t, err)\nassert.Equal(t, \"\", host)\nassert.Equal(t, \"8000\", port)\n\nhost, port, err = net.SplitHostPort(\"1:8\")\nrequire.NoError(t, err)\nassert.Equal(t, \"1\", host)\nassert.Equal(t, \"8\", port)\n```\n\n</td><td>\n\n```go\n// func TestSplitHostPort(t *testing.T)\n\ntests := []struct{\n  give     string\n  wantHost string\n  wantPort string\n}{\n  {\n    give:     \"192.0.2.0:8000\",\n    wantHost: \"192.0.2.0\",\n    wantPort: \"8000\",\n  },\n  {\n    give:     \"192.0.2.0:http\",\n    wantHost: \"192.0.2.0\",\n    wantPort: \"http\",\n  },\n  {\n    give:     \":8000\",\n    wantHost: \"\",\n    wantPort: \"8000\",\n  },\n  {\n    give:     \"1:8\",\n    wantHost: \"1\",\n    wantPort: \"8\",\n  },\n}\n\nfor _, tt := range tests {\n  t.Run(tt.give, func(t *testing.T) {\n    host, port, err := net.SplitHostPort(tt.give)\n    require.NoError(t, err)\n    assert.Equal(t, tt.wantHost, host)\n    assert.Equal(t, tt.wantPort, port)\n  })\n}\n```\n\n</td></tr>\n</tbody></table>\n\nTest tables make it easier to add context to error messages, reduce duplicate\nlogic, and add new test cases.\n\nWe follow the convention that the slice of structs is referred to as `tests`\nand each test case `tt`. Further, we encourage explicating the input and output\nvalues for each test case with `give` and `want` prefixes.\n\n```go\ntests := []struct{\n  give     string\n  wantHost string\n  wantPort string\n}{\n  // ...\n}\n\nfor _, tt := range tests {\n  // ...\n}\n```\n\n## Avoid Unnecessary Complexity in Table Tests\n\nTable tests can be difficult to read and maintain if the subtests contain conditional\nassertions or other branching logic. Table tests should **NOT** be used whenever\nthere needs to be complex or conditional logic inside subtests (i.e. complex logic inside the `for` loop).\n\nLarge, complex table tests harm readability and maintainability because test readers may\nhave difficulty debugging test failures that occur.\n\nTable tests like this should be split into either multiple test tables or multiple\nindividual `Test...` functions.\n\nSome ideals to aim for are:\n\n* Focus on the narrowest unit of behavior\n* Minimize \"test depth\", and avoid conditional assertions (see below)\n* Ensure that all table fields are used in all tests\n* Ensure that all test logic runs for all table cases\n\nIn this context, \"test depth\" means \"within a given test, the number of\nsuccessive assertions that require previous assertions to hold\" (similar\nto cyclomatic complexity).\nHaving \"shallower\" tests means that there are fewer relationships between\nassertions and, more importantly, that those assertions are less likely\nto be conditional by default.\n\nConcretely, table tests can become confusing and difficult to read if they use multiple branching\npathways (e.g. `shouldError`, `expectCall`, etc.), use many `if` statements for\nspecific mock expectations (e.g. `shouldCallFoo`), or place functions inside the\ntable (e.g. `setupMocks func(*FooMock)`).\n\nHowever, when testing behavior that only\nchanges based on changed input, it may be preferable to group similar cases\ntogether in a table test to better illustrate how behavior changes across all inputs,\nrather than splitting otherwise comparable units into separate tests\nand making them harder to compare and contrast.\n\nIf the test body is short and straightforward,\nit's acceptable to have a single branching pathway for success versus failure cases\nwith a table field like `shouldErr` to specify error expectations.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc TestComplicatedTable(t *testing.T) {\n  tests := []struct {\n    give          string\n    want          string\n    wantErr       error\n    shouldCallX   bool\n    shouldCallY   bool\n    giveXResponse string\n    giveXErr      error\n    giveYResponse string\n    giveYErr      error\n  }{\n    // ...\n  }\n\n  for _, tt := range tests {\n    t.Run(tt.give, func(t *testing.T) {\n      // setup mocks\n      ctrl := gomock.NewController(t)\n      xMock := xmock.NewMockX(ctrl)\n      if tt.shouldCallX {\n        xMock.EXPECT().Call().Return(\n          tt.giveXResponse, tt.giveXErr,\n        )\n      }\n      yMock := ymock.NewMockY(ctrl)\n      if tt.shouldCallY {\n        yMock.EXPECT().Call().Return(\n          tt.giveYResponse, tt.giveYErr,\n        )\n      }\n\n      got, err := DoComplexThing(tt.give, xMock, yMock)\n\n      // verify results\n      if tt.wantErr != nil {\n        require.EqualError(t, err, tt.wantErr)\n        return\n      }\n      require.NoError(t, err)\n      assert.Equal(t, want, got)\n    })\n  }\n}\n```\n\n</td><td>\n\n```go\nfunc TestShouldCallX(t *testing.T) {\n  // setup mocks\n  ctrl := gomock.NewController(t)\n  xMock := xmock.NewMockX(ctrl)\n  xMock.EXPECT().Call().Return(\"XResponse\", nil)\n\n  yMock := ymock.NewMockY(ctrl)\n\n  got, err := DoComplexThing(\"inputX\", xMock, yMock)\n\n  require.NoError(t, err)\n  assert.Equal(t, \"want\", got)\n}\n\nfunc TestShouldCallYAndFail(t *testing.T) {\n  // setup mocks\n  ctrl := gomock.NewController(t)\n  xMock := xmock.NewMockX(ctrl)\n\n  yMock := ymock.NewMockY(ctrl)\n  yMock.EXPECT().Call().Return(\"YResponse\", nil)\n\n  _, err := DoComplexThing(\"inputY\", xMock, yMock)\n  assert.EqualError(t, err, \"Y failed\")\n}\n```\n</td></tr>\n</tbody></table>\n\nThis complexity makes it more difficult to change, understand, and prove the\ncorrectness of the test.\n\nWhile there are no strict guidelines, readability and maintainability should\nalways be top-of-mind when deciding between Table Tests versus separate tests\nfor multiple inputs/outputs to a system.\n\n## Parallel Tests\n\nParallel tests, like some specialized loops (for example, those that spawn\ngoroutines or capture references as part of the loop body),\nmust take care to explicitly assign loop variables within the loop's scope to\nensure that they hold the expected values.\n\n```go\ntests := []struct{\n  give string\n  // ...\n}{\n  // ...\n}\n\nfor _, tt := range tests {\n  t.Run(tt.give, func(t *testing.T) {\n    t.Parallel()\n    // ...\n  })\n}\n```\n\nIn the example above, we must declare a `tt` variable scoped to the loop\niteration because of the use of `t.Parallel()` below.\nIf we do not do that, most or all tests will receive an unexpected value for\n`tt`, or a value that changes as they're running.\n\n<!-- TODO: Explain how to use _test packages. -->\n"
  },
  {
    "path": "src/time.md",
    "content": "# Use `\"time\"` to handle time\n\nTime is complicated. Incorrect assumptions often made about time include the\nfollowing.\n\n1. A day has 24 hours\n2. An hour has 60 minutes\n3. A week has 7 days\n4. A year has 365 days\n5. [And a lot more](https://infiniteundo.com/post/25326999628/falsehoods-programmers-believe-about-time)\n\nFor example, *1* means that adding 24 hours to a time instant will not always\nyield a new calendar day.\n\nTherefore, always use the [`\"time\"`] package when dealing with time because it\nhelps deal with these incorrect assumptions in a safer, more accurate manner.\n\n  [`\"time\"`]: https://pkg.go.dev/time\n\n## Use `time.Time` for instants of time\n\nUse [`time.Time`] when dealing with instants of time, and the methods on\n`time.Time` when comparing, adding, or subtracting time.\n\n  [`time.Time`]: https://pkg.go.dev/time#Time\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc isActive(now, start, stop int) bool {\n  return start <= now && now < stop\n}\n```\n\n</td><td>\n\n```go\nfunc isActive(now, start, stop time.Time) bool {\n  return (start.Before(now) || start.Equal(now)) && now.Before(stop)\n}\n```\n\n</td></tr>\n</tbody></table>\n\n## Use `time.Duration` for periods of time\n\nUse [`time.Duration`] when dealing with periods of time.\n\n  [`time.Duration`]: https://pkg.go.dev/time#Duration\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc poll(delay int) {\n  for {\n    // ...\n    time.Sleep(time.Duration(delay) * time.Millisecond)\n  }\n}\n\npoll(10) // was it seconds or milliseconds?\n```\n\n</td><td>\n\n```go\nfunc poll(delay time.Duration) {\n  for {\n    // ...\n    time.Sleep(delay)\n  }\n}\n\npoll(10*time.Second)\n```\n\n</td></tr>\n</tbody></table>\n\nGoing back to the example of adding 24 hours to a time instant, the method we\nuse to add time depends on intent. If we want the same time of the day, but on\nthe next calendar day, we should use [`Time.AddDate`]. However, if we want an\ninstant of time guaranteed to be 24 hours after the previous time, we should\nuse [`Time.Add`].\n\n  [`Time.AddDate`]: https://pkg.go.dev/time#Time.AddDate\n  [`Time.Add`]: https://pkg.go.dev/time#Time.Add\n\n```go\nnewDay := t.AddDate(0 /* years */, 0 /* months */, 1 /* days */)\nmaybeNewDay := t.Add(24 * time.Hour)\n```\n\n## Use `time.Time` and `time.Duration` with external systems\n\nUse `time.Duration` and `time.Time` in interactions with external systems when\npossible. For example:\n\n- Command-line flags: [`flag`] supports `time.Duration` via\n  [`time.ParseDuration`]\n- JSON: [`encoding/json`] supports encoding `time.Time` as an [RFC 3339]\n  string via its [`UnmarshalJSON` method]\n- SQL: [`database/sql`] supports converting `DATETIME` or `TIMESTAMP` columns\n  into `time.Time` and back if the underlying driver supports it\n- YAML: [`gopkg.in/yaml.v2`] supports `time.Time` as an [RFC 3339] string, and\n  `time.Duration` via [`time.ParseDuration`].\n\n  [`flag`]: https://pkg.go.dev/flag\n  [`time.ParseDuration`]: https://pkg.go.dev/time#ParseDuration\n  [`encoding/json`]: https://pkg.go.dev/encoding/json\n  [RFC 3339]: https://tools.ietf.org/html/rfc3339\n  [`UnmarshalJSON` method]: https://pkg.go.dev/time#Time.UnmarshalJSON\n  [`database/sql`]: https://pkg.go.dev/database/sql\n  [`gopkg.in/yaml.v2`]: https://pkg.go.dev/gopkg.in/yaml.v2\n\nWhen it is not possible to use `time.Duration` in these interactions, use\n`int` or `float64` and include the unit in the name of the field.\n\nFor example, since `encoding/json` does not support `time.Duration`, the unit\nis included in the name of the field.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// {\"interval\": 2}\ntype Config struct {\n  Interval int `json:\"interval\"`\n}\n```\n\n</td><td>\n\n```go\n// {\"intervalMillis\": 2000}\ntype Config struct {\n  IntervalMillis int `json:\"intervalMillis\"`\n}\n```\n\n</td></tr>\n</tbody></table>\n\nWhen it is not possible to use `time.Time` in these interactions, unless an\nalternative is agreed upon, use `string` and format timestamps as defined in\n[RFC 3339]. This format is used by default by [`Time.UnmarshalText`] and is\navailable for use in `Time.Format` and `time.Parse` via [`time.RFC3339`].\n\n  [`Time.UnmarshalText`]: https://pkg.go.dev/time#Time.UnmarshalText\n  [`time.RFC3339`]: https://pkg.go.dev/time#RFC3339\n\nAlthough this tends to not be a problem in practice, keep in mind that the\n`\"time\"` package does not support parsing timestamps with leap seconds\n([8728]), nor does it account for leap seconds in calculations ([15190]). If\nyou compare two instants of time, the difference will not include the leap\nseconds that may have occurred between those two instants.\n\n  [8728]: https://github.com/golang/go/issues/8728\n  [15190]: https://github.com/golang/go/issues/15190\n"
  },
  {
    "path": "src/type-assert.md",
    "content": "# Handle Type Assertion Failures\n\nThe single return value form of a [type assertion] will panic on an incorrect\ntype. Therefore, always use the \"comma ok\" idiom.\n\n  [type assertion]: https://go.dev/ref/spec#Type_assertions\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nt := i.(string)\n```\n\n</td><td>\n\n```go\nt, ok := i.(string)\nif !ok {\n  // handle the error gracefully\n}\n```\n\n</td></tr>\n</tbody></table>\n\n<!-- TODO: There are a few situations where the single assignment form is\nfine. -->\n"
  },
  {
    "path": "src/var-decl.md",
    "content": "# Local Variable Declarations\n\nShort variable declarations (`:=`) should be used if a variable is being set to\nsome value explicitly.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nvar s = \"foo\"\n```\n\n</td><td>\n\n```go\ns := \"foo\"\n```\n\n</td></tr>\n</tbody></table>\n\nHowever, there are cases where the default value is clearer when the `var`\nkeyword is used. [Declaring Empty Slices], for example.\n\n  [Declaring Empty Slices]: https://go.dev/wiki/CodeReviewComments#declaring-empty-slices\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc f(list []int) {\n  filtered := []int{}\n  for _, v := range list {\n    if v > 10 {\n      filtered = append(filtered, v)\n    }\n  }\n}\n```\n\n</td><td>\n\n```go\nfunc f(list []int) {\n  var filtered []int\n  for _, v := range list {\n    if v > 10 {\n      filtered = append(filtered, v)\n    }\n  }\n}\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "src/var-scope.md",
    "content": "# Reduce Scope of Variables\n\nWhere possible, reduce scope of variables and constants. Do not reduce the scope if it\nconflicts with [Reduce Nesting](nest-less.md).\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nerr := os.WriteFile(name, data, 0644)\nif err != nil {\n return err\n}\n```\n\n</td><td>\n\n```go\nif err := os.WriteFile(name, data, 0644); err != nil {\n return err\n}\n```\n\n</td></tr>\n</tbody></table>\n\nIf you need a result of a function call outside of the if, then you should not\ntry to reduce the scope.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nif data, err := os.ReadFile(name); err == nil {\n  err = cfg.Decode(data)\n  if err != nil {\n    return err\n  }\n\n  fmt.Println(cfg)\n  return nil\n} else {\n  return err\n}\n```\n\n</td><td>\n\n```go\ndata, err := os.ReadFile(name)\nif err != nil {\n   return err\n}\n\nif err := cfg.Decode(data); err != nil {\n  return err\n}\n\nfmt.Println(cfg)\nreturn nil\n```\n\n</td></tr>\n</tbody></table>\n\nConstants do not need to be global unless they are used in multiple functions or files\nor are part of an external contract of the package.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nconst (\n  _defaultPort = 8080\n  _defaultUser = \"user\"\n)\n\nfunc Bar() {\n  fmt.Println(\"Default port\", _defaultPort)\n}\n```\n\n</td><td>\n\n```go\nfunc Bar() {\n  const (\n    defaultPort = 8080\n    defaultUser = \"user\"\n  )\n  fmt.Println(\"Default port\", defaultPort)\n}\n```\n\n</td></tr>\n</tbody></table>\n"
  },
  {
    "path": "style.md",
    "content": "<!--\n  This file was generated by stitchmd. DO NOT EDIT.\n  To make changes, edit the files in the \"src\" directory.\n-->\n\n<!-- markdownlint-disable MD033 -->\n\n# Uber Go Style Guide\n\n- [Introduction](#introduction)\n- [Guidelines](#guidelines)\n  - [Pointers to Interfaces](#pointers-to-interfaces)\n  - [Verify Interface Compliance](#verify-interface-compliance)\n  - [Receivers and Interfaces](#receivers-and-interfaces)\n  - [Zero-value Mutexes are Valid](#zero-value-mutexes-are-valid)\n  - [Copy Slices and Maps at Boundaries](#copy-slices-and-maps-at-boundaries)\n  - [Defer to Clean Up](#defer-to-clean-up)\n  - [Channel Size is One or None](#channel-size-is-one-or-none)\n  - [Start Enums at One](#start-enums-at-one)\n  - [Use `\"time\"` to handle time](#use-time-to-handle-time)\n  - [Errors](#errors)\n    - [Error Types](#error-types)\n    - [Error Wrapping](#error-wrapping)\n    - [Error Naming](#error-naming)\n    - [Handle Errors Once](#handle-errors-once)\n  - [Handle Type Assertion Failures](#handle-type-assertion-failures)\n  - [Don't Panic](#dont-panic)\n  - [Use go.uber.org/atomic](#use-gouberorgatomic)\n  - [Avoid Mutable Globals](#avoid-mutable-globals)\n  - [Avoid Embedding Types in Public Structs](#avoid-embedding-types-in-public-structs)\n  - [Avoid Using Built-In Names](#avoid-using-built-in-names)\n  - [Avoid `init()`](#avoid-init)\n  - [Exit in Main](#exit-in-main)\n    - [Exit Once](#exit-once)\n  - [Use field tags in marshaled structs](#use-field-tags-in-marshaled-structs)\n  - [Don't fire-and-forget goroutines](#dont-fire-and-forget-goroutines)\n    - [Wait for goroutines to exit](#wait-for-goroutines-to-exit)\n    - [No goroutines in `init()`](#no-goroutines-in-init)\n- [Performance](#performance)\n  - [Prefer strconv over fmt](#prefer-strconv-over-fmt)\n  - [Avoid repeated string-to-byte conversions](#avoid-repeated-string-to-byte-conversions)\n  - [Prefer Specifying Container Capacity](#prefer-specifying-container-capacity)\n- [Style](#style)\n  - [Avoid overly long lines](#avoid-overly-long-lines)\n  - [Be Consistent](#be-consistent)\n  - [Group Similar Declarations](#group-similar-declarations)\n  - [Import Group Ordering](#import-group-ordering)\n  - [Package Names](#package-names)\n  - [Function Names](#function-names)\n  - [Import Aliasing](#import-aliasing)\n  - [Function Grouping and Ordering](#function-grouping-and-ordering)\n  - [Reduce Nesting](#reduce-nesting)\n  - [Unnecessary Else](#unnecessary-else)\n  - [Top-level Variable Declarations](#top-level-variable-declarations)\n  - [Prefix Unexported Globals with _](#prefix-unexported-globals-with-_)\n  - [Embedding in Structs](#embedding-in-structs)\n  - [Local Variable Declarations](#local-variable-declarations)\n  - [nil is a valid slice](#nil-is-a-valid-slice)\n  - [Reduce Scope of Variables](#reduce-scope-of-variables)\n  - [Avoid Naked Parameters](#avoid-naked-parameters)\n  - [Use Raw String Literals to Avoid Escaping](#use-raw-string-literals-to-avoid-escaping)\n  - [Initializing Structs](#initializing-structs)\n    - [Use Field Names to Initialize Structs](#use-field-names-to-initialize-structs)\n    - [Omit Zero Value Fields in Structs](#omit-zero-value-fields-in-structs)\n    - [Use `var` for Zero Value Structs](#use-var-for-zero-value-structs)\n    - [Initializing Struct References](#initializing-struct-references)\n  - [Initializing Maps](#initializing-maps)\n  - [Format Strings outside Printf](#format-strings-outside-printf)\n  - [Naming Printf-style Functions](#naming-printf-style-functions)\n- [Patterns](#patterns)\n  - [Test Tables](#test-tables)\n  - [Functional Options](#functional-options)\n- [Linting](#linting)\n\n## Introduction\n\nStyles are the conventions that govern our code. The term style is a bit of a\nmisnomer, since these conventions cover far more than just source file\nformatting—gofmt handles that for us.\n\nThe goal of this guide is to manage this complexity by describing in detail the\nDos and Don'ts of writing Go code at Uber. These rules exist to keep the code\nbase manageable while still allowing engineers to use Go language features\nproductively.\n\nThis guide was originally created by [Prashant Varanasi](https://github.com/prashantv) and [Simon Newton](https://github.com/nomis52) as\na way to bring some colleagues up to speed with using Go. Over the years it has\nbeen amended based on feedback from others.\n\nThis documents idiomatic conventions in Go code that we follow at Uber. A lot\nof these are general guidelines for Go, while others extend upon external\nresources:\n\n1. [Effective Go](https://go.dev/doc/effective_go)\n2. [Go Common Mistakes](https://go.dev/wiki/CommonMistakes)\n3. [Go Code Review Comments](https://go.dev/wiki/CodeReviewComments)\n\nWe aim for the code samples to be accurate for the two most recent minor versions\nof Go [releases](https://go.dev/doc/devel/release).\n\nAll code should be error-free when run through `golint` and `go vet`. We\nrecommend setting up your editor to:\n\n- Run `goimports` on save\n- Run `golint` and `go vet` to check for errors\n\nYou can find information in editor support for Go tools here:\nhttps://go.dev/wiki/IDEsAndTextEditorPlugins\n\n## Guidelines\n\n### Pointers to Interfaces\n\nYou almost never need a pointer to an interface. You should be passing\ninterfaces as values—the underlying data can still be a pointer.\n\nAn interface is two fields:\n\n1. A pointer to some type-specific information. You can think of this as\n   \"type.\"\n2. Data pointer. If the data stored is a pointer, it’s stored directly. If\n   the data stored is a value, then a pointer to the value is stored.\n\nIf you want interface methods to modify the underlying data, you must use a\npointer.\n\n### Verify Interface Compliance\n\nVerify interface compliance at compile time where appropriate. This includes:\n\n- Exported types that are required to implement specific interfaces as part of\n  their API contract\n- Exported or unexported types that are part of a collection of types\n  implementing the same interface\n- Other cases where violating an interface would break users\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype Handler struct {\n  // ...\n}\n\n\n\nfunc (h *Handler) ServeHTTP(\n  w http.ResponseWriter,\n  r *http.Request,\n) {\n  ...\n}\n```\n\n</td><td>\n\n```go\ntype Handler struct {\n  // ...\n}\n\nvar _ http.Handler = (*Handler)(nil)\n\nfunc (h *Handler) ServeHTTP(\n  w http.ResponseWriter,\n  r *http.Request,\n) {\n  // ...\n}\n```\n\n</td></tr>\n</tbody></table>\n\nThe statement `var _ http.Handler = (*Handler)(nil)` will fail to compile if\n`*Handler` ever stops matching the `http.Handler` interface.\n\nThe right hand side of the assignment should be the zero value of the asserted\ntype. This is `nil` for pointer types (like `*Handler`), slices, and maps, and\nan empty struct for struct types.\n\n```go\ntype LogHandler struct {\n  h   http.Handler\n  log *zap.Logger\n}\n\nvar _ http.Handler = LogHandler{}\n\nfunc (h LogHandler) ServeHTTP(\n  w http.ResponseWriter,\n  r *http.Request,\n) {\n  // ...\n}\n```\n\n### Receivers and Interfaces\n\nMethods with value receivers can be called on pointers as well as values.\nMethods with pointer receivers can only be called on pointers or [addressable values](https://go.dev/ref/spec#Method_values).\n\nFor example,\n\n```go\ntype S struct {\n  data string\n}\n\nfunc (s S) Read() string {\n  return s.data\n}\n\nfunc (s *S) Write(str string) {\n  s.data = str\n}\n\n// We cannot get pointers to values stored in maps, because they are not\n// addressable values.\nsVals := map[int]S{1: {\"A\"}}\n\n// We can call Read on values stored in the map because Read\n// has a value receiver, which does not require the value to\n// be addressable.\nsVals[1].Read()\n\n// We cannot call Write on values stored in the map because Write\n// has a pointer receiver, and it's not possible to get a pointer\n// to a value stored in a map.\n//\n//  sVals[1].Write(\"test\")\n\nsPtrs := map[int]*S{1: {\"A\"}}\n\n// You can call both Read and Write if the map stores pointers,\n// because pointers are intrinsically addressable.\nsPtrs[1].Read()\nsPtrs[1].Write(\"test\")\n```\n\nSimilarly, an interface can be satisfied by a pointer, even if the method has a\nvalue receiver.\n\n```go\ntype F interface {\n  f()\n}\n\ntype S1 struct{}\n\nfunc (s S1) f() {}\n\ntype S2 struct{}\n\nfunc (s *S2) f() {}\n\ns1Val := S1{}\ns1Ptr := &S1{}\ns2Val := S2{}\ns2Ptr := &S2{}\n\nvar i F\ni = s1Val\ni = s1Ptr\ni = s2Ptr\n\n// The following doesn't compile, since s2Val is a value, and there is no value receiver for f.\n//   i = s2Val\n```\n\nEffective Go has a good write up on [Pointers vs. Values](https://go.dev/doc/effective_go#pointers_vs_values).\n\n### Zero-value Mutexes are Valid\n\nThe zero-value of `sync.Mutex` and `sync.RWMutex` is valid, so you almost\nnever need a pointer to a mutex.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nmu := new(sync.Mutex)\nmu.Lock()\n```\n\n</td><td>\n\n```go\nvar mu sync.Mutex\nmu.Lock()\n```\n\n</td></tr>\n</tbody></table>\n\nIf you use a struct by pointer, then the mutex should be a non-pointer field on\nit. Do not embed the mutex on the struct, even if the struct is not exported.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype SMap struct {\n  sync.Mutex\n\n  data map[string]string\n}\n\nfunc NewSMap() *SMap {\n  return &SMap{\n    data: make(map[string]string),\n  }\n}\n\nfunc (m *SMap) Get(k string) string {\n  m.Lock()\n  defer m.Unlock()\n\n  return m.data[k]\n}\n```\n\n</td><td>\n\n```go\ntype SMap struct {\n  mu sync.Mutex\n\n  data map[string]string\n}\n\nfunc NewSMap() *SMap {\n  return &SMap{\n    data: make(map[string]string),\n  }\n}\n\nfunc (m *SMap) Get(k string) string {\n  m.mu.Lock()\n  defer m.mu.Unlock()\n\n  return m.data[k]\n}\n```\n\n</td></tr>\n\n<tr><td>\n\nThe `Mutex` field, and the `Lock` and `Unlock` methods are unintentionally part\nof the exported API of `SMap`.\n\n</td><td>\n\nThe mutex and its methods are implementation details of `SMap` hidden from its\ncallers.\n\n</td></tr>\n</tbody></table>\n\n### Copy Slices and Maps at Boundaries\n\nSlices and maps contain pointers to the underlying data so be wary of scenarios\nwhen they need to be copied.\n\n#### Receiving Slices and Maps\n\nKeep in mind that users can modify a map or slice you received as an argument\nif you store a reference to it.\n\n<table>\n<thead><tr><th>Bad</th> <th>Good</th></tr></thead>\n<tbody>\n<tr>\n<td>\n\n```go\nfunc (d *Driver) SetTrips(trips []Trip) {\n  d.trips = trips\n}\n\ntrips := ...\nd1.SetTrips(trips)\n\n// Did you mean to modify d1.trips?\ntrips[0] = ...\n```\n\n</td>\n<td>\n\n```go\nfunc (d *Driver) SetTrips(trips []Trip) {\n  d.trips = make([]Trip, len(trips))\n  copy(d.trips, trips)\n}\n\ntrips := ...\nd1.SetTrips(trips)\n\n// We can now modify trips[0] without affecting d1.trips.\ntrips[0] = ...\n```\n\n</td>\n</tr>\n\n</tbody>\n</table>\n\n#### Returning Slices and Maps\n\nSimilarly, be wary of user modifications to maps or slices exposing internal\nstate.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype Stats struct {\n  mu sync.Mutex\n  counters map[string]int\n}\n\n// Snapshot returns the current stats.\nfunc (s *Stats) Snapshot() map[string]int {\n  s.mu.Lock()\n  defer s.mu.Unlock()\n\n  return s.counters\n}\n\n// snapshot is no longer protected by the mutex, so any\n// access to the snapshot is subject to data races.\nsnapshot := stats.Snapshot()\n```\n\n</td><td>\n\n```go\ntype Stats struct {\n  mu sync.Mutex\n  counters map[string]int\n}\n\nfunc (s *Stats) Snapshot() map[string]int {\n  s.mu.Lock()\n  defer s.mu.Unlock()\n\n  result := make(map[string]int, len(s.counters))\n  for k, v := range s.counters {\n    result[k] = v\n  }\n  return result\n}\n\n// Snapshot is now a copy.\nsnapshot := stats.Snapshot()\n```\n\n</td></tr>\n</tbody></table>\n\n### Defer to Clean Up\n\nUse defer to clean up resources such as files and locks.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\np.Lock()\nif p.count < 10 {\n  p.Unlock()\n  return p.count\n}\n\np.count++\nnewCount := p.count\np.Unlock()\n\nreturn newCount\n\n// easy to miss unlocks due to multiple returns\n```\n\n</td><td>\n\n```go\np.Lock()\ndefer p.Unlock()\n\nif p.count < 10 {\n  return p.count\n}\n\np.count++\nreturn p.count\n\n// more readable\n```\n\n</td></tr>\n</tbody></table>\n\nDefer has an extremely small overhead and should be avoided only if you can\nprove that your function execution time is in the order of nanoseconds. The\nreadability win of using defers is worth the miniscule cost of using them. This\nis especially true for larger methods that have more than simple memory\naccesses, where the other computations are more significant than the `defer`.\n\n### Channel Size is One or None\n\nChannels should usually have a size of one or be unbuffered. By default,\nchannels are unbuffered and have a size of zero. Any other size\nmust be subject to a high level of scrutiny. Consider how the size is\ndetermined, what prevents the channel from filling up under load and blocking\nwriters, and what happens when this occurs.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// Ought to be enough for anybody!\nc := make(chan int, 64)\n```\n\n</td><td>\n\n```go\n// Size of one\nc := make(chan int, 1) // or\n// Unbuffered channel, size of zero\nc := make(chan int)\n```\n\n</td></tr>\n</tbody></table>\n\n### Start Enums at One\n\nThe standard way of introducing enumerations in Go is to declare a custom type\nand a `const` group with `iota`. Since variables have a 0 default value, you\nshould usually start your enums on a non-zero value.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype Operation int\n\nconst (\n  Add Operation = iota\n  Subtract\n  Multiply\n)\n\n// Add=0, Subtract=1, Multiply=2\n```\n\n</td><td>\n\n```go\ntype Operation int\n\nconst (\n  Add Operation = iota + 1\n  Subtract\n  Multiply\n)\n\n// Add=1, Subtract=2, Multiply=3\n```\n\n</td></tr>\n</tbody></table>\n\nThere are cases where using the zero value makes sense, for example when the\nzero value case is the desirable default behavior.\n\n```go\ntype LogOutput int\n\nconst (\n  LogToStdout LogOutput = iota\n  LogToFile\n  LogToRemote\n)\n\n// LogToStdout=0, LogToFile=1, LogToRemote=2\n```\n\n<!-- TODO: section on String methods for enums -->\n\n### Use `\"time\"` to handle time\n\nTime is complicated. Incorrect assumptions often made about time include the\nfollowing.\n\n1. A day has 24 hours\n2. An hour has 60 minutes\n3. A week has 7 days\n4. A year has 365 days\n5. [And a lot more](https://infiniteundo.com/post/25326999628/falsehoods-programmers-believe-about-time)\n\nFor example, *1* means that adding 24 hours to a time instant will not always\nyield a new calendar day.\n\nTherefore, always use the [`\"time\"`](https://pkg.go.dev/time) package when dealing with time because it\nhelps deal with these incorrect assumptions in a safer, more accurate manner.\n\n#### Use `time.Time` for instants of time\n\nUse [`time.Time`](https://pkg.go.dev/time#Time) when dealing with instants of time, and the methods on\n`time.Time` when comparing, adding, or subtracting time.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc isActive(now, start, stop int) bool {\n  return start <= now && now < stop\n}\n```\n\n</td><td>\n\n```go\nfunc isActive(now, start, stop time.Time) bool {\n  return (start.Before(now) || start.Equal(now)) && now.Before(stop)\n}\n```\n\n</td></tr>\n</tbody></table>\n\n#### Use `time.Duration` for periods of time\n\nUse [`time.Duration`](https://pkg.go.dev/time#Duration) when dealing with periods of time.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc poll(delay int) {\n  for {\n    // ...\n    time.Sleep(time.Duration(delay) * time.Millisecond)\n  }\n}\n\npoll(10) // was it seconds or milliseconds?\n```\n\n</td><td>\n\n```go\nfunc poll(delay time.Duration) {\n  for {\n    // ...\n    time.Sleep(delay)\n  }\n}\n\npoll(10*time.Second)\n```\n\n</td></tr>\n</tbody></table>\n\nGoing back to the example of adding 24 hours to a time instant, the method we\nuse to add time depends on intent. If we want the same time of the day, but on\nthe next calendar day, we should use [`Time.AddDate`](https://pkg.go.dev/time#Time.AddDate). However, if we want an\ninstant of time guaranteed to be 24 hours after the previous time, we should\nuse [`Time.Add`](https://pkg.go.dev/time#Time.Add).\n\n```go\nnewDay := t.AddDate(0 /* years */, 0 /* months */, 1 /* days */)\nmaybeNewDay := t.Add(24 * time.Hour)\n```\n\n#### Use `time.Time` and `time.Duration` with external systems\n\nUse `time.Duration` and `time.Time` in interactions with external systems when\npossible. For example:\n\n- Command-line flags: [`flag`](https://pkg.go.dev/flag) supports `time.Duration` via\n  [`time.ParseDuration`](https://pkg.go.dev/time#ParseDuration)\n- JSON: [`encoding/json`](https://pkg.go.dev/encoding/json) supports encoding `time.Time` as an [RFC 3339](https://tools.ietf.org/html/rfc3339)\n  string via its [`UnmarshalJSON` method](https://pkg.go.dev/time#Time.UnmarshalJSON)\n- SQL: [`database/sql`](https://pkg.go.dev/database/sql) supports converting `DATETIME` or `TIMESTAMP` columns\n  into `time.Time` and back if the underlying driver supports it\n- YAML: [`gopkg.in/yaml.v2`](https://pkg.go.dev/gopkg.in/yaml.v2) supports `time.Time` as an [RFC 3339](https://tools.ietf.org/html/rfc3339) string, and\n  `time.Duration` via [`time.ParseDuration`](https://pkg.go.dev/time#ParseDuration).\n\nWhen it is not possible to use `time.Duration` in these interactions, use\n`int` or `float64` and include the unit in the name of the field.\n\nFor example, since `encoding/json` does not support `time.Duration`, the unit\nis included in the name of the field.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// {\"interval\": 2}\ntype Config struct {\n  Interval int `json:\"interval\"`\n}\n```\n\n</td><td>\n\n```go\n// {\"intervalMillis\": 2000}\ntype Config struct {\n  IntervalMillis int `json:\"intervalMillis\"`\n}\n```\n\n</td></tr>\n</tbody></table>\n\nWhen it is not possible to use `time.Time` in these interactions, unless an\nalternative is agreed upon, use `string` and format timestamps as defined in\n[RFC 3339](https://tools.ietf.org/html/rfc3339). This format is used by default by [`Time.UnmarshalText`](https://pkg.go.dev/time#Time.UnmarshalText) and is\navailable for use in `Time.Format` and `time.Parse` via [`time.RFC3339`](https://pkg.go.dev/time#RFC3339).\n\nAlthough this tends to not be a problem in practice, keep in mind that the\n`\"time\"` package does not support parsing timestamps with leap seconds\n([8728](https://github.com/golang/go/issues/8728)), nor does it account for leap seconds in calculations ([15190](https://github.com/golang/go/issues/15190)). If\nyou compare two instants of time, the difference will not include the leap\nseconds that may have occurred between those two instants.\n\n### Errors\n\n#### Error Types\n\nThere are few options for declaring errors.\nConsider the following before picking the option best suited for your use case.\n\n- Does the caller need to match the error so that they can handle it?\n  If yes, we must support the [`errors.Is`](https://pkg.go.dev/errors#Is) or [`errors.As`](https://pkg.go.dev/errors#As) functions\n  by declaring a top-level error variable or a custom type.\n- Is the error message a static string,\n  or is it a dynamic string that requires contextual information?\n  For the former, we can use [`errors.New`](https://pkg.go.dev/errors#New), but for the latter we must\n  use [`fmt.Errorf`](https://pkg.go.dev/fmt#Errorf) or a custom error type.\n- Are we propagating a new error returned by a downstream function?\n  If so, see the [section on error wrapping](#error-wrapping).\n\n| Error matching? | Error Message | Guidance                                                           |\n|-----------------|---------------|--------------------------------------------------------------------|\n| No              | static        | [`errors.New`](https://pkg.go.dev/errors#New)                      |\n| No              | dynamic       | [`fmt.Errorf`](https://pkg.go.dev/fmt#Errorf)                      |\n| Yes             | static        | top-level `var` with [`errors.New`](https://pkg.go.dev/errors#New) |\n| Yes             | dynamic       | custom `error` type                                                |\n\nFor example,\nuse [`errors.New`](https://pkg.go.dev/errors#New) for an error with a static string.\nExport this error as a variable to support matching it with `errors.Is`\nif the caller needs to match and handle this error.\n\n<table>\n<thead><tr><th>No error matching</th><th>Error matching</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// package foo\n\nfunc Open() error {\n  return errors.New(\"could not open\")\n}\n\n// package bar\n\nif err := foo.Open(); err != nil {\n  // Can't handle the error.\n  panic(\"unknown error\")\n}\n```\n\n</td><td>\n\n```go\n// package foo\n\nvar ErrCouldNotOpen = errors.New(\"could not open\")\n\nfunc Open() error {\n  return ErrCouldNotOpen\n}\n\n// package bar\n\nif err := foo.Open(); err != nil {\n  if errors.Is(err, foo.ErrCouldNotOpen) {\n    // handle the error\n  } else {\n    panic(\"unknown error\")\n  }\n}\n```\n\n</td></tr>\n</tbody></table>\n\nFor an error with a dynamic string,\nuse [`fmt.Errorf`](https://pkg.go.dev/fmt#Errorf) if the caller does not need to match it,\nand a custom `error` if the caller does need to match it.\n\n<table>\n<thead><tr><th>No error matching</th><th>Error matching</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// package foo\n\nfunc Open(file string) error {\n  return fmt.Errorf(\"file %q not found\", file)\n}\n\n// package bar\n\nif err := foo.Open(\"testfile.txt\"); err != nil {\n  // Can't handle the error.\n  panic(\"unknown error\")\n}\n```\n\n</td><td>\n\n```go\n// package foo\n\ntype NotFoundError struct {\n  File string\n}\n\nfunc (e *NotFoundError) Error() string {\n  return fmt.Sprintf(\"file %q not found\", e.File)\n}\n\nfunc Open(file string) error {\n  return &NotFoundError{File: file}\n}\n\n\n// package bar\n\nif err := foo.Open(\"testfile.txt\"); err != nil {\n  var notFound *NotFoundError\n  if errors.As(err, &notFound) {\n    // handle the error\n  } else {\n    panic(\"unknown error\")\n  }\n}\n```\n\n</td></tr>\n</tbody></table>\n\nNote that if you export error variables or types from a package,\nthey will become part of the public API of the package.\n\n#### Error Wrapping\n\nThere are three main options for propagating errors if a call fails:\n\n- return the original error as-is\n- add context with `fmt.Errorf` and the `%w` verb\n- add context with `fmt.Errorf` and the `%v` verb\n\nReturn the original error as-is if there is no additional context to add.\nThis maintains the original error type and message.\nThis is well suited for cases when the underlying error message\nhas sufficient information to track down where it came from.\n\nOtherwise, add context to the error message where possible\nso that instead of a vague error such as \"connection refused\",\nyou get more useful errors such as \"call service foo: connection refused\".\n\nUse `fmt.Errorf` to add context to your errors,\npicking between the `%w` or `%v` verbs\nbased on whether the caller should be able to\nmatch and extract the underlying cause.\n\n- Use `%w` if the caller should have access to the underlying error.\n  This is a good default for most wrapped errors,\n  but be aware that callers may begin to rely on this behavior.\n  So for cases where the wrapped error is a known `var` or type,\n  document and test it as part of your function's contract.\n- Use `%v` to obfuscate the underlying error.\n  Callers will be unable to match it,\n  but you can switch to `%w` in the future if needed.\n\nWhen adding context to returned errors, keep the context succinct by avoiding\nphrases like \"failed to\", which state the obvious and pile up as the error\npercolates up through the stack:\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ns, err := store.New()\nif err != nil {\n    return fmt.Errorf(\n        \"failed to create new store: %w\", err)\n}\n```\n\n</td><td>\n\n```go\ns, err := store.New()\nif err != nil {\n    return fmt.Errorf(\n        \"new store: %w\", err)\n}\n```\n\n</td></tr><tr><td>\n\n```plain\nfailed to x: failed to y: failed to create new store: the error\n```\n\n</td><td>\n\n```plain\nx: y: new store: the error\n```\n\n</td></tr>\n</tbody></table>\n\nHowever once the error is sent to another system, it should be clear the\nmessage is an error (e.g. an `err` tag or \"Failed\" prefix in logs).\n\nSee also [Don't just check errors, handle them gracefully](https://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully).\n\n#### Error Naming\n\nFor error values stored as global variables,\nuse the prefix `Err` or `err` depending on whether they're exported.\nThis guidance supersedes the [Prefix Unexported Globals with _](#prefix-unexported-globals-with-_).\n\n```go\nvar (\n  // The following two errors are exported\n  // so that users of this package can match them\n  // with errors.Is.\n\n  ErrBrokenLink = errors.New(\"link is broken\")\n  ErrCouldNotOpen = errors.New(\"could not open\")\n\n  // This error is not exported because\n  // we don't want to make it part of our public API.\n  // We may still use it inside the package\n  // with errors.Is.\n\n  errNotFound = errors.New(\"not found\")\n)\n```\n\nFor custom error types, use the suffix `Error` instead.\n\n```go\n// Similarly, this error is exported\n// so that users of this package can match it\n// with errors.As.\n\ntype NotFoundError struct {\n  File string\n}\n\nfunc (e *NotFoundError) Error() string {\n  return fmt.Sprintf(\"file %q not found\", e.File)\n}\n\n// And this error is not exported because\n// we don't want to make it part of the public API.\n// We can still use it inside the package\n// with errors.As.\n\ntype resolveError struct {\n  Path string\n}\n\nfunc (e *resolveError) Error() string {\n  return fmt.Sprintf(\"resolve %q\", e.Path)\n}\n```\n\n#### Handle Errors Once\n\nWhen a caller receives an error from a callee,\nit can handle it in a variety of different ways\ndepending on what it knows about the error.\n\nThese include, but not are limited to:\n\n- if the callee contract defines specific errors,\n  matching the error with `errors.Is` or `errors.As`\n  and handling the branches differently\n- if the error is recoverable,\n  logging the error and degrading gracefully\n- if the error represents a domain-specific failure condition,\n  returning a well-defined error\n- returning the error, either [wrapped](#error-wrapping) or verbatim\n\nRegardless of how the caller handles the error,\nit should typically handle each error only once.\nThe caller should not, for example, log the error and then return it,\nbecause *its* callers may handle the error as well.\n\nFor example, consider the following cases:\n\n<table>\n<thead><tr><th>Description</th><th>Code</th></tr></thead>\n<tbody>\n<tr><td>\n\n**Bad**: Log the error and return it\n\nCallers further up the stack will likely take a similar action with the error.\nDoing so makes a lot of noise in the application logs for little value.\n\n</td><td>\n\n```go\nu, err := getUser(id)\nif err != nil {\n  // BAD: See description\n  log.Printf(\"Could not get user %q: %v\", id, err)\n  return err\n}\n```\n\n</td></tr>\n<tr><td>\n\n**Good**: Wrap the error and return it\n\nCallers further up the stack will handle the error.\nUse of `%w` ensures they can match the error with `errors.Is` or `errors.As`\nif relevant.\n\n</td><td>\n\n```go\nu, err := getUser(id)\nif err != nil {\n  return fmt.Errorf(\"get user %q: %w\", id, err)\n}\n```\n\n</td></tr>\n<tr><td>\n\n**Good**: Log the error and degrade gracefully\n\nIf the operation isn't strictly necessary,\nwe can provide a degraded but unbroken experience\nby recovering from it.\n\n</td><td>\n\n```go\nif err := emitMetrics(); err != nil {\n  // Failure to write metrics should not\n  // break the application.\n  log.Printf(\"Could not emit metrics: %v\", err)\n}\n\n```\n\n</td></tr>\n<tr><td>\n\n**Good**: Match the error and degrade gracefully\n\nIf the callee defines a specific error in its contract,\nand the failure is recoverable,\nmatch on that error case and degrade gracefully.\nFor all other cases, wrap the error and return it.\n\nCallers further up the stack will handle other errors.\n\n</td><td>\n\n```go\ntz, err := getUserTimeZone(id)\nif err != nil {\n  if errors.Is(err, ErrUserNotFound) {\n    // User doesn't exist. Use UTC.\n    tz = time.UTC\n  } else {\n    return fmt.Errorf(\"get user %q: %w\", id, err)\n  }\n}\n```\n\n</td></tr>\n</tbody></table>\n\n### Handle Type Assertion Failures\n\nThe single return value form of a [type assertion](https://go.dev/ref/spec#Type_assertions) will panic on an incorrect\ntype. Therefore, always use the \"comma ok\" idiom.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nt := i.(string)\n```\n\n</td><td>\n\n```go\nt, ok := i.(string)\nif !ok {\n  // handle the error gracefully\n}\n```\n\n</td></tr>\n</tbody></table>\n\n<!-- TODO: There are a few situations where the single assignment form is\nfine. -->\n\n### Don't Panic\n\nCode running in production must avoid panics. Panics are a major source of\n[cascading failures](https://en.wikipedia.org/wiki/Cascading_failure). If an error occurs, the function must return an error and\nallow the caller to decide how to handle it.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc run(args []string) {\n  if len(args) == 0 {\n    panic(\"an argument is required\")\n  }\n  // ...\n}\n\nfunc main() {\n  run(os.Args[1:])\n}\n```\n\n</td><td>\n\n```go\nfunc run(args []string) error {\n  if len(args) == 0 {\n    return errors.New(\"an argument is required\")\n  }\n  // ...\n  return nil\n}\n\nfunc main() {\n  if err := run(os.Args[1:]); err != nil {\n    fmt.Fprintln(os.Stderr, err)\n    os.Exit(1)\n  }\n}\n```\n\n</td></tr>\n</tbody></table>\n\nPanic/recover is not an error handling strategy. A program must panic only when\nsomething irrecoverable happens such as a nil dereference. An exception to this is\nprogram initialization: bad things at program startup that should abort the\nprogram may cause panic.\n\n```go\nvar _statusTemplate = template.Must(template.New(\"name\").Parse(\"_statusHTML\"))\n```\n\nEven in tests, prefer `t.Fatal` or `t.FailNow` over panics to ensure that the\ntest is marked as failed.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// func TestFoo(t *testing.T)\n\nf, err := os.CreateTemp(\"\", \"test\")\nif err != nil {\n  panic(\"failed to set up test\")\n}\n```\n\n</td><td>\n\n```go\n// func TestFoo(t *testing.T)\n\nf, err := os.CreateTemp(\"\", \"test\")\nif err != nil {\n  t.Fatal(\"failed to set up test\")\n}\n```\n\n</td></tr>\n</tbody></table>\n\n### Use go.uber.org/atomic\n\nAtomic operations with the [sync/atomic](https://pkg.go.dev/sync/atomic) package operate on the raw types\n(`int32`, `int64`, etc.) so it is easy to forget to use the atomic operation to\nread or modify the variables.\n\n[go.uber.org/atomic](https://pkg.go.dev/go.uber.org/atomic) adds type safety to these operations by hiding the\nunderlying type. Additionally, it includes a convenient `atomic.Bool` type.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype foo struct {\n  running int32  // atomic\n}\n\nfunc (f* foo) start() {\n  if atomic.SwapInt32(&f.running, 1) == 1 {\n     // already running…\n     return\n  }\n  // start the Foo\n}\n\nfunc (f *foo) isRunning() bool {\n  return f.running == 1  // race!\n}\n```\n\n</td><td>\n\n```go\ntype foo struct {\n  running atomic.Bool\n}\n\nfunc (f *foo) start() {\n  if f.running.Swap(true) {\n     // already running…\n     return\n  }\n  // start the Foo\n}\n\nfunc (f *foo) isRunning() bool {\n  return f.running.Load()\n}\n```\n\n</td></tr>\n</tbody></table>\n\n### Avoid Mutable Globals\n\nAvoid mutating global variables, instead opting for dependency injection.\nThis applies to function pointers as well as other kinds of values.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// sign.go\n\nvar _timeNow = time.Now\n\nfunc sign(msg string) string {\n  now := _timeNow()\n  return signWithTime(msg, now)\n}\n```\n\n</td><td>\n\n```go\n// sign.go\n\ntype signer struct {\n  now func() time.Time\n}\n\nfunc newSigner() *signer {\n  return &signer{\n    now: time.Now,\n  }\n}\n\nfunc (s *signer) Sign(msg string) string {\n  now := s.now()\n  return signWithTime(msg, now)\n}\n```\n\n</td></tr>\n<tr><td>\n\n```go\n// sign_test.go\n\nfunc TestSign(t *testing.T) {\n  oldTimeNow := _timeNow\n  _timeNow = func() time.Time {\n    return someFixedTime\n  }\n  defer func() { _timeNow = oldTimeNow }()\n\n  assert.Equal(t, want, sign(give))\n}\n```\n\n</td><td>\n\n```go\n// sign_test.go\n\nfunc TestSigner(t *testing.T) {\n  s := newSigner()\n  s.now = func() time.Time {\n    return someFixedTime\n  }\n\n  assert.Equal(t, want, s.Sign(give))\n}\n```\n\n</td></tr>\n</tbody></table>\n\n### Avoid Embedding Types in Public Structs\n\nThese embedded types leak implementation details, inhibit type evolution, and\nobscure documentation.\n\nAssuming you have implemented a variety of list types using a shared\n`AbstractList`, avoid embedding the `AbstractList` in your concrete list\nimplementations.\nInstead, hand-write only the methods to your concrete list that will delegate\nto the abstract list.\n\n```go\ntype AbstractList struct {}\n\n// Add adds an entity to the list.\nfunc (l *AbstractList) Add(e Entity) {\n  // ...\n}\n\n// Remove removes an entity from the list.\nfunc (l *AbstractList) Remove(e Entity) {\n  // ...\n}\n```\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// ConcreteList is a list of entities.\ntype ConcreteList struct {\n  *AbstractList\n}\n```\n\n</td><td>\n\n```go\n// ConcreteList is a list of entities.\ntype ConcreteList struct {\n  list *AbstractList\n}\n\n// Add adds an entity to the list.\nfunc (l *ConcreteList) Add(e Entity) {\n  l.list.Add(e)\n}\n\n// Remove removes an entity from the list.\nfunc (l *ConcreteList) Remove(e Entity) {\n  l.list.Remove(e)\n}\n```\n\n</td></tr>\n</tbody></table>\n\nGo allows [type embedding](https://go.dev/doc/effective_go#embedding) as a compromise between inheritance and composition.\nThe outer type gets implicit copies of the embedded type's methods.\nThese methods, by default, delegate to the same method of the embedded\ninstance.\n\nThe struct also gains a field by the same name as the type.\nSo, if the embedded type is public, the field is public.\nTo maintain backward compatibility, every future version of the outer type must\nkeep the embedded type.\n\nAn embedded type is rarely necessary.\nIt is a convenience that helps you avoid writing tedious delegate methods.\n\nEven embedding a compatible AbstractList *interface*, instead of the struct,\nwould offer the developer more flexibility to change in the future, but still\nleak the detail that the concrete lists use an abstract implementation.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// AbstractList is a generalized implementation\n// for various kinds of lists of entities.\ntype AbstractList interface {\n  Add(Entity)\n  Remove(Entity)\n}\n\n// ConcreteList is a list of entities.\ntype ConcreteList struct {\n  AbstractList\n}\n```\n\n</td><td>\n\n```go\n// ConcreteList is a list of entities.\ntype ConcreteList struct {\n  list AbstractList\n}\n\n// Add adds an entity to the list.\nfunc (l *ConcreteList) Add(e Entity) {\n  l.list.Add(e)\n}\n\n// Remove removes an entity from the list.\nfunc (l *ConcreteList) Remove(e Entity) {\n  l.list.Remove(e)\n}\n```\n\n</td></tr>\n</tbody></table>\n\nEither with an embedded struct or an embedded interface, the embedded type\nplaces limits on the evolution of the type.\n\n- Adding methods to an embedded interface is a breaking change.\n- Removing methods from an embedded struct is a breaking change.\n- Removing the embedded type is a breaking change.\n- Replacing the embedded type, even with an alternative that satisfies the same\n  interface, is a breaking change.\n\nAlthough writing these delegate methods is tedious, the additional effort hides\nan implementation detail, leaves more opportunities for change, and also\neliminates indirection for discovering the full List interface in\ndocumentation.\n\n### Avoid Using Built-In Names\n\nThe Go [language specification](https://go.dev/ref/spec) outlines several built-in,\n[predeclared identifiers](https://go.dev/ref/spec#Predeclared_identifiers) that should not be used as names within Go programs.\n\nDepending on context, reusing these identifiers as names will either shadow\nthe original within the current lexical scope (and any nested scopes) or make\naffected code confusing. In the best case, the compiler will complain; in the\nworst case, such code may introduce latent, hard-to-grep bugs.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nvar error string\n// `error` shadows the builtin\n\n// or\n\nfunc handleErrorMessage(error string) {\n    // `error` shadows the builtin\n}\n```\n\n</td><td>\n\n```go\nvar errorMessage string\n// `error` refers to the builtin\n\n// or\n\nfunc handleErrorMessage(msg string) {\n    // `error` refers to the builtin\n}\n```\n\n</td></tr>\n<tr><td>\n\n```go\ntype Foo struct {\n    // While these fields technically don't\n    // constitute shadowing, grepping for\n    // `error` or `string` strings is now\n    // ambiguous.\n    error  error\n    string string\n}\n\nfunc (f Foo) Error() error {\n    // `error` and `f.error` are\n    // visually similar\n    return f.error\n}\n\nfunc (f Foo) String() string {\n    // `string` and `f.string` are\n    // visually similar\n    return f.string\n}\n```\n\n</td><td>\n\n```go\ntype Foo struct {\n    // `error` and `string` strings are\n    // now unambiguous.\n    err error\n    str string\n}\n\nfunc (f Foo) Error() error {\n    return f.err\n}\n\nfunc (f Foo) String() string {\n    return f.str\n}\n```\n\n</td></tr>\n</tbody></table>\n\nNote that the compiler will not generate errors when using predeclared\nidentifiers, but tools such as `go vet` should correctly point out these and\nother cases of shadowing.\n\n### Avoid `init()`\n\nAvoid `init()` where possible. When `init()` is unavoidable or desirable, code\nshould attempt to:\n\n1. Be completely deterministic, regardless of program environment or invocation.\n2. Avoid depending on the ordering or side-effects of other `init()` functions.\n   While `init()` ordering is well-known, code can change, and thus\n   relationships between `init()` functions can make code brittle and\n   error-prone.\n3. Avoid accessing or manipulating global or environment state, such as machine\n   information, environment variables, working directory, program\n   arguments/inputs, etc.\n4. Avoid I/O, including both filesystem, network, and system calls.\n\nCode that cannot satisfy these requirements likely belongs as a helper to be\ncalled as part of `main()` (or elsewhere in a program's lifecycle), or be\nwritten as part of `main()` itself. In particular, libraries that are intended\nto be used by other programs should take special care to be completely\ndeterministic and not perform \"init magic\".\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype Foo struct {\n    // ...\n}\n\nvar _defaultFoo Foo\n\nfunc init() {\n    _defaultFoo = Foo{\n        // ...\n    }\n}\n```\n\n</td><td>\n\n```go\nvar _defaultFoo = Foo{\n    // ...\n}\n\n// or, better, for testability:\n\nvar _defaultFoo = defaultFoo()\n\nfunc defaultFoo() Foo {\n    return Foo{\n        // ...\n    }\n}\n```\n\n</td></tr>\n<tr><td>\n\n```go\ntype Config struct {\n    // ...\n}\n\nvar _config Config\n\nfunc init() {\n    // Bad: based on current directory\n    cwd, _ := os.Getwd()\n\n    // Bad: I/O\n    raw, _ := os.ReadFile(\n        path.Join(cwd, \"config\", \"config.yaml\"),\n    )\n\n    yaml.Unmarshal(raw, &_config)\n}\n```\n\n</td><td>\n\n```go\ntype Config struct {\n    // ...\n}\n\nfunc loadConfig() Config {\n    cwd, err := os.Getwd()\n    // handle err\n\n    raw, err := os.ReadFile(\n        path.Join(cwd, \"config\", \"config.yaml\"),\n    )\n    // handle err\n\n    var config Config\n    yaml.Unmarshal(raw, &config)\n\n    return config\n}\n```\n\n</td></tr>\n</tbody></table>\n\nConsidering the above, some situations in which `init()` may be preferable or\nnecessary might include:\n\n- Complex expressions that cannot be represented as single assignments.\n- Pluggable hooks, such as `database/sql` dialects, encoding type registries, etc.\n- Optimizations to [Google Cloud Functions](https://cloud.google.com/functions/docs/bestpractices/tips#use_global_variables_to_reuse_objects_in_future_invocations) and other forms of deterministic\n  precomputation.\n\n### Exit in Main\n\nGo programs use [`os.Exit`](https://pkg.go.dev/os#Exit) or [`log.Fatal*`](https://pkg.go.dev/log#Fatal) to exit immediately. (Panicking\nis not a good way to exit programs, please [don't panic](#dont-panic).)\n\nCall one of `os.Exit` or `log.Fatal*` **only in `main()`**. All other\nfunctions should return errors to signal failure.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc main() {\n  body := readFile(path)\n  fmt.Println(body)\n}\n\nfunc readFile(path string) string {\n  f, err := os.Open(path)\n  if err != nil {\n    log.Fatal(err)\n  }\n\n  b, err := io.ReadAll(f)\n  if err != nil {\n    log.Fatal(err)\n  }\n\n  return string(b)\n}\n```\n\n</td><td>\n\n```go\nfunc main() {\n  body, err := readFile(path)\n  if err != nil {\n    log.Fatal(err)\n  }\n  fmt.Println(body)\n}\n\nfunc readFile(path string) (string, error) {\n  f, err := os.Open(path)\n  if err != nil {\n    return \"\", err\n  }\n\n  b, err := io.ReadAll(f)\n  if err != nil {\n    return \"\", err\n  }\n\n  return string(b), nil\n}\n```\n\n</td></tr>\n</tbody></table>\n\nRationale: Programs with multiple functions that exit present a few issues:\n\n- Non-obvious control flow: Any function can exit the program so it becomes\n  difficult to reason about the control flow.\n- Difficult to test: A function that exits the program will also exit the test\n  calling it. This makes the function difficult to test and introduces risk of\n  skipping other tests that have not yet been run by `go test`.\n- Skipped cleanup: When a function exits the program, it skips function calls\n  enqueued with `defer` statements. This adds risk of skipping important\n  cleanup tasks.\n\n#### Exit Once\n\nIf possible, prefer to call `os.Exit` or `log.Fatal` **at most once** in your\n`main()`. If there are multiple error scenarios that halt program execution,\nput that logic under a separate function and return errors from it.\n\nThis has the effect of shortening your `main()` function and putting all key\nbusiness logic into a separate, testable function.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\npackage main\n\nfunc main() {\n  args := os.Args[1:]\n  if len(args) != 1 {\n    log.Fatal(\"missing file\")\n  }\n  name := args[0]\n\n  f, err := os.Open(name)\n  if err != nil {\n    log.Fatal(err)\n  }\n  defer f.Close()\n\n  // If we call log.Fatal after this line,\n  // f.Close will not be called.\n\n  b, err := io.ReadAll(f)\n  if err != nil {\n    log.Fatal(err)\n  }\n\n  // ...\n}\n```\n\n</td><td>\n\n```go\npackage main\n\nfunc main() {\n  if err := run(); err != nil {\n    log.Fatal(err)\n  }\n}\n\nfunc run() error {\n  args := os.Args[1:]\n  if len(args) != 1 {\n    return errors.New(\"missing file\")\n  }\n  name := args[0]\n\n  f, err := os.Open(name)\n  if err != nil {\n    return err\n  }\n  defer f.Close()\n\n  b, err := io.ReadAll(f)\n  if err != nil {\n    return err\n  }\n\n  // ...\n}\n```\n\n</td></tr>\n</tbody></table>\n\nThe example above uses `log.Fatal`, but the guidance also applies to\n`os.Exit` or any library code that calls `os.Exit`.\n\n```go\nfunc main() {\n  if err := run(); err != nil {\n    fmt.Fprintln(os.Stderr, err)\n    os.Exit(1)\n  }\n}\n```\n\nYou may alter the signature of `run()` to fit your needs.\nFor example, if your program must exit with specific exit codes for failures,\n`run()` may return the exit code instead of an error.\nThis allows unit tests to verify this behavior directly as well.\n\n```go\nfunc main() {\n  os.Exit(run(args))\n}\n\nfunc run() (exitCode int) {\n  // ...\n}\n```\n\nMore generally, note that the `run()` function used in these examples\nis not intended to be prescriptive.\nThere's flexibility in the name, signature, and setup of the `run()` function.\nAmong other things, you may:\n\n- accept unparsed command line arguments (e.g., `run(os.Args[1:])`)\n- parse command line arguments in `main()` and pass them onto `run`\n- use a custom error type to carry the exit code back to `main()`\n- put business logic in a different layer of abstraction from `package main`\n\nThis guidance only requires that there's a single place in your `main()`\nresponsible for actually exiting the process.\n\n### Use field tags in marshaled structs\n\nAny struct field that is marshaled into JSON, YAML,\nor other formats that support tag-based field naming\nshould be annotated with the relevant tag.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype Stock struct {\n  Price int\n  Name  string\n}\n\nbytes, err := json.Marshal(Stock{\n  Price: 137,\n  Name:  \"UBER\",\n})\n```\n\n</td><td>\n\n```go\ntype Stock struct {\n  Price int    `json:\"price\"`\n  Name  string `json:\"name\"`\n  // Safe to rename Name to Symbol.\n}\n\nbytes, err := json.Marshal(Stock{\n  Price: 137,\n  Name:  \"UBER\",\n})\n```\n\n</td></tr>\n</tbody></table>\n\nRationale:\nThe serialized form of the structure is a contract between different systems.\nChanges to the structure of the serialized form--including field names--break\nthis contract. Specifying field names inside tags makes the contract explicit,\nand it guards against accidentally breaking the contract by refactoring or\nrenaming fields.\n\n### Don't fire-and-forget goroutines\n\nGoroutines are lightweight, but they're not free:\nat minimum, they cost memory for their stack and CPU to be scheduled.\nWhile these costs are small for typical uses of goroutines,\nthey can cause significant performance issues\nwhen spawned in large numbers without controlled lifetimes.\nGoroutines with unmanaged lifetimes can also cause other issues\nlike preventing unused objects from being garbage collected\nand holding onto resources that are otherwise no longer used.\n\nTherefore, do not leak goroutines in production code.\nUse [go.uber.org/goleak](https://pkg.go.dev/go.uber.org/goleak)\nto test for goroutine leaks inside packages that may spawn goroutines.\n\nIn general, every goroutine:\n\n- must have a predictable time at which it will stop running; or\n- there must be a way to signal to the goroutine that it should stop\n\nIn both cases, there must be a way for code to block and wait for the goroutine to\nfinish.\n\nFor example:\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ngo func() {\n  for {\n    flush()\n    time.Sleep(delay)\n  }\n}()\n```\n\n</td><td>\n\n```go\nvar (\n  stop = make(chan struct{}) // tells the goroutine to stop\n  done = make(chan struct{}) // tells us that the goroutine exited\n)\ngo func() {\n  defer close(done)\n\n  ticker := time.NewTicker(delay)\n  defer ticker.Stop()\n  for {\n    select {\n    case <-ticker.C:\n      flush()\n    case <-stop:\n      return\n    }\n  }\n}()\n\n// Elsewhere...\nclose(stop)  // signal the goroutine to stop\n<-done       // and wait for it to exit\n```\n\n</td></tr>\n<tr><td>\n\nThere's no way to stop this goroutine.\nThis will run until the application exits.\n\n</td><td>\n\nThis goroutine can be stopped with `close(stop)`,\nand we can wait for it to exit with `<-done`.\n\n</td></tr>\n</tbody></table>\n\n#### Wait for goroutines to exit\n\nGiven a goroutine spawned by the system,\nthere must be a way to wait for the goroutine to exit.\nThere are two popular ways to do this:\n\n- Use a `sync.WaitGroup` to wait for multiple goroutines to complete.\n  Do this if there are multiple goroutines that you want to wait for.\n\n  ```go\n  var wg sync.WaitGroup\n  for i := 0; i < N; i++ {\n    wg.Go(...)\n  }\n\n  // To wait for all to finish:\n  wg.Wait()\n  ```\n\n- Add another `chan struct{}` that the goroutine closes when it's done.\n  Do this if there's only one goroutine.\n\n  ```go\n  done := make(chan struct{})\n  go func() {\n    defer close(done)\n    // ...\n  }()\n\n  // To wait for the goroutine to finish:\n  <-done\n  ```\n\n#### No goroutines in `init()`\n\n`init()` functions should not spawn goroutines.\nSee also [Avoid init()](#avoid-init).\n\nIf a package has need of a background goroutine,\nit must expose an object that is responsible for managing a goroutine's\nlifetime.\nThe object must provide a method (`Close`, `Stop`, `Shutdown`, etc)\nthat signals the background goroutine to stop, and waits for it to exit.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc init() {\n  go doWork()\n}\n\nfunc doWork() {\n  for {\n    // ...\n  }\n}\n```\n\n</td><td>\n\n```go\ntype Worker struct{ /* ... */ }\n\nfunc NewWorker(...) *Worker {\n  w := &Worker{\n    stop: make(chan struct{}),\n    done: make(chan struct{}),\n    // ...\n  }\n  go w.doWork()\n  return w\n}\n\nfunc (w *Worker) doWork() {\n  defer close(w.done)\n  for {\n    // ...\n    case <-w.stop:\n      return\n  }\n}\n\n// Shutdown tells the worker to stop\n// and waits until it has finished.\nfunc (w *Worker) Shutdown() {\n  close(w.stop)\n  <-w.done\n}\n```\n\n</td></tr>\n<tr><td>\n\nSpawns a background goroutine unconditionally when the user exports this package.\nThe user has no control over the goroutine or a means of stopping it.\n\n</td><td>\n\nSpawns the worker only if the user requests it.\nProvides a means of shutting down the worker so that the user can free up\nresources used by the worker.\n\nNote that you should use `WaitGroup`s if the worker manages multiple\ngoroutines.\nSee [Wait for goroutines to exit](#wait-for-goroutines-to-exit).\n\n</td></tr>\n</tbody></table>\n\n## Performance\n\nPerformance-specific guidelines apply only to the hot path.\n\n### Prefer strconv over fmt\n\nWhen converting primitives to/from strings, `strconv` is faster than\n`fmt`.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfor i := 0; i < b.N; i++ {\n  s := fmt.Sprint(rand.Int())\n}\n```\n\n</td><td>\n\n```go\nfor i := 0; i < b.N; i++ {\n  s := strconv.Itoa(rand.Int())\n}\n```\n\n</td></tr>\n<tr><td>\n\n```plain\nBenchmarkFmtSprint-4    143 ns/op    2 allocs/op\n```\n\n</td><td>\n\n```plain\nBenchmarkStrconv-4    64.2 ns/op    1 allocs/op\n```\n\n</td></tr>\n</tbody></table>\n\n### Avoid repeated string-to-byte conversions\n\nDo not create byte slices from a fixed string repeatedly. Instead, perform the\nconversion once and capture the result.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfor i := 0; i < b.N; i++ {\n  w.Write([]byte(\"Hello world\"))\n}\n```\n\n</td><td>\n\n```go\ndata := []byte(\"Hello world\")\nfor i := 0; i < b.N; i++ {\n  w.Write(data)\n}\n```\n\n</td></tr>\n<tr><td>\n\n```plain\nBenchmarkBad-4   50000000   22.2 ns/op\n```\n\n</td><td>\n\n```plain\nBenchmarkGood-4  500000000   3.25 ns/op\n```\n\n</td></tr>\n</tbody></table>\n\n### Prefer Specifying Container Capacity\n\nSpecify container capacity where possible in order to allocate memory for the\ncontainer up front. This minimizes subsequent allocations (by copying and\nresizing of the container) as elements are added.\n\n#### Specifying Map Capacity Hints\n\nWhere possible, provide capacity hints when initializing\nmaps with `make()`.\n\n```go\nmake(map[T1]T2, hint)\n```\n\nProviding a capacity hint to `make()` tries to right-size the\nmap at initialization time, which reduces the need for growing\nthe map and allocations as elements are added to the map.\n\nNote that, unlike slices, map capacity hints do not guarantee complete,\npreemptive allocation, but are used to approximate the number of hashmap buckets\nrequired. Consequently, allocations may still occur when adding elements to the\nmap, even up to the specified capacity.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfiles, _ := os.ReadDir(\"./files\")\n\nm := make(map[string]os.DirEntry)\nfor _, f := range files {\n    m[f.Name()] = f\n}\n```\n\n</td><td>\n\n```go\n\nfiles, _ := os.ReadDir(\"./files\")\n\nm := make(map[string]os.DirEntry, len(files))\nfor _, f := range files {\n    m[f.Name()] = f\n}\n```\n\n</td></tr>\n<tr><td>\n\n`m` is created without a size hint; the map will resize\ndynamically, causing multiple allocations as it grows.\n\n</td><td>\n\n`m` is created with a size hint; there may be fewer\nallocations at assignment time.\n\n</td></tr>\n</tbody></table>\n\n#### Specifying Slice Capacity\n\nWhere possible, provide capacity hints when initializing slices with `make()`,\nparticularly when appending.\n\n```go\nmake([]T, length, capacity)\n```\n\nUnlike maps, slice capacity is not a hint: the compiler will allocate enough\nmemory for the capacity of the slice as provided to `make()`, which means that\nsubsequent `append()` operations will incur zero allocations (until the length\nof the slice matches the capacity, after which any appends will require a resize\nto hold additional elements).\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfor n := 0; n < b.N; n++ {\n  data := make([]int, 0)\n  for k := 0; k < size; k++{\n    data = append(data, k)\n  }\n}\n```\n\n</td><td>\n\n```go\nfor n := 0; n < b.N; n++ {\n  data := make([]int, 0, size)\n  for k := 0; k < size; k++{\n    data = append(data, k)\n  }\n}\n```\n\n</td></tr>\n<tr><td>\n\n```plain\nBenchmarkBad-4    100000000    2.48s\n```\n\n</td><td>\n\n```plain\nBenchmarkGood-4   100000000    0.21s\n```\n\n</td></tr>\n</tbody></table>\n\n## Style\n\n### Avoid overly long lines\n\nAvoid lines of code that require readers to scroll horizontally\nor turn their heads too much.\n\nWe recommend a soft line length limit of **99 characters**.\nAuthors should aim to wrap lines before hitting this limit,\nbut it is not a hard limit.\nCode is allowed to exceed this limit.\n\n### Be Consistent\n\nSome of the guidelines outlined in this document can be evaluated objectively;\nothers are situational, contextual, or subjective.\n\nAbove all else, **be consistent**.\n\nConsistent code is easier to maintain, is easier to rationalize, requires less\ncognitive overhead, and is easier to migrate or update as new conventions emerge\nor classes of bugs are fixed.\n\nConversely, having multiple disparate or conflicting styles within a single\ncodebase causes maintenance overhead, uncertainty, and cognitive dissonance,\nall of which can directly contribute to lower velocity, painful code reviews,\nand bugs.\n\nWhen applying these guidelines to a codebase, it is recommended that changes\nare made at a package (or larger) level: application at a sub-package level\nviolates the above concern by introducing multiple styles into the same code.\n\n### Group Similar Declarations\n\nGo supports grouping similar declarations.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nimport \"a\"\nimport \"b\"\n```\n\n</td><td>\n\n```go\nimport (\n  \"a\"\n  \"b\"\n)\n```\n\n</td></tr>\n</tbody></table>\n\nThis also applies to constants, variables, and type declarations.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n\nconst a = 1\nconst b = 2\n\n\n\nvar a = 1\nvar b = 2\n\n\n\ntype Area float64\ntype Volume float64\n```\n\n</td><td>\n\n```go\nconst (\n  a = 1\n  b = 2\n)\n\nvar (\n  a = 1\n  b = 2\n)\n\ntype (\n  Area float64\n  Volume float64\n)\n```\n\n</td></tr>\n</tbody></table>\n\nOnly group related declarations. Do not group declarations that are unrelated.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype Operation int\n\nconst (\n  Add Operation = iota + 1\n  Subtract\n  Multiply\n  EnvVar = \"MY_ENV\"\n)\n```\n\n</td><td>\n\n```go\ntype Operation int\n\nconst (\n  Add Operation = iota + 1\n  Subtract\n  Multiply\n)\n\nconst EnvVar = \"MY_ENV\"\n```\n\n</td></tr>\n</tbody></table>\n\nGroups are not limited in where they can be used. For example, you can use them\ninside of functions.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc f() string {\n  red := color.New(0xff0000)\n  green := color.New(0x00ff00)\n  blue := color.New(0x0000ff)\n\n  // ...\n}\n```\n\n</td><td>\n\n```go\nfunc f() string {\n  var (\n    red   = color.New(0xff0000)\n    green = color.New(0x00ff00)\n    blue  = color.New(0x0000ff)\n  )\n\n  // ...\n}\n```\n\n</td></tr>\n</tbody></table>\n\nException: Variable declarations, particularly inside functions, should be\ngrouped together if declared adjacent to other variables. Do this for variables\ndeclared together even if they are unrelated.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc (c *client) request() {\n  caller := c.name\n  format := \"json\"\n  timeout := 5*time.Second\n  var err error\n\n  // ...\n}\n```\n\n</td><td>\n\n```go\nfunc (c *client) request() {\n  var (\n    caller  = c.name\n    format  = \"json\"\n    timeout = 5*time.Second\n    err error\n  )\n\n  // ...\n}\n```\n\n</td></tr>\n</tbody></table>\n\n### Import Group Ordering\n\nThere should be two import groups:\n\n- Standard library\n- Everything else\n\nThis is the grouping applied by goimports by default.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nimport (\n  \"fmt\"\n  \"os\"\n  \"go.uber.org/atomic\"\n  \"golang.org/x/sync/errgroup\"\n)\n```\n\n</td><td>\n\n```go\nimport (\n  \"fmt\"\n  \"os\"\n\n  \"go.uber.org/atomic\"\n  \"golang.org/x/sync/errgroup\"\n)\n```\n\n</td></tr>\n</tbody></table>\n\n### Package Names\n\nWhen naming packages, choose a name that is:\n\n- All lower-case. No capitals or underscores.\n- Does not need to be renamed using named imports at most call sites.\n- Short and succinct. Remember that the name is identified in full at every call\n  site.\n- Not plural. For example, `net/url`, not `net/urls`.\n- Not \"common\", \"util\", \"shared\", or \"lib\". These are bad, uninformative names.\n\nSee also [Package Names](https://go.dev/blog/package-names) and [Style guideline for Go packages](https://rakyll.org/style-packages/).\n\n### Function Names\n\nWe follow the Go community's convention of using [MixedCaps for function\nnames](https://go.dev/doc/effective_go#mixed-caps). An exception is made for test functions, which may contain underscores\nfor the purpose of grouping related test cases, e.g.,\n`TestMyFunction_WhatIsBeingTested`.\n\n### Import Aliasing\n\nImport aliasing must be used if the package name does not match the last\nelement of the import path.\n\n```go\nimport (\n  \"net/http\"\n\n  client \"example.com/client-go\"\n  trace \"example.com/trace/v2\"\n)\n```\n\nIn all other scenarios, import aliases should be avoided unless there is a\ndirect conflict between imports.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nimport (\n  \"fmt\"\n  \"os\"\n  runtimetrace \"runtime/trace\"\n\n  nettrace \"golang.net/x/trace\"\n)\n```\n\n</td><td>\n\n```go\nimport (\n  \"fmt\"\n  \"os\"\n  \"runtime/trace\"\n\n  nettrace \"golang.net/x/trace\"\n)\n```\n\n</td></tr>\n</tbody></table>\n\n### Function Grouping and Ordering\n\n- Functions should be sorted in rough call order.\n- Functions in a file should be grouped by receiver.\n\nTherefore, exported functions should appear first in a file, after\n`struct`, `const`, `var` definitions.\n\nA `newXYZ()`/`NewXYZ()` may appear after the type is defined, but before the\nrest of the methods on the receiver.\n\nSince functions are grouped by receiver, plain utility functions should appear\ntowards the end of the file.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc (s *something) Cost() {\n  return calcCost(s.weights)\n}\n\ntype something struct{ ... }\n\nfunc calcCost(n []int) int {...}\n\nfunc (s *something) Stop() {...}\n\nfunc newSomething() *something {\n    return &something{}\n}\n```\n\n</td><td>\n\n```go\ntype something struct{ ... }\n\nfunc newSomething() *something {\n    return &something{}\n}\n\nfunc (s *something) Cost() {\n  return calcCost(s.weights)\n}\n\nfunc (s *something) Stop() {...}\n\nfunc calcCost(n []int) int {...}\n```\n\n</td></tr>\n</tbody></table>\n\n### Reduce Nesting\n\nCode should reduce nesting where possible by handling error cases/special\nconditions first and returning early or continuing the loop. Reduce the amount\nof code that is nested multiple levels.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfor _, v := range data {\n  if v.F1 == 1 {\n    v = process(v)\n    if err := v.Call(); err == nil {\n      v.Send()\n    } else {\n      return err\n    }\n  } else {\n    log.Printf(\"Invalid v: %v\", v)\n  }\n}\n```\n\n</td><td>\n\n```go\nfor _, v := range data {\n  if v.F1 != 1 {\n    log.Printf(\"Invalid v: %v\", v)\n    continue\n  }\n\n  v = process(v)\n  if err := v.Call(); err != nil {\n    return err\n  }\n  v.Send()\n}\n```\n\n</td></tr>\n</tbody></table>\n\n### Unnecessary Else\n\nIf a variable is set in both branches of an if, it can be replaced with a\nsingle if.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nvar a int\nif b {\n  a = 100\n} else {\n  a = 10\n}\n```\n\n</td><td>\n\n```go\na := 10\nif b {\n  a = 100\n}\n```\n\n</td></tr>\n</tbody></table>\n\n### Top-level Variable Declarations\n\nAt the top level, use the standard `var` keyword. Do not specify the type,\nunless it is not the same type as the expression.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nvar _s string = F()\n\nfunc F() string { return \"A\" }\n```\n\n</td><td>\n\n```go\nvar _s = F()\n// Since F already states that it returns a string, we don't need to specify\n// the type again.\n\nfunc F() string { return \"A\" }\n```\n\n</td></tr>\n</tbody></table>\n\nSpecify the type if the type of the expression does not match the desired type\nexactly.\n\n```go\ntype myError struct{}\n\nfunc (myError) Error() string { return \"error\" }\n\nfunc F() myError { return myError{} }\n\nvar _e error = F()\n// F returns an object of type myError but we want error.\n```\n\n### Prefix Unexported Globals with _\n\nPrefix unexported top-level `var`s and `const`s with `_` to make it clear when\nthey are used that they are global symbols.\n\nRationale: Top-level variables and constants have a package scope. Using a\ngeneric name makes it easy to accidentally use the wrong value in a different\nfile.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// foo.go\n\nconst (\n  defaultPort = 8080\n  defaultUser = \"user\"\n)\n\n// bar.go\n\nfunc Bar() {\n  defaultPort := 9090\n  ...\n  fmt.Println(\"Default port\", defaultPort)\n\n  // We will not see a compile error if the first line of\n  // Bar() is deleted.\n}\n```\n\n</td><td>\n\n```go\n// foo.go\n\nconst (\n  _defaultPort = 8080\n  _defaultUser = \"user\"\n)\n```\n\n</td></tr>\n</tbody></table>\n\n**Exception**: Unexported error values may use the prefix `err` without the underscore.\nSee [Error Naming](#error-naming).\n\n### Embedding in Structs\n\nEmbedded types should be at the top of the field list of a\nstruct, and there must be an empty line separating embedded fields from regular\nfields.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype Client struct {\n  version int\n  http.Client\n}\n```\n\n</td><td>\n\n```go\ntype Client struct {\n  http.Client\n\n  version int\n}\n```\n\n</td></tr>\n</tbody></table>\n\nEmbedding should provide tangible benefit, like adding or augmenting\nfunctionality in a semantically-appropriate way. It should do this with zero\nadverse user-facing effects (see also: [Avoid Embedding Types in Public Structs](#avoid-embedding-types-in-public-structs)).\n\nException: Mutexes should not be embedded, even on unexported types. See also: [Zero-value Mutexes are Valid](#zero-value-mutexes-are-valid).\n\nEmbedding **should not**:\n\n- Be purely cosmetic or convenience-oriented.\n- Make outer types more difficult to construct or use.\n- Affect outer types' zero values. If the outer type has a useful zero value, it\n  should still have a useful zero value after embedding the inner type.\n- Expose unrelated functions or fields from the outer type as a side-effect of\n  embedding the inner type.\n- Expose unexported types.\n- Affect outer types' copy semantics.\n- Change the outer type's API or type semantics.\n- Embed a non-canonical form of the inner type.\n- Expose implementation details of the outer type.\n- Allow users to observe or control type internals.\n- Change the general behavior of inner functions through wrapping in a way that\n  would reasonably surprise users.\n\nSimply put, embed consciously and intentionally. A good litmus test is, \"would\nall of these exported inner methods/fields be added directly to the outer type\";\nif the answer is \"some\" or \"no\", don't embed the inner type - use a field\ninstead.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\ntype A struct {\n    // Bad: A.Lock() and A.Unlock() are\n    //      now available, provide no\n    //      functional benefit, and allow\n    //      users to control details about\n    //      the internals of A.\n    sync.Mutex\n}\n```\n\n</td><td>\n\n```go\ntype countingWriteCloser struct {\n    // Good: Write() is provided at this\n    //       outer layer for a specific\n    //       purpose, and delegates work\n    //       to the inner type's Write().\n    io.WriteCloser\n\n    count int\n}\n\nfunc (w *countingWriteCloser) Write(bs []byte) (int, error) {\n    w.count += len(bs)\n    return w.WriteCloser.Write(bs)\n}\n```\n\n</td></tr>\n<tr><td>\n\n```go\ntype Book struct {\n    // Bad: pointer changes zero value usefulness\n    io.ReadWriter\n\n    // other fields\n}\n\n// later\n\nvar b Book\nb.Read(...)  // panic: nil pointer\nb.String()   // panic: nil pointer\nb.Write(...) // panic: nil pointer\n```\n\n</td><td>\n\n```go\ntype Book struct {\n    // Good: has useful zero value\n    bytes.Buffer\n\n    // other fields\n}\n\n// later\n\nvar b Book\nb.Read(...)  // ok\nb.String()   // ok\nb.Write(...) // ok\n```\n\n</td></tr>\n<tr><td>\n\n```go\ntype Client struct {\n    sync.Mutex\n    sync.WaitGroup\n    bytes.Buffer\n    url.URL\n}\n```\n\n</td><td>\n\n```go\ntype Client struct {\n    mtx sync.Mutex\n    wg  sync.WaitGroup\n    buf bytes.Buffer\n    url url.URL\n}\n```\n\n</td></tr>\n</tbody></table>\n\n### Local Variable Declarations\n\nShort variable declarations (`:=`) should be used if a variable is being set to\nsome value explicitly.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nvar s = \"foo\"\n```\n\n</td><td>\n\n```go\ns := \"foo\"\n```\n\n</td></tr>\n</tbody></table>\n\nHowever, there are cases where the default value is clearer when the `var`\nkeyword is used. [Declaring Empty Slices](https://go.dev/wiki/CodeReviewComments#declaring-empty-slices), for example.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc f(list []int) {\n  filtered := []int{}\n  for _, v := range list {\n    if v > 10 {\n      filtered = append(filtered, v)\n    }\n  }\n}\n```\n\n</td><td>\n\n```go\nfunc f(list []int) {\n  var filtered []int\n  for _, v := range list {\n    if v > 10 {\n      filtered = append(filtered, v)\n    }\n  }\n}\n```\n\n</td></tr>\n</tbody></table>\n\n### nil is a valid slice\n\n`nil` is a valid slice of length 0. This means that,\n\n- You should not return a slice of length zero explicitly. Return `nil`\n  instead.\n\n  <table>\n  <thead><tr><th>Bad</th><th>Good</th></tr></thead>\n  <tbody>\n  <tr><td>\n\n  ```go\n  if x == \"\" {\n    return []int{}\n  }\n  ```\n\n  </td><td>\n\n  ```go\n  if x == \"\" {\n    return nil\n  }\n  ```\n\n  </td></tr>\n  </tbody></table>\n\n- To check if a slice is empty, always use `len(s) == 0`. Do not check for\n  `nil`.\n\n  <table>\n  <thead><tr><th>Bad</th><th>Good</th></tr></thead>\n  <tbody>\n  <tr><td>\n\n  ```go\n  func isEmpty(s []string) bool {\n    return s == nil\n  }\n  ```\n\n  </td><td>\n\n  ```go\n  func isEmpty(s []string) bool {\n    return len(s) == 0\n  }\n  ```\n\n  </td></tr>\n  </tbody></table>\n\n- The zero value (a slice declared with `var`) is usable immediately without\n  `make()`.\n\n  <table>\n  <thead><tr><th>Bad</th><th>Good</th></tr></thead>\n  <tbody>\n  <tr><td>\n\n  ```go\n  nums := []int{}\n  // or, nums := make([]int)\n\n  if add1 {\n    nums = append(nums, 1)\n  }\n\n  if add2 {\n    nums = append(nums, 2)\n  }\n  ```\n\n  </td><td>\n\n  ```go\n  var nums []int\n\n  if add1 {\n    nums = append(nums, 1)\n  }\n\n  if add2 {\n    nums = append(nums, 2)\n  }\n  ```\n\n  </td></tr>\n  </tbody></table>\n\nRemember that, while it is a valid slice, a nil slice is not equivalent to an\nallocated slice of length 0 - one is nil and the other is not - and the two may\nbe treated differently in different situations (such as serialization).\n\n### Reduce Scope of Variables\n\nWhere possible, reduce scope of variables and constants. Do not reduce the scope if it\nconflicts with [Reduce Nesting](#reduce-nesting).\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nerr := os.WriteFile(name, data, 0644)\nif err != nil {\n return err\n}\n```\n\n</td><td>\n\n```go\nif err := os.WriteFile(name, data, 0644); err != nil {\n return err\n}\n```\n\n</td></tr>\n</tbody></table>\n\nIf you need a result of a function call outside of the if, then you should not\ntry to reduce the scope.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nif data, err := os.ReadFile(name); err == nil {\n  err = cfg.Decode(data)\n  if err != nil {\n    return err\n  }\n\n  fmt.Println(cfg)\n  return nil\n} else {\n  return err\n}\n```\n\n</td><td>\n\n```go\ndata, err := os.ReadFile(name)\nif err != nil {\n   return err\n}\n\nif err := cfg.Decode(data); err != nil {\n  return err\n}\n\nfmt.Println(cfg)\nreturn nil\n```\n\n</td></tr>\n</tbody></table>\n\nConstants do not need to be global unless they are used in multiple functions or files\nor are part of an external contract of the package.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nconst (\n  _defaultPort = 8080\n  _defaultUser = \"user\"\n)\n\nfunc Bar() {\n  fmt.Println(\"Default port\", _defaultPort)\n}\n```\n\n</td><td>\n\n```go\nfunc Bar() {\n  const (\n    defaultPort = 8080\n    defaultUser = \"user\"\n  )\n  fmt.Println(\"Default port\", defaultPort)\n}\n```\n\n</td></tr>\n</tbody></table>\n\n### Avoid Naked Parameters\n\nNaked parameters in function calls can hurt readability. Add C-style comments\n(`/* ... */`) for parameter names when their meaning is not obvious.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// func printInfo(name string, isLocal, done bool)\n\nprintInfo(\"foo\", true, true)\n```\n\n</td><td>\n\n```go\n// func printInfo(name string, isLocal, done bool)\n\nprintInfo(\"foo\", true /* isLocal */, true /* done */)\n```\n\n</td></tr>\n</tbody></table>\n\nBetter yet, replace naked `bool` types with custom types for more readable and\ntype-safe code. This allows more than just two states (true/false) for that\nparameter in the future.\n\n```go\ntype Region int\n\nconst (\n  UnknownRegion Region = iota\n  Local\n)\n\ntype Status int\n\nconst (\n  StatusReady Status = iota + 1\n  StatusDone\n  // Maybe we will have a StatusInProgress in the future.\n)\n\nfunc printInfo(name string, region Region, status Status)\n```\n\n### Use Raw String Literals to Avoid Escaping\n\nGo supports [raw string literals](https://go.dev/ref/spec#raw_string_lit),\nwhich can span multiple lines and include quotes. Use these to avoid\nhand-escaped strings which are much harder to read.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nwantError := \"unknown name:\\\"test\\\"\"\n```\n\n</td><td>\n\n```go\nwantError := `unknown error:\"test\"`\n```\n\n</td></tr>\n</tbody></table>\n\n### Initializing Structs\n\n#### Use Field Names to Initialize Structs\n\nYou should almost always specify field names when initializing structs. This is\nnow enforced by [`go vet`](https://pkg.go.dev/cmd/vet).\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nk := User{\"John\", \"Doe\", true}\n```\n\n</td><td>\n\n```go\nk := User{\n    FirstName: \"John\",\n    LastName: \"Doe\",\n    Admin: true,\n}\n```\n\n</td></tr>\n</tbody></table>\n\nException: Field names *may* be omitted in test tables when there are 3 or\nfewer fields.\n\n```go\ntests := []struct{\n  op Operation\n  want string\n}{\n  {Add, \"add\"},\n  {Subtract, \"subtract\"},\n}\n```\n\n#### Omit Zero Value Fields in Structs\n\nWhen initializing structs with field names, omit fields that have zero values\nunless they provide meaningful context. Otherwise, let Go set these to zero\nvalues automatically.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nuser := User{\n  FirstName: \"John\",\n  LastName: \"Doe\",\n  MiddleName: \"\",\n  Admin: false,\n}\n```\n\n</td><td>\n\n```go\nuser := User{\n  FirstName: \"John\",\n  LastName: \"Doe\",\n}\n```\n\n</td></tr>\n</tbody></table>\n\nThis helps reduce noise for readers by omitting values that are default in\nthat context. Only meaningful values are specified.\n\nInclude zero values where field names provide meaningful context. For example,\ntest cases in [Test Tables](#test-tables) can benefit from names of fields\neven when they are zero-valued.\n\n```go\ntests := []struct{\n  give string\n  want int\n}{\n  {give: \"0\", want: 0},\n  // ...\n}\n```\n\n#### Use `var` for Zero Value Structs\n\nWhen all the fields of a struct are omitted in a declaration, use the `var`\nform to declare the struct.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nuser := User{}\n```\n\n</td><td>\n\n```go\nvar user User\n```\n\n</td></tr>\n</tbody></table>\n\nThis differentiates zero valued structs from those with non-zero fields\nsimilar to the distinction created for [map initialization](#initializing-maps), and matches how\nwe prefer to [declare empty slices](https://go.dev/wiki/CodeReviewComments#declaring-empty-slices).\n\n#### Initializing Struct References\n\nUse `&T{}` instead of `new(T)` when initializing struct references so that it\nis consistent with the struct initialization.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nsval := T{Name: \"foo\"}\n\n// inconsistent\nsptr := new(T)\nsptr.Name = \"bar\"\n```\n\n</td><td>\n\n```go\nsval := T{Name: \"foo\"}\n\nsptr := &T{Name: \"bar\"}\n```\n\n</td></tr>\n</tbody></table>\n\n### Initializing Maps\n\nPrefer `make(..)` for empty maps, and maps populated\nprogrammatically. This makes map initialization visually\ndistinct from declaration, and it makes it easy to add size\nhints later if available.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nvar (\n  // m1 is safe to read and write;\n  // m2 will panic on writes.\n  m1 = map[T1]T2{}\n  m2 map[T1]T2\n)\n```\n\n</td><td>\n\n```go\nvar (\n  // m1 is safe to read and write;\n  // m2 will panic on writes.\n  m1 = make(map[T1]T2)\n  m2 map[T1]T2\n)\n```\n\n</td></tr>\n<tr><td>\n\nDeclaration and initialization are visually similar.\n\n</td><td>\n\nDeclaration and initialization are visually distinct.\n\n</td></tr>\n</tbody></table>\n\nWhere possible, provide capacity hints when initializing\nmaps with `make()`. See\n[Specifying Map Capacity Hints](#specifying-map-capacity-hints)\nfor more information.\n\nOn the other hand, if the map holds a fixed list of elements,\nuse map literals to initialize the map.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nm := make(map[T1]T2, 3)\nm[k1] = v1\nm[k2] = v2\nm[k3] = v3\n```\n\n</td><td>\n\n```go\nm := map[T1]T2{\n  k1: v1,\n  k2: v2,\n  k3: v3,\n}\n```\n\n</td></tr>\n</tbody></table>\n\nThe basic rule of thumb is to use map literals when adding a fixed set of\nelements at initialization time, otherwise use `make` (and specify a size hint\nif available).\n\n### Format Strings outside Printf\n\nIf you declare format strings for `Printf`-style functions outside a string\nliteral, make them `const` values.\n\nThis helps `go vet` perform static analysis of the format string.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nmsg := \"unexpected values %v, %v\\n\"\nfmt.Printf(msg, 1, 2)\n```\n\n</td><td>\n\n```go\nconst msg = \"unexpected values %v, %v\\n\"\nfmt.Printf(msg, 1, 2)\n```\n\n</td></tr>\n</tbody></table>\n\n### Naming Printf-style Functions\n\nWhen you declare a `Printf`-style function, make sure that `go vet` can detect\nit and check the format string.\n\nThis means that you should use predefined `Printf`-style function\nnames if possible. `go vet` will check these by default. See [Printf family](https://pkg.go.dev/cmd/vet#hdr-Printf_family)\nfor more information.\n\nIf using the predefined names is not an option, end the name you choose with\nf: `Wrapf`, not `Wrap`. `go vet` can be asked to check specific `Printf`-style\nnames but they must end with f.\n\n```shell\ngo vet -printfuncs=wrapf,statusf\n```\n\nSee also [go vet: Printf family check](https://kuzminva.wordpress.com/2017/11/07/go-vet-printf-family-check/).\n\n## Patterns\n\n### Test Tables\n\nTable-driven tests with [subtests](https://go.dev/blog/subtests) can be a helpful pattern for writing tests\nto avoid duplicating code when the core test logic is repetitive.\n\nIf a system under test needs to be tested against *multiple conditions* where\ncertain parts of the inputs and outputs change, a table-driven test should\nbe used to reduce redundancy and improve readability.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// func TestSplitHostPort(t *testing.T)\n\nhost, port, err := net.SplitHostPort(\"192.0.2.0:8000\")\nrequire.NoError(t, err)\nassert.Equal(t, \"192.0.2.0\", host)\nassert.Equal(t, \"8000\", port)\n\nhost, port, err = net.SplitHostPort(\"192.0.2.0:http\")\nrequire.NoError(t, err)\nassert.Equal(t, \"192.0.2.0\", host)\nassert.Equal(t, \"http\", port)\n\nhost, port, err = net.SplitHostPort(\":8000\")\nrequire.NoError(t, err)\nassert.Equal(t, \"\", host)\nassert.Equal(t, \"8000\", port)\n\nhost, port, err = net.SplitHostPort(\"1:8\")\nrequire.NoError(t, err)\nassert.Equal(t, \"1\", host)\nassert.Equal(t, \"8\", port)\n```\n\n</td><td>\n\n```go\n// func TestSplitHostPort(t *testing.T)\n\ntests := []struct{\n  give     string\n  wantHost string\n  wantPort string\n}{\n  {\n    give:     \"192.0.2.0:8000\",\n    wantHost: \"192.0.2.0\",\n    wantPort: \"8000\",\n  },\n  {\n    give:     \"192.0.2.0:http\",\n    wantHost: \"192.0.2.0\",\n    wantPort: \"http\",\n  },\n  {\n    give:     \":8000\",\n    wantHost: \"\",\n    wantPort: \"8000\",\n  },\n  {\n    give:     \"1:8\",\n    wantHost: \"1\",\n    wantPort: \"8\",\n  },\n}\n\nfor _, tt := range tests {\n  t.Run(tt.give, func(t *testing.T) {\n    host, port, err := net.SplitHostPort(tt.give)\n    require.NoError(t, err)\n    assert.Equal(t, tt.wantHost, host)\n    assert.Equal(t, tt.wantPort, port)\n  })\n}\n```\n\n</td></tr>\n</tbody></table>\n\nTest tables make it easier to add context to error messages, reduce duplicate\nlogic, and add new test cases.\n\nWe follow the convention that the slice of structs is referred to as `tests`\nand each test case `tt`. Further, we encourage explicating the input and output\nvalues for each test case with `give` and `want` prefixes.\n\n```go\ntests := []struct{\n  give     string\n  wantHost string\n  wantPort string\n}{\n  // ...\n}\n\nfor _, tt := range tests {\n  // ...\n}\n```\n\n#### Avoid Unnecessary Complexity in Table Tests\n\nTable tests can be difficult to read and maintain if the subtests contain conditional\nassertions or other branching logic. Table tests should **NOT** be used whenever\nthere needs to be complex or conditional logic inside subtests (i.e. complex logic inside the `for` loop).\n\nLarge, complex table tests harm readability and maintainability because test readers may\nhave difficulty debugging test failures that occur.\n\nTable tests like this should be split into either multiple test tables or multiple\nindividual `Test...` functions.\n\nSome ideals to aim for are:\n\n* Focus on the narrowest unit of behavior\n* Minimize \"test depth\", and avoid conditional assertions (see below)\n* Ensure that all table fields are used in all tests\n* Ensure that all test logic runs for all table cases\n\nIn this context, \"test depth\" means \"within a given test, the number of\nsuccessive assertions that require previous assertions to hold\" (similar\nto cyclomatic complexity).\nHaving \"shallower\" tests means that there are fewer relationships between\nassertions and, more importantly, that those assertions are less likely\nto be conditional by default.\n\nConcretely, table tests can become confusing and difficult to read if they use multiple branching\npathways (e.g. `shouldError`, `expectCall`, etc.), use many `if` statements for\nspecific mock expectations (e.g. `shouldCallFoo`), or place functions inside the\ntable (e.g. `setupMocks func(*FooMock)`).\n\nHowever, when testing behavior that only\nchanges based on changed input, it may be preferable to group similar cases\ntogether in a table test to better illustrate how behavior changes across all inputs,\nrather than splitting otherwise comparable units into separate tests\nand making them harder to compare and contrast.\n\nIf the test body is short and straightforward,\nit's acceptable to have a single branching pathway for success versus failure cases\nwith a table field like `shouldErr` to specify error expectations.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\nfunc TestComplicatedTable(t *testing.T) {\n  tests := []struct {\n    give          string\n    want          string\n    wantErr       error\n    shouldCallX   bool\n    shouldCallY   bool\n    giveXResponse string\n    giveXErr      error\n    giveYResponse string\n    giveYErr      error\n  }{\n    // ...\n  }\n\n  for _, tt := range tests {\n    t.Run(tt.give, func(t *testing.T) {\n      // setup mocks\n      ctrl := gomock.NewController(t)\n      xMock := xmock.NewMockX(ctrl)\n      if tt.shouldCallX {\n        xMock.EXPECT().Call().Return(\n          tt.giveXResponse, tt.giveXErr,\n        )\n      }\n      yMock := ymock.NewMockY(ctrl)\n      if tt.shouldCallY {\n        yMock.EXPECT().Call().Return(\n          tt.giveYResponse, tt.giveYErr,\n        )\n      }\n\n      got, err := DoComplexThing(tt.give, xMock, yMock)\n\n      // verify results\n      if tt.wantErr != nil {\n        require.EqualError(t, err, tt.wantErr)\n        return\n      }\n      require.NoError(t, err)\n      assert.Equal(t, want, got)\n    })\n  }\n}\n```\n\n</td><td>\n\n```go\nfunc TestShouldCallX(t *testing.T) {\n  // setup mocks\n  ctrl := gomock.NewController(t)\n  xMock := xmock.NewMockX(ctrl)\n  xMock.EXPECT().Call().Return(\"XResponse\", nil)\n\n  yMock := ymock.NewMockY(ctrl)\n\n  got, err := DoComplexThing(\"inputX\", xMock, yMock)\n\n  require.NoError(t, err)\n  assert.Equal(t, \"want\", got)\n}\n\nfunc TestShouldCallYAndFail(t *testing.T) {\n  // setup mocks\n  ctrl := gomock.NewController(t)\n  xMock := xmock.NewMockX(ctrl)\n\n  yMock := ymock.NewMockY(ctrl)\n  yMock.EXPECT().Call().Return(\"YResponse\", nil)\n\n  _, err := DoComplexThing(\"inputY\", xMock, yMock)\n  assert.EqualError(t, err, \"Y failed\")\n}\n```\n</td></tr>\n</tbody></table>\n\nThis complexity makes it more difficult to change, understand, and prove the\ncorrectness of the test.\n\nWhile there are no strict guidelines, readability and maintainability should\nalways be top-of-mind when deciding between Table Tests versus separate tests\nfor multiple inputs/outputs to a system.\n\n#### Parallel Tests\n\nParallel tests, like some specialized loops (for example, those that spawn\ngoroutines or capture references as part of the loop body),\nmust take care to explicitly assign loop variables within the loop's scope to\nensure that they hold the expected values.\n\n```go\ntests := []struct{\n  give string\n  // ...\n}{\n  // ...\n}\n\nfor _, tt := range tests {\n  t.Run(tt.give, func(t *testing.T) {\n    t.Parallel()\n    // ...\n  })\n}\n```\n\nIn the example above, we must declare a `tt` variable scoped to the loop\niteration because of the use of `t.Parallel()` below.\nIf we do not do that, most or all tests will receive an unexpected value for\n`tt`, or a value that changes as they're running.\n\n<!-- TODO: Explain how to use _test packages. -->\n\n### Functional Options\n\nFunctional options is a pattern in which you declare an opaque `Option` type\nthat records information in some internal struct. You accept a variadic number\nof these options and act upon the full information recorded by the options on\nthe internal struct.\n\nUse this pattern for optional arguments in constructors and other public APIs\nthat you foresee needing to expand, especially if you already have three or\nmore arguments on those functions.\n\n<table>\n<thead><tr><th>Bad</th><th>Good</th></tr></thead>\n<tbody>\n<tr><td>\n\n```go\n// package db\n\nfunc Open(\n  addr string,\n  cache bool,\n  logger *zap.Logger\n) (*Connection, error) {\n  // ...\n}\n```\n\n</td><td>\n\n```go\n// package db\n\ntype Option interface {\n  // ...\n}\n\nfunc WithCache(c bool) Option {\n  // ...\n}\n\nfunc WithLogger(log *zap.Logger) Option {\n  // ...\n}\n\n// Open creates a connection.\nfunc Open(\n  addr string,\n  opts ...Option,\n) (*Connection, error) {\n  // ...\n}\n```\n\n</td></tr>\n<tr><td>\n\nThe cache and logger parameters must always be provided, even if the user\nwants to use the default.\n\n```go\ndb.Open(addr, db.DefaultCache, zap.NewNop())\ndb.Open(addr, db.DefaultCache, log)\ndb.Open(addr, false /* cache */, zap.NewNop())\ndb.Open(addr, false /* cache */, log)\n```\n\n</td><td>\n\nOptions are provided only if needed.\n\n```go\ndb.Open(addr)\ndb.Open(addr, db.WithLogger(log))\ndb.Open(addr, db.WithCache(false))\ndb.Open(\n  addr,\n  db.WithCache(false),\n  db.WithLogger(log),\n)\n```\n\n</td></tr>\n</tbody></table>\n\nOur suggested way of implementing this pattern is with an `Option` interface\nthat holds an unexported method, recording options on an unexported `options`\nstruct.\n\n```go\ntype options struct {\n  cache  bool\n  logger *zap.Logger\n}\n\ntype Option interface {\n  apply(*options)\n}\n\ntype cacheOption bool\n\nfunc (c cacheOption) apply(opts *options) {\n  opts.cache = bool(c)\n}\n\nfunc WithCache(c bool) Option {\n  return cacheOption(c)\n}\n\ntype loggerOption struct {\n  Log *zap.Logger\n}\n\nfunc (l loggerOption) apply(opts *options) {\n  opts.logger = l.Log\n}\n\nfunc WithLogger(log *zap.Logger) Option {\n  return loggerOption{Log: log}\n}\n\n// Open creates a connection.\nfunc Open(\n  addr string,\n  opts ...Option,\n) (*Connection, error) {\n  options := options{\n    cache:  defaultCache,\n    logger: zap.NewNop(),\n  }\n\n  for _, o := range opts {\n    o.apply(&options)\n  }\n\n  // ...\n}\n```\n\nNote that there's a method of implementing this pattern with closures but we\nbelieve that the pattern above provides more flexibility for authors and is\neasier to debug and test for users. In particular, it allows options to be\ncompared against each other in tests and mocks, versus closures where this is\nimpossible. Further, it lets options implement other interfaces, including\n`fmt.Stringer` which allows for user-readable string representations of the\noptions.\n\nSee also,\n\n- [Self-referential functions and the design of options](https://commandcenter.blogspot.com/2014/01/self-referential-functions-and-design.html)\n- [Functional options for friendly APIs](https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis)\n\n<!-- TODO: replace this with parameter structs and functional options, when to\nuse one vs other -->\n\n## Linting\n\nMore importantly than any \"blessed\" set of linters, lint consistently across a\ncodebase.\n\nWe recommend using the following linters at a minimum, because we feel that they\nhelp to catch the most common issues and also establish a high bar for code\nquality without being unnecessarily prescriptive:\n\n- [errcheck](https://github.com/kisielk/errcheck) to ensure that errors are handled\n- [goimports](https://pkg.go.dev/golang.org/x/tools/cmd/goimports) to format code and manage imports\n- [revive](https://github.com/mgechev/revive) to point out common style mistakes\n- [govet](https://pkg.go.dev/cmd/vet) to analyze code for common mistakes\n- [staticcheck](https://staticcheck.dev) to do various static analysis checks\n\n  > **Note**: [revive](https://github.com/mgechev/revive) is the modern, faster successor to the now-deprecated [golint](https://github.com/golang/lint).\n\n### Lint Runners\n\nWe recommend [golangci-lint](https://github.com/golangci/golangci-lint) as the go-to lint runner for Go code, largely due\nto its performance in larger codebases and ability to configure and use many\ncanonical linters at once. This repo has an example [.golangci.yml](https://github.com/uber-go/guide/blob/master/.golangci.yml) config file\nwith recommended linters and settings.\n\ngolangci-lint has [various linters](https://golangci-lint.run/usage/linters/) available for use. The above linters are\nrecommended as a base set, and we encourage teams to add any additional linters\nthat make sense for their projects.\n"
  }
]