[
  {
    "path": ".gitattributes",
    "content": "*.html linguist-detectable=false\n*.js linguist-detectable=false\n*.css linguist-detectable=false\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: teivah\npatreon: # Replace with a single Patreon username\nopen_collective: # Replace with a single Open Collective username\nko_fi: # Replace with a single Ko-fi username\ntidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\ncommunity_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry\nliberapay: # Replace with a single Liberapay username\nissuehunt: # Replace with a single IssueHunt username\notechie: # Replace with a single Otechie username\nlfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry\ncustom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/community_mistake.md",
    "content": "---\nname: Community mistake\nabout: Propose a new community mistake\ntitle: ''\nlabels: community mistake\n---\n\n**Describe the mistake**\n\nDescribe the mistake and the context.\n\n**Solution**\n\nOne or multiple solutions to avoid the mistake.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/erratum.md",
    "content": "---\nname: Erratum\nabout: Suggest a book correction\ntitle: ''\nlabels: erratum\n---\n\n**Describe the book error**\n\nDescribe a factual error in the book and suggest a correction. \n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: ci \non:\n  push:\n    branches:\n      - master \n      - main\npermissions:\n  contents: write\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-python@v4\n        with:\n          python-version: 3.x\n      - run: echo \"cache_id=$(date --utc '+%V')\" >> $GITHUB_ENV \n      - uses: actions/cache@v3\n        with:\n          key: mkdocs-material-${{ env.cache_id }}\n          path: .cache\n          restore-keys: |\n            mkdocs-material-\n      - run: pip install mkdocs-material\n      - run: pip install pillow cairosvg\n      - run: pip install mkdocs-glightbox\n      - run: mkdocs gh-deploy --force\n"
  },
  {
    "path": ".gitignore",
    "content": ".idea\n*.out\n100-go-mistakes.iml"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to 100 Go Mistakes\n\nFirst of all, thank you for taking the time to contribute! 🎉\n\nWe aim to create a collaborative space that could become the canonical place to find common mistakes to avoid in Go.\n\nIf you want to participate, please look at the open issues. The 100 Go Mistakes repository is a documentation project, so all the content that can be enriched is in the \n[/docs](https://github.com/teivah/100-go-mistakes/tree/master/docs) folder. The main file is [index.md](https://github.com/teivah/100-go-mistakes/blob/master/docs/index.md), \nthe one containing the main content of [100go.co](https://100go.co/).\n\nIf you submit a PR, please do not care about the HTML generation (the website uses MkDocs), I'll take care of it. Said differently, most PRs should\nonly contain modifications to .md files.\n"
  },
  {
    "path": "LICENSE.md",
    "content": "# Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International\n\nCreative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.\n\n### Using Creative Commons Public Licenses\n\nCreative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.\n\n* __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors).\n\n* __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees).\n\n## Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License\n\nBy exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License (\"Public License\"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.\n\n### Section 1 – Definitions.\n\na. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.\n\nb. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.\n\ne. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.\n\nf. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.\n\nh. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License.\n\ni. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.\n\nh. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License.\n\ni. __NonCommercial__ means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange.\n\nj. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.\n\nk. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.\n\nl. __You__ means the individual or entity exercising the Licensed Rights under this Public License. __Your__ has a corresponding meaning.\n\n### Section 2 – Scope.\n\na. ___License grant.___\n\n1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:\n\n   A. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial purposes only; and\n\n   B. produce and reproduce, but not Share, Adapted Material for NonCommercial purposes only.\n\n2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.\n\n3. __Term.__ The term of this Public License is specified in Section 6(a).\n\n4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.\n\n5. __Downstream recipients.__\n\n   A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.\n\n   B. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.\n\n6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).\n\nb. ___Other rights.___\n\n1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.\n\n2. Patent and trademark rights are not licensed under this Public License.\n\n3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties, including when the Licensed Material is used other than for NonCommercial purposes.\n\n### Section 3 – License Conditions.\n\nYour exercise of the Licensed Rights is expressly made subject to the following conditions.\n\na. ___Attribution.___\n\n1. If You Share the Licensed Material, You must:\n\n   A. retain the following if it is supplied by the Licensor with the Licensed Material:\n\n   i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);\n\n   ii. a copyright notice;\n\n   iii. a notice that refers to this Public License;\n\n   iv. a notice that refers to the disclaimer of warranties;\n\n   v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;\n\n   B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and\n\n   C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.\n\n   For the avoidance of doubt, You do not have permission under this Public License to Share Adapted Material.\n\n2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.\n\n3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.\n\n### Section 4 – Sui Generis Database Rights.\n\nWhere the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:\n\na. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database for NonCommercial purposes only and provided You do not Share Adapted Material;\n\nb. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and\n\nc. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.\n\nFor the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.\n\n### Section 5 – Disclaimer of Warranties and Limitation of Liability.\n\na. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__\n\nb. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__\n\nc. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.\n\n### Section 6 – Term and Termination.\n\na. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.\n\nb. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:\n\n1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or\n\n2. upon express reinstatement by the Licensor.\n\nFor the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.\n\nc. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.\n\nd. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.\n\n### Section 7 – Other Terms and Conditions.\n\na. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.\n\nb. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.\n\n### Section 8 – Interpretation.\n\na. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.\n\nb. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.\n\nc. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.\n\nd. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.\n\n> Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.\n>\n> Creative Commons may be contacted at [creativecommons.org](http://creativecommons.org).\n"
  },
  {
    "path": "README.md",
    "content": "# 100 Go Mistakes and How to Avoid Them\n\nSource code and community space of 📖 _100 Go Mistakes and How to Avoid Them_, published by Manning in August 2022.\n\nRead online: [100go.co](https://100go.co).\n\n## Powered by\n\n[![JetBrains logo.](https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.svg)](https://jb.gg/OpenSource)"
  },
  {
    "path": "docs/20-slice.md",
    "content": "---\ntitle: Not understanding slice length and capacity (#20)\ncomments: true\nhide:\n- toc\n---\n\n# Not understanding slice length and capacity\n\n![](img/20-slice.png)\n\nIt’s pretty common for Go developers to mix slice length and capacity or not understand them thoroughly. Assimilating these two concepts is essential for efficiently handling core operations such as slice initialization and adding elements with append, copying, or slicing. This misunderstanding can lead to using slices suboptimally or even to memory leaks.\n\nIn Go, a slice is backed by an array. That means the slice’s data is stored contiguously in an array data structure. A slice also handles the logic of adding an element if the backing array is full or shrinking the backing array if it’s almost empty.\n\nInternally, a slice holds a pointer to the backing array plus a length and a capacity. The length is the number of elements the slice contains, whereas the capacity is the number of elements in the backing array, counting from the first element in the slice. Let’s go through a few examples to make things clearer. First, let’s initialize a slice with a given length and capacity:\n\n```go\ns := make([]int, 3, 6) // Three-length, six-capacity slice\n```\n\nThe first argument, representing the length, is mandatory. However, the second argument representing the capacity is optional. Figure 1 shows the result of this code in memory.\n\n<figure markdown>\n  ![](img/slice-1.png)\n  <figcaption>Figure 1: A three-length, six-capacity slice.</figcaption>\n</figure>\n\nIn this case, `make` creates an array of six elements (the capacity). But because the length was set to 3, Go initializes only the first three elements. Also, because the slice is an `[]int` type, the first three elements are initialized to the zeroed value of an `int`: 0. The grayed elements are allocated but not yet used.\n\nIf we print this slice, we get the elements within the range of the length, `[0 0 0]`. If we set `s[1]` to 1, the second element of the slice updates without impacting its length or capacity. Figure 2 illustrates this.\n\n<figure markdown>\n  ![](img/slice-2.png)\n  <figcaption>Figure 2: Updating the slice’s second element: s[1] = 1.</figcaption>\n</figure>\n\nHowever, accessing an element outside the length range is forbidden, even though it’s already allocated in memory. For example, `s[4]` = 0 would lead to the following panic:\n\n```\npanic: runtime error: index out of range [4] with length 3\n```\n\nHow can we use the remaining space of the slice? By using the `append` built-in function:\n\n```go\ns = append(s, 2)\n```\n\nThis code appends to the existing `s` slice a new element. It uses the first grayed element (which was allocated but not yet used) to store element 2, as figure 3 shows.\n\n<figure markdown>\n  ![](img/slice-3.png)\n  <figcaption>Figure 3: Appending an element to s.</figcaption>\n</figure>\n\nThe length of the slice is updated from 3 to 4 because the slice now contains four elements. Now, what happens if we add three more elements so that the backing array isn’t large enough?\n\n```go\ns = append(s, 3, 4, 5)\nfmt.Println(s)\n```\n\nIf we run this code, we see that the slice was able to cope with our request:\n\n```\n[0 1 0 2 3 4 5]\n```\n\nBecause an array is a fixed-size structure, it can store the new elements until element 4. When we want to insert element 5, the array is already full: Go internally creates another array by doubling the capacity, copying all the elements, and then inserting element 5. Figure 4 shows this process.\n\n<figure markdown>\n  ![](img/slice-4.png)\n  <figcaption>Figure 4: Because the initial backing array is full, Go creates another array and copies all the elements.</figcaption>\n</figure>\n\nThe slice now references the new backing array. What will happen to the previous backing array? If it’s no longer referenced, it’s eventually freed by the garbage collector (GC) if allocated on the heap. (We discuss heap memory in mistake #95, “[Not understanding stack vs. heap](https://100go.co#not-understanding-stack-vs-heap-95),” and we look at how the GC works in mistake #99, “[Not understanding how the GC works](https://100go.co#not-understanding-how-the-gc-works-99).”)\n\nWhat happens with slicing? Slicing is an operation done on an array or a slice, providing a half-open range; the first index is included, whereas the second is excluded. The following example shows the impact, and figure 5 displays the result in memory:\n\n```go\ns1 := make([]int, 3, 6) // Three-length, six-capacity slice\ns2 := s1[1:3] // Slicing from indices 1 to 3\n```\n\n<figure markdown>\n  ![](img/slice-5.png)\n  <figcaption>Figure 5: The slices s1 and s2 reference the same backing array with different lengths and capacities.</figcaption>\n</figure>\n\nFirst, `s1` is created as a three-length, six-capacity slice. When `s2` is created by slicing `s1`, both slices reference the same backing array. However, `s2` starts from a different index, 1. Therefore, its length and capacity (a two-length, five-capacity slice) differ from s1. If we update `s1[1]` or `s2[0]`, the change is made to the same array, hence, visible in both slices, as figure 6 shows.\n\n<figure markdown>\n  ![](img/slice-6.png)\n  <figcaption>Figure 6: Because s1 and s2 are backed by the same array, updating a common element makes the change visible in both slices.</figcaption>\n</figure>\n\nNow, what happens if we append an element to `s2`? Does the following code change `s1` as well?\n\n```go\ns2 = append(s2, 2)\n```\n\nThe shared backing array is modified, but only the length of `s2` changes. Figure 7 shows the result of appending an element to `s2`.\n\n<figure markdown>\n  ![](img/slice-7.png)\n  <figcaption>Figure 7: Appending an element to s2.</figcaption>\n</figure>\n\n`s1` remains a three-length, six-capacity slice. Therefore, if we print `s1` and `s2`, the added element is only visible for `s2`:\n\n```go\ns1=[0 1 0], s2=[1 0 2]\n```\n\nIt’s important to understand this behavior so that we don’t make wrong assumptions while using append.\n\n???+ note\n\n    In these examples, the backing array is internal and not available directly to the Go developer. The only exception is when a slice is created from slicing an existing array.\n\nOne last thing to note: what if we keep appending elements to `s2` until the backing array is full? What will the state be, memory-wise? Let’s add three more elements so that the backing array will not have enough capacity:\n\n```go\ns2 = append(s2, 3)\ns2 = append(s2, 4) // At this stage, the backing is already full\ns2 = append(s2, 5)\n```\n\nThis code leads to creating another backing array. Figure 8 displays the results in memory.\n\n<figure markdown>\n  ![](img/slice-8.png)\n  <figcaption>Figure 8: Appending elements to s2 until the backing array is full.</figcaption>\n</figure>\n\n`s1` and `s2` now reference two different arrays. As `s1` is still a three-length, six-capacity slice, it still has some available buffer, so it keeps referencing the initial array. Also, the new backing array was made by copying the initial one from the first index of `s2`. That’s why the new array starts with element 1, not 0.\n\nTo summarize, the slice length is the number of available elements in the slice, whereas the slice capacity is the number of elements in the backing array. Adding an element to a full slice (length == capacity) leads to creating a new backing array with a new capacity, copying all the elements from the previous array, and updating the slice pointer to the new array.\n"
  },
  {
    "path": "docs/28-maps-memory-leaks.md",
    "content": "---\ntitle: Maps and memory leaks (#28)\ncomments: true\nhide:\n- toc\n---\n\n# Maps and memory leaks\n\n![](img/28-maps-memory-leaks.png)\n\nWhen working with maps in Go, we need to understand some important characteristics of how a map grows and shrinks. Let’s delve into this to prevent issues that can cause memory leaks.\n\nFirst, to view a concrete example of this problem, let’s design a scenario where we will work with the following map:\n\n```go\nm := make(map[int][128]byte)\n```\n\nEach value of m is an array of 128 bytes. We will do the following:\n\n1. Allocate an empty map.\n2. Add 1 million elements.\n3. Remove all the elements, and run a Garbage Collection (GC).\n\nAfter each step, we want to print the size of the heap (using a `printAlloc` utility function). This shows us how this example behaves memory-wise:\n\n```go\nfunc main() {\n\tn := 1_000_000\n\tm := make(map[int][128]byte)\n\tprintAlloc()\n\n\tfor i := 0; i < n; i++ { // Adds 1 million elements\n\t\tm[i] = [128]byte{}\n\t}\n\tprintAlloc()\n\n\tfor i := 0; i < n; i++ { // Deletes 1 million elements\n\t\tdelete(m, i)\n\t}\n\n\truntime.GC() // Triggers a manual GC\n\tprintAlloc()\n\truntime.KeepAlive(m) // Keeps a reference to m so that the map isn’t collected\n}\n\nfunc printAlloc() {\n\tvar m runtime.MemStats\n\truntime.ReadMemStats(&m)\n\tfmt.Printf(\"%d MB\\n\", m.Alloc/(1024*1024))\n}\n```\n\nWe allocate an empty map, add 1 million elements, remove 1 million elements, and then run a GC. We also make sure to keep a reference to the map using [`runtime.KeepAlive`](https://pkg.go.dev/runtime#KeepAlive) so that the map isn’t collected as well. Let’s run this example:\n\n```\n0 MB   <-- After m is allocated\n461 MB <-- After we add 1 million elements\n293 MB <-- After we remove 1 million elements\n```\n\nWhat can we observe? At first, the heap size is minimal. Then it grows significantly after having added 1 million elements to the map. But if we expected the heap size to decrease after removing all the elements, this isn’t how maps work in Go. In the end, even though the GC has collected all the elements, the heap size is still 293 MB. So the memory shrunk, but not as we might have expected. What’s the rationale? We need to delve into how a map works in Go.\n\nA map provides an unordered collection of key-value pairs in which all the keys are distinct. In Go, a map is based on the hash table data structure: an array where each element is a pointer to a bucket of key-value pairs, as shown in figure 1.\n\n<figure markdown>\n  ![](img/map-leak-1.png)\n  <figcaption>Figure 1: A hash table example with a focus on bucket 0.</figcaption>\n</figure>\n\nEach bucket is a fixed-size array of eight elements. In the case of an insertion into a bucket that is already full (a bucket overflow), Go creates another bucket of eight elements and links the previous one to it. Figure 2 shows an example:\n\n<figure markdown>\n  ![](img/map-leak-2.png)\n  <figcaption>Figure 2: In case of a bucket overflow, Go allocates a new bucket and links the previous bucket to it.</figcaption>\n</figure>\n\n\nUnder the hood, a Go map is a pointer to a [runtime.hmap](https://github.com/golang/go/blob/0262ea1ff9ac3b9fd268a48fcaaa6811c20cbea2/src/runtime/map.go#L117-L131) struct. This struct contains multiple fields, including a B field, giving the number of buckets in the map:\n\n```go\ntype hmap struct {\n    B uint8 // log_2 of # of buckets\n            // (can hold up to loadFactor * 2^B items)\n    // ...\n}\n```\n\nAfter adding 1 million elements, the value of B equals 18, which means 2¹⁸ = 262,144 buckets. When we remove 1 million elements, what’s the value of B? Still 18. Hence, the map still contains the same number of buckets.\n\nThe reason is that the number of buckets in a map cannot shrink. Therefore, removing elements from a map doesn’t impact the number of existing buckets; it just zeroes the slots in the buckets. A map can only grow and have more buckets; it never shrinks.\n\nIn the previous example, we went from 461 MB to 293 MB because the elements were collected, but running the GC didn’t impact the map itself. Even the number of extra buckets (the buckets created because of overflows) remains the same.\n\nLet’s take a step back and discuss when the fact that a map cannot shrink can be a problem. Imagine building a cache using a `map[int][128]byte`. This map holds per customer ID (the `int`), a sequence of 128 bytes. Now, suppose we want to save the last 1,000 customers. The map size will remain constant, so we shouldn’t worry about the fact that a map cannot shrink.\n\nHowever, let’s say we want to store one hour of data. Meanwhile, our company has decided to have a big promotion for Black Friday: in one hour, we may have millions of customers connected to our system. But a few days after Black Friday, our map will contain the same number of buckets as during the peak time. This explains why we can experience high memory consumption that doesn’t significantly decrease in such a scenario.\n\nWhat are the solutions if we don’t want to manually restart our service to clean the amount of memory consumed by the map? One solution could be to re-create a copy of the current map at a regular pace. For example, every hour, we can build a new map, copy all the elements, and release the previous one. The main drawback of this option is that following the copy and until the next garbage collection, we may consume twice the current memory for a short period.\n\nAnother solution would be to change the map type to store an array pointer: `map[int]*[128]byte`. It doesn’t solve the fact that we will have a significant number of buckets; however, each bucket entry will reserve the size of a pointer for the value instead of 128 bytes (8 bytes on 64-bit systems and 4 bytes on 32-bit systems).\n\nComing back to the original scenario, let’s compare the memory consumption for each map type following each step. The following table shows the comparison.\n\n| Step  | `map[int][128]byte`  | `map[int]*[128]byte`  |\n|---|---|---|\n|  Allocate an empty map | 0 MB  | 0 MB  |\n|  Add 1 million elements | 461 MB  |  182 MB |\n| Remove all the elements and run a GC  |  293 MB | 38 MB  |\n\n???+ note\n\n    If a key or a value is over 128 bytes, Go won’t store it directly in the map bucket. Instead, Go stores a pointer to reference the key or the value.\n\nAs we have seen, adding n elements to a map and then deleting all the elements means keeping the same number of buckets in memory. So, we must remember that because a Go map can only grow in size, so does its memory consumption. There is no automated strategy to shrink it. If this leads to high memory consumption, we can try different options such as forcing Go to re-create the map or using pointers to check if it can be optimized.\n"
  },
  {
    "path": "docs/5-interface-pollution.md",
    "content": "---\ntitle: Interface pollution (#5)\ncomments: true\nhide:\n- toc\nstatus: new\n---\n\n# Interface pollution\n\n![](img/interface-pollution.jpeg)\n\nInterfaces are one of the cornerstones of the Go language when designing and structuring our code. However, like many tools or concepts, abusing them is generally not a good idea. Interface pollution is about overwhelming our code with unnecessary abstractions, making it harder to understand. It’s a common mistake made by developers coming from another language with different habits. Before delving into the topic, let’s refresh our minds about Go’s interfaces. Then, we will see when it’s appropriate to use interfaces and when it may be considered pollution.\n\n## Concepts\n\nAn interface provides a way to specify the behavior of an object. We use interfaces to create common abstractions that multiple objects can implement. What makes Go interfaces so different is that they are satisfied implicitly. There is no explicit keyword like `implements` to mark that an object X implements interface Y.\n\nTo understand what makes interfaces so powerful, we will dig into two popular ones from the standard library: `io.Reader` and `io.Writer`. The `io` package provides abstractions for I/O primitives. Among these abstractions, `io.Reader` relates to reading data from a data source and `io.Writer` to writing data to a target, as represented in the next figure:\n\n<figure markdown>\n  ![](img/ioreaderwriter.svg)\n</figure>\n\nThe `io.Reader` contains a single Read method:\n\n```go\ntype Reader interface {\n    Read(p []byte) (n int, err error)\n}\n```\n\nCustom implementations of the `io.Reader` interface should accept a slice of bytes, filling it with its data and returning either the number of bytes read or an error.\n\nOn the other hand, `io.Writer` defines a single method, Write:\n\n```go\ntype Writer interface {\n    Write(p []byte) (n int, err error)\n}\n```\n\nCustom implementations of `io.Writer` should write the data coming from a slice to a target and return either the number of bytes written or an error. Therefore, both interfaces provide fundamental abstractions:\n\n* `io.Reader` reads data from a source\n* `io.Writer` writes data to a target\n\nWhat is the rationale for having these two interfaces in the language? What is the point of creating these abstractions?\n\nLet’s assume we need to implement a function that should copy the content of one file to another. We could create a specific function that would take as input two `*os.File`. Or, we can choose to create a more generic function using `io.Reader` and `io.Writer` abstractions:\n\n```go\nfunc copySourceToDest(source io.Reader, dest io.Writer) error {\n    // ...\n}\n```\n\nThis function would work with `*os.File` parameters (as `*os.File` implements both `io.Reader` and `io.Writer`) and any other type that would implement these interfaces. For example, we could create our own `io.Writer` that writes to a database, and the code would remain the same. It increases the genericity of the function; hence, its reusability.\n\nFurthermore, writing a unit test for this function is easier because, instead of having to handle files, we can use the `strings` and `bytes` packages that provide helpful implementations:\n\n```go\nfunc TestCopySourceToDest(t *testing.T) {\n    const input = \"foo\"\n    source := strings.NewReader(input) // Creates an io.Reader\n    dest := bytes.NewBuffer(make([]byte, 0)) // Creates an io.Writer\n\n    err := copySourceToDest(source, dest) // Calls copySourceToDest from a *strings.Reader and a *bytes.Buffer\n    if err != nil {\n        t.FailNow()\n    }\n\n    got := dest.String()\n    if got != input {\n        t.Errorf(\"expected: %s, got: %s\", input, got)\n    }\n}\n```\n\nIn the example, source is a `*strings.Reader`, whereas dest is a `*bytes.Buffer`. Here, we test the behavior of `copySourceToDest` without creating any files.\n\nWhile designing interfaces, the granularity (how many methods the interface contains) is also something to keep in mind. A [known proverb](https://www.youtube.com/watch?v=PAAkCSZUG1c&t=318s) in Go relates to how big an interface should be:\n\n!!! quote \"Rob Pike\"\n\n    The bigger the interface, the weaker the abstraction.\n\nIndeed, adding methods to an interface can decrease its level of reusability. `io.Reader` and `io.Writer` are powerful abstractions because they cannot get any simpler. Furthermore, we can also combine fine-grained interfaces to create higher-level abstractions. This is the case with `io.ReadWriter`, which combines the reader and writer behaviors:\n\n```go\ntype ReadWriter interface {\n    Reader\n    Writer\n}\n```\n\n???+ note\n\n    As Einstein said, “_Everything should be made as simple as possible, but no simpler._” Applied to interfaces, this denotes that finding the perfect granularity for an interface isn’t necessarily a straightforward process.\n\nLet’s now discuss common cases where interfaces are recommended.\n\n## When to use interfaces\n\nWhen should we create interfaces in Go? Let’s look at three concrete use cases where interfaces are usually considered to bring value. Note that the goal isn’t to be exhaustive because the more cases we add, the more they would depend on the context. However, these three cases should give us a general idea:\n\n* Common behavior \n* Decoupling\n* Restricting behavior\n\n### Common behavior\n\nThe first option we will discuss is to use interfaces when multiple types implement a common behavior. In such a case, we can factor out the behavior inside an interface. If we look at the standard library, we can find many examples of such a use case. For example, sorting a collection can be factored out via three methods:\n\n* Retrieving the number of elements in the collection\n* Reporting whether one element must be sorted before another \n* Swapping two elements\n\nHence, the following interface was added to the `sort` package:\n\n```go\ntype Interface interface {\n    Len() int // Number of elements\n    Less(i, j int) bool // Checks two elements\n    Swap(i, j int) // Swaps two elements\n}\n```\n\nThis interface has a strong potential for reusability because it encompasses the common behavior to sort any collection that is index-based.\n\nThroughout the `sort` package, we can find dozens of implementations. If at some point we compute a collection of integers, for example, and we want to sort it, are we necessarily interested in the implementation type? Is it important whether the sorting algorithm is a merge sort or a quicksort? In many cases, we don’t care. Hence, the sorting behavior can be abstracted, and we can depend on the `sort.Interface`.\n\nFinding the right abstraction to factor out a behavior can also bring many benefits. For example, the `sort` package provides utility functions that also rely on `sort.Interface`, such as checking whether a collection is already sorted. For instance:\n\n```go\nfunc IsSorted(data Interface) bool {\n    n := data.Len()\n    for i := n - 1; i > 0; i-- {\n        if data.Less(i, i-1) {\n            return false\n        }\n    }\n    return true\n}\n```\n\nBecause `sort.Interface` is the right level of abstraction, it makes it highly valuable.\n\nLet’s now see another main use case when using interfaces.\n\n### Decoupling\n\nAnother important use case is about decoupling our code from an implementation. If we rely on an abstraction instead of a concrete implementation, the implementation itself can be replaced with another without even having to change our code. This is the Liskov Substitution Principle (the L in Robert C. Martin’s [SOLID](https://en.wikipedia.org/wiki/SOLID) design principles).\n\nOne benefit of decoupling can be related to unit testing. Let’s assume we want to implement a `CreateNewCustomer` method that creates a new customer and stores it. We decide to rely on the concrete implementation directly (let’s say a `mysql.Store` struct):\n\n```go\ntype CustomerService struct {\n    store mysql.Store // Depends on the concrete implementation\n}\n\nfunc (cs CustomerService) CreateNewCustomer(id string) error {\n    customer := Customer{id: id}\n    return cs.store.StoreCustomer(customer)\n}\n```\n\nNow, what if we want to test this method? Because `customerService` relies on the actual implementation to store a `Customer`, we are obliged to test it through integration tests, which requires spinning up a MySQL instance (unless we use an alternative technique such as [`go-sqlmock`](https://github.com/DATA-DOG/go-sqlmock), but this isn’t the scope of this section). Although integration tests are helpful, that’s not always what we want to do. To give us more flexibility, we should decouple `CustomerService` from the actual implementation, which can be done via an interface like so:\n\n```go\ntype customerStorer interface { // Creates a storage abstraction\n    StoreCustomer(Customer) error\n}\n\ntype CustomerService struct {\n    storer customerStorer // Decouples CustomerService from the actual implementation\n}\n\nfunc (cs CustomerService) CreateNewCustomer(id string) error {\n    customer := Customer{id: id}\n    return cs.storer.StoreCustomer(customer)\n}\n```\n\nBecause storing a customer is now done via an interface, this gives us more flexibility in how we want to test the method. For instance, we can:\n\n* Use the concrete implementation via integration tests \n* Use a mock (or any kind of test double) via unit tests \n* Or both\n\nLet’s now discuss another use case: to restrict a behavior.\n\n### Restricting behavior\n\nThe last use case we will discuss can be pretty counterintuitive at first sight. It’s about restricting a type to a specific behavior. Let’s imagine we implement a custom configuration package to deal with dynamic configuration. We create a specific container for `int` configurations via an `IntConfig` struct that also exposes two methods: `Get` and `Set`. Here’s how that code would look:\n\n```go\ntype IntConfig struct {\n    // ...\n}\n\nfunc (c *IntConfig) Get() int {\n    // Retrieve configuration\n}\n\nfunc (c *IntConfig) Set(value int) {\n    // Update configuration\n}\n```\n\nNow, suppose we receive an `IntConfig` that holds some specific configuration, such as a threshold. Yet, in our code, we are only interested in retrieving the configuration value, and we want to prevent updating it. How can we enforce that, semantically, this configuration is read-only, if we don’t want to change our configuration package? By creating an abstraction that restricts the behavior to retrieving only a config value:\n\n```go\ntype intConfigGetter interface {\n    Get() int\n}\n```\n\nThen, in our code, we can rely on `intConfigGetter` instead of the concrete implementation:\n\n```go\ntype Foo struct {\n    threshold intConfigGetter\n}\n\nfunc NewFoo(threshold intConfigGetter) Foo { // Injects the configuration getter\n    return Foo{threshold: threshold}\n}\n\nfunc (f Foo) Bar()  {\n    threshold := f.threshold.Get() // Reads the configuration\n    // ...\n}\n```\n\nIn this example, the configuration getter is injected into the `NewFoo` factory method. It doesn’t impact a client of this function because it can still pass an `IntConfig` struct as it implements `intConfigGetter`. Then, we can only read the configuration in the `Bar` method, not modify it. Therefore, we can also use interfaces to restrict a type to a specific behavior for various reasons, such as semantics enforcement.\n\nIn this section, we saw three potential use cases where interfaces are generally considered as bringing value: factoring out a common behavior, creating some decoupling, and restricting a type to a certain behavior. Again, this list isn’t exhaustive, but it should give us a general understanding of when interfaces are helpful in Go.\n\nNow, let’s finish this section and discuss the problems with interface pollution.\n\n## Interface pollution\n\nIt’s fairly common to see interfaces being overused in Go projects. Perhaps the developer’s background was C# or Java, and they found it natural to create interfaces before concrete types. However, this isn’t how things should work in Go.\n\nAs we discussed, interfaces are made to create abstractions. And the main caveat when programming meets abstractions is remembering that **abstractions should be discovered, not created**. What does this mean? It means we shouldn’t start creating abstractions in our code if there is no immediate reason to do so. We shouldn’t design with interfaces but wait for a concrete need. Said differently, we should create an interface when we need it, not when we foresee that we could need it.\n\nWhat’s the main problem if we overuse interfaces? The answer is that they make the code flow more complex. Adding a useless level of indirection doesn’t bring any value; it creates a worthless abstraction making the code more difficult to read, understand, and reason about. If we don’t have a strong reason for adding an interface and it’s unclear how an interface makes a code better, we should challenge this interface’s purpose. Why not call the implementation directly?\n\n???+ note\n\n    We may also experience performance overhead when calling a method through an interface. It requires a lookup in a hash table’s data structure to find the concrete type an interface points to. But this isn’t an issue in many contexts as the overhead is minimal.\n\nIn summary, we should be cautious when creating abstractions in our code—abstractions should be discovered, not created. It’s common for us, software developers, to overengineer our code by trying to guess what the perfect level of abstraction is, based on what we think we might need later. This process should be avoided because, in most cases, it pollutes our code with unnecessary abstractions, making it more complex to read.\n\n!!! quote \"Rob Pike\"\n\n    Don’t design with interfaces, discover them.\n\nLet’s not try to solve a problem abstractly but solve what has to be solved now. Last, but not least, if it’s unclear how an interface makes the code better, we should probably consider removing it to make our code simpler.\n"
  },
  {
    "path": "docs/56-concurrency-faster.md",
    "content": "---\ntitle: Thinking concurrency is always faster (#56)\ncomments: true\nhide:\n- toc\n---\n\n# Thinking concurrency is always faster\n\n![](img/56-concurrency-faster.png)\n\nA misconception among many developers is believing that a concurrent solution is always faster than a sequential one. This couldn’t be more wrong. The overall performance of a solution depends on many factors, such as the efficiency of our code structure (concurrency), which parts can be tackled in parallel, and the level of contention among the computation units. This post reminds us about some fundamental knowledge of concurrency in Go; then we will see a concrete example where a concurrent solution isn’t necessarily faster.\n\n## Go Scheduling\n\nA thread is the smallest unit of processing that an OS can perform. If a process wants to execute multiple actions simultaneously, it spins up multiple threads. These threads can be:\n\n* _Concurrent_ — Two or more threads can start, run, and complete in overlapping time periods.\n* _Parallel_ — The same task can be executed multiple times at once.\n\nThe OS is responsible for scheduling the thread’s processes optimally so that:\n\n* All the threads can consume CPU cycles without being starved for too much time.\n* The workload is distributed as evenly as possible among the different CPU cores.\n\n???+ note\n\n    The word thread can also have a different meaning at a CPU level. Each physical core can be composed of multiple logical cores (the concept of [hyper-threading](https://en.wikipedia.org/wiki/Hyper-threading)), and a logical core is also called a thread. In this post, when we use the word thread, we mean the unit of processing, not a logical core.\n\nA CPU core executes different threads. When it switches from one thread to another, it executes an operation called _context switching_. The active thread consuming CPU cycles was in an _executing_ state and moves to a _runnable_ state, meaning it’s ready to be executed pending an available core. Context switching is considered an expensive operation because the OS needs to save the current execution state of a thread before the switch (such as the current register values).\n\nAs Go developers, we can’t create threads directly, but we can create goroutines, which can be thought of as application-level threads. However, whereas an OS thread is context-switched on and off a CPU core by the OS, a goroutine is context-switched on and off an OS thread by the Go runtime. Also, compared to an OS thread, a goroutine has a smaller memory footprint: 2 KB for goroutines from Go 1.4. An OS thread depends on the OS, but, for example, on Linux/x86–32, the default size is 2 MB (see https://man7.org/linux/man-pages/man3/pthread_create.3.html). Having a smaller size makes context switching faster.\n\n???+ note\n\n    Context switching a goroutine versus a thread is about 80% to 90% faster, depending on the architecture.\n\nLet’s now discuss how the Go scheduler works to overview how goroutines are handled. Internally, the Go scheduler uses the following terminology (see [proc.go](https://github.com/golang/go/blob/go1.17.6/src/runtime/proc.go#L22)):\n\n* _G_ — Goroutine\n* _M_ — OS thread (stands for machine)\n* _P_ — CPU core (stands for processor)\n\nEach OS thread (M) is assigned to a CPU core (P) by the OS scheduler. Then, each goroutine (G) runs on an M. The GOMAXPROCS variable defines the limit of Ms in charge of executing user-level code simultaneously. But if a thread is blocked in a system call (for example, I/O), the scheduler can spin up more Ms. As of Go 1.5, GOMAXPROCS is by default equal to the number of available CPU cores.\n\nA goroutine has a simpler lifecycle than an OS thread. It can be doing one of the following:\n\n* _Executing_ — The goroutine is scheduled on an M and executing its instructions.\n* _Runnable_ — The goroutine is waiting to be in an executing state.\n* _Waiting_ — The goroutine is stopped and pending something completing, such as a system call or a synchronization operation (such as acquiring a mutex).\n\nThere’s one last stage to understand about the implementation of Go scheduling: when a goroutine is created but cannot be executed yet; for example, all the other Ms are already executing a G. In this scenario, what will the Go runtime do about it? The answer is queuing. The Go runtime handles two kinds of queues: one local queue per P and a global queue shared among all the Ps.\n\nFigure 1 shows a given scheduling situation on a four-core machine with GOMAXPROCS equal to 4. The parts are the logical cores (Ps), goroutines (Gs), OS threads (Ms), local queues, and global queue:\n\n<figure markdown>\n  ![](img/go-scheduler.png)\n  <figcaption>Figure 1: An example of the current state of a Go application executed on a four-core machine. Goroutines that aren’t in an executing state are either runnable (pending being executed) or waiting (pending a blocking operation)</figcaption>\n</figure>\n\nFirst, we can see five Ms, whereas GOMAXPROCS is set to 4. But as we mentioned, if needed, the Go runtime can create more OS threads than the GOMAXPROCS value.\n\nP0, P1, and P3 are currently busy executing Go runtime threads. But P2 is presently idle as M3 is switched off P2, and there’s no goroutine to be executed. This isn’t a good situation because six runnable goroutines are pending being executed, some in the global queue and some in other local queues. How will the Go runtime handle this situation? Here’s the scheduling implementation in pseudocode (see [proc.go](https://github.com/golang/go/blob/go1.17.6/src/runtime/proc.go#L3291)):\n\n```\nruntime.schedule() {\n    // Only 1/61 of the time, check the global runnable queue for a G.\n    // If not found, check the local queue.\n    // If not found,\n    //     Try to steal from other Ps.\n    //     If not, check the global runnable queue.\n    //     If not found, poll network.\n}\n```\n\nEvery sixty-first execution, the Go scheduler will check whether goroutines from the global queue are available. If not, it will check its local queue. Meanwhile, if both the global and local queues are empty, the Go scheduler can pick up goroutines from other local queues. This principle in scheduling is called _work stealing_, and it allows an underutilized processor to actively look for another processor’s goroutines and _steal_ some.\n\nOne last important thing to mention: prior to Go 1.14, the scheduler was cooperative, which meant a goroutine could be context-switched off a thread only in specific blocking cases (for example, channel send or receive, I/O, waiting to acquire a mutex). Since Go 1.14, the Go scheduler is now preemptive: when a goroutine is running for a specific amount of time (10 ms), it will be marked preemptible and can be context-switched off to be replaced by another goroutine. This allows a long-running job to be forced to share CPU time.\n\nNow that we understand the fundamentals of scheduling in Go, let’s look at a concrete example: implementing a merge sort in a parallel manner.\n\n## Parallel Merge Sort\n\nFirst, let’s briefly review how the merge sort algorithm works. Then we will implement a parallel version. Note that the objective isn’t to implement the most efficient version but to support a concrete example showing why concurrency isn’t always faster.\n\nThe merge sort algorithm works by breaking a list repeatedly into two sublists until each sublist consists of a single element and then merging these sublists so that the result is a sorted list (see figure 2). Each split operation splits the list into two sublists, whereas the merge operation merges two sublists into a sorted list.\n\n<figure markdown>\n  ![](img/mergesort.png)\n  <figcaption>Figure 2: Applying the merge sort algorithm repeatedly breaks each list into two sublists. Then the algorithm uses a merge operation such that the resulting list is sorted</figcaption>\n</figure>\n\nHere is the sequential implementation of this algorithm. We don’t include all of the code as it’s not the main point of this section:\n\n```go\nfunc sequentialMergesort(s []int) {\n    if len(s) <= 1 {\n        return\n    }\n\n    middle := len(s) / 2\n    sequentialMergesort(s[:middle]) // First half\n    sequentialMergesort(s[middle:]) // Second half\n    merge(s, middle) // Merges the two halves\n}\n\nfunc merge(s []int, middle int) {\n    // ...\n}\n```\n\nThis algorithm has a structure that makes it open to concurrency. Indeed, as each _sequentialMergesort_ operation works on an independent set of data that doesn’t need to be fully copied (here, an independent view of the underlying array using slicing), we could distribute this workload among the CPU cores by spinning up each _sequentialMergesort_ operation in a different goroutine. Let’s write a first parallel implementation:\n\n```go\nfunc parallelMergesortV1(s []int) {\n    if len(s) <= 1 {\n        return\n    }\n\n    middle := len(s) / 2\n\n    var wg sync.WaitGroup\n    wg.Add(2)\n\n    go func() { // Spins up the first half of the work in a goroutine\n        defer wg.Done()\n        parallelMergesortV1(s[:middle])\n    }()\n\n    go func() { // Spins up the second half of the work in a goroutine\n        defer wg.Done()\n        parallelMergesortV1(s[middle:])\n    }()\n\n    wg.Wait()\n    merge(s, middle) // Merges the halves\n}\n```\n\nIn this version, each half of the workload is handled in a separate goroutine. The parent goroutine waits for both parts by using _sync.WaitGroup_. Hence, we call the Wait method before the merge operation.\n\nWe now have a parallel version of the merge sort algorithm. Therefore, if we run a benchmark to compare this version against the sequential one, the parallel version should be faster, correct? Let’s run it on a four-core machine with 10,000 elements:\n\n```\nBenchmark_sequentialMergesort-4       2278993555 ns/op\nBenchmark_parallelMergesortV1-4      17525998709 ns/op\n```\n\nSurprisingly, the parallel version is almost an order of magnitude slower. How can we explain this result? How is it possible that a parallel version that distributes a workload across four cores is slower than a sequential version running on a single machine? Let’s analyze the problem.\n\nIf we have a slice of, say, 1,024 elements, the parent goroutine will spin up two goroutines, each in charge of handling a half consisting of 512 elements. Each of these goroutines will spin up two new goroutines in charge of handling 256 elements, then 128, and so on, until we spin up a goroutine to compute a single element.\n\nIf the workload that we want to parallelize is too small, meaning we’re going to compute it too fast, the benefit of distributing a job across cores is destroyed: the time it takes to create a goroutine and have the scheduler execute it is much too high compared to directly merging a tiny number of items in the current goroutine. Although goroutines are lightweight and faster to start than threads, we can still face cases where a workload is too small.\n\nSo what can we conclude from this result? Does it mean the merge sort algorithm cannot be parallelized? Wait, not so fast.\n\nLet’s try another approach. Because merging a tiny number of elements within a new goroutine isn’t efficient, let’s define a threshold. This threshold will represent how many elements a half should contain in order to be handled in a parallel manner. If the number of elements in the half is fewer than this value, we will handle it sequentially. Here’s a new version:\n\n```go\nconst max = 2048 // Defines the threshold\n\nfunc parallelMergesortV2(s []int) {\n    if len(s) <= 1 {\n        return\n    }\n\n    if len(s) <= max {\n        sequentialMergesort(s) // Calls our initial sequential version\n    } else { // If bigger than the threshold, keeps the parallel version\n        middle := len(s) / 2\n\n        var wg sync.WaitGroup\n        wg.Add(2)\n\n        go func() {\n            defer wg.Done()\n            parallelMergesortV2(s[:middle])\n        }()\n\n        go func() {\n            defer wg.Done()\n            parallelMergesortV2(s[middle:])\n        }()\n\n        wg.Wait()\n        merge(s, middle)\n    }\n}\n```\n\nIf the number of elements in the s slice is smaller than max, we call the sequential version. Otherwise, we keep calling our parallel implementation. Does this approach impact the result? Yes, it does:\n\n```\nBenchmark_sequentialMergesort-4       2278993555 ns/op\nBenchmark_parallelMergesortV1-4      17525998709 ns/op\nBenchmark_parallelMergesortV2-4       1313010260 ns/op\n```\n\nOur v2 parallel implementation is more than 40% faster than the sequential one, thanks to this idea of defining a threshold to indicate when parallel should be more efficient than sequential.\n\n???+ note\n\n    Why did I set the threshold to 2,048? Because it was the optimal value for this specific workload on my machine. In general, such magic values should be defined carefully with benchmarks (running on an execution environment similar to production). It’s also pretty interesting to note that running the same algorithm in a programming language that doesn’t implement the concept of goroutines has an impact on the value. For example, running the same example in Java using threads means an optimal value closer to 8,192. This tends to illustrate how goroutines are more efficient than threads.\n\n## Conclusion\n\nWe have seen throughout this post the fundamental concepts of scheduling in Go: the differences between a thread and a goroutine and how the Go runtime schedules goroutines. Meanwhile, using the parallel merge sort example, we illustrated that concurrency isn’t always necessarily faster. As we have seen, spinning up goroutines to handle minimal workloads (merging only a small set of elements) demolishes the benefit we could get from parallelism.\n\nSo, where should we go from here? We must keep in mind that concurrency isn’t always faster and shouldn’t be considered the default way to go for all problems. First, it makes things more complex. Also, modern CPUs have become incredibly efficient at executing sequential code and predictable code. For example, a superscalar processor can parallelize instruction execution over a single core with high efficiency.\n\nDoes this mean we shouldn’t use concurrency? Of course not. However, it’s essential to keep these conclusions in mind. If we’re not sure that a parallel version will be faster, the right approach may be to start with a simple sequential version and build from there using profiling (mistake #98, “[Not using Go diagnostics tooling](https://100go.co/98-profiling-execution-tracing/)”) and benchmarks (mistake #89, “[Writing inaccurate benchmarks](https://100go.co/89-benchmarks/)”), for example. It can be the only way to ensure that a concurrent implementation is worth it.\n"
  },
  {
    "path": "docs/89-benchmarks.md",
    "content": "---\ntitle: Writing inaccurate benchmarks (#89)\ncomments: true\nhide:\n- toc\n---\n\n# Writing inaccurate benchmarks\n\n![](img/89-benchmarks.png)\n\nIn general, we should never guess about performance. When writing optimizations, so many factors may come into play that even if we have a strong opinion about the results, it’s rarely a bad idea to test them. However, writing benchmarks isn’t straightforward. It can be pretty simple to write inaccurate benchmarks and make wrong assumptions based on them. The goal of this post is to examine four common and concrete traps leading to inaccuracy:\n\n* Not resetting or pausing the timer\n* Making wrong assumptions about micro-benchmarks\n* Not being careful about compiler optimizations\n* Being fooled by the observer effect\n\n## General concepts\n\nBefore discussing these traps, let’s briefly review how benchmarks work in Go. The skeleton of a benchmark is as follows:\n\n```go\nfunc BenchmarkFoo(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\tfoo()\n\t}\n}\n```\n\nThe function name starts with the `Benchmark` prefix. The function under test (foo) is called within the `for` loop. `b.N` represents a variable number of iterations. When running a benchmark, Go tries to make it match the requested benchmark time. The benchmark time is set by default to 1 second and can be changed with the `-benchtime` flag. `b.N` starts at 1; if the benchmark completes in under 1 second, `b.N` is increased, and the benchmark runs again until `b.N` roughly matches benchtime:\n\n```\n$ go test -bench=.\ncpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\nBenchmarkFoo-4                73          16511228 ns/op\n```\n\nHere, the benchmark took about 1 second, and `foo` was executed 73 times, for an average execution time of 16,511,228 nanoseconds. We can change the benchmark time using `-benchtime`:\n\n```\n$ go test -bench=. -benchtime=2s\nBenchmarkFoo-4               150          15832169 ns/op\n```\n\n`foo` was executed roughly twice more than during the previous benchmark.\n\nNext, let’s look at some common traps.\n\n## Not resetting or pausing the timer\n\nIn some cases, we need to perform operations before the benchmark loop. These operations may take quite a while (for example, generating a large slice of data) and may significantly impact the benchmark results:\n\n```go\nfunc BenchmarkFoo(b *testing.B) {\n\texpensiveSetup()\n\tfor i := 0; i < b.N; i++ {\n\t\tfunctionUnderTest()\n\t}\n}\n```\n\nIn this case, we can use the `ResetTimer` method before entering the loop:\n\n```go\nfunc BenchmarkFoo(b *testing.B) {\n\texpensiveSetup()\n\tb.ResetTimer() // Reset the benchmark timer\n\tfor i := 0; i < b.N; i++ {\n\t\tfunctionUnderTest()\n\t}\n}\n```\n\nCalling `ResetTimer` zeroes the elapsed benchmark time and memory allocation counters since the beginning of the test. This way, an expensive setup can be discarded from the test results.\n\nWhat if we have to perform an expensive setup not just once but within each loop iteration?\n\n```go\nfunc BenchmarkFoo(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\texpensiveSetup()\n\t\tfunctionUnderTest()\n\t}\n}\n```\n\nWe can’t reset the timer, because that would be executed during each loop iteration. But we can stop and resume the benchmark timer, surrounding the call to `expensiveSetup`:\n\n```go\nfunc BenchmarkFoo(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer() // Pause the benchmark timer\n\t\texpensiveSetup()\n\t\tb.StartTimer() // Resume the benchmark timer\n\t\tfunctionUnderTest()\n\t}\n}\n```\n\nHere, we pause the benchmark timer to perform the expensive setup and then resume the timer.\n\n???+ note\n\n    There’s one catch to remember about this approach: if the function under test is too fast to execute compared to the setup function, the benchmark may take too long to complete. The reason is that it would take much longer than 1 second to reach `benchtime`. Calculating the benchmark time is based solely on the execution time of `functionUnderTest`. So, if we wait a significant time in each loop iteration, the benchmark will be much slower than 1 second. If we want to keep the benchmark, one possible mitigation is to decrease `benchtime`.\n\nWe must be sure to use the timer methods to preserve the accuracy of a benchmark.\n\n## Making wrong assumptions about micro-benchmarks\n\nA micro-benchmark measures a tiny computation unit, and it can be extremely easy to make wrong assumptions about it. Let’s say, for example, that we aren’t sure whether to use `atomic.StoreInt32` or `atomic.StoreInt64` (assuming that the values we handle will always fit in 32 bits). We want to write a benchmark to compare both functions:\n\n```go\nfunc BenchmarkAtomicStoreInt32(b *testing.B) {\n\tvar v int32\n\tfor i := 0; i < b.N; i++ {\n\t\tatomic.StoreInt32(&v, 1)\n\t}\n}\n\nfunc BenchmarkAtomicStoreInt64(b *testing.B) {\n\tvar v int64\n\tfor i := 0; i < b.N; i++ {\n\t\tatomic.StoreInt64(&v, 1)\n\t}\n}\n```\n\nIf we run this benchmark, here’s some example output:\n\n```\ncpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\nBenchmarkAtomicStoreInt32\nBenchmarkAtomicStoreInt32-4    197107742           5.682 ns/op\nBenchmarkAtomicStoreInt64\nBenchmarkAtomicStoreInt64-4    213917528           5.134 ns/op\n```\n\nWe could easily take this benchmark for granted and decide to use `atomic.StoreInt64` because it appears to be faster. Now, for the sake of doing a fair benchmark, we reverse the order and test `atomic.StoreInt64` first, followed by `atomic.StoreInt32`. Here is some example output:\n\n```\nBenchmarkAtomicStoreInt64\nBenchmarkAtomicStoreInt64-4    224900722           5.434 ns/op\nBenchmarkAtomicStoreInt32\nBenchmarkAtomicStoreInt32-4    230253900           5.159 ns/op\n```\n\nThis time, `atomic.StoreInt32` has better results. What happened?\n\nIn the case of micro-benchmarks, many factors can impact the results, such as machine activity while running the benchmarks, power management, thermal scaling, and better cache alignment of a sequence of instructions. We must remember that many factors, even outside the scope of our Go project, can impact the results.\n\n???+ note\n\n    We should make sure the machine executing the benchmark is idle. However, external processes may run in the background, which may affect benchmark results. For that reason, tools such as `perflock` can limit how much CPU a benchmark can consume. For example, we can run a benchmark with 70% of the total available CPU, giving 30% to the OS and other processes and reducing the impact of the machine activity factor on the results.\n\nOne option is to increase the benchmark time using the `-benchtime` option. Similar to the law of large numbers in probability theory, if we run a benchmark a large number of times, it should tend to approach its expected value (assuming we omit the benefits of instructions caching and similar mechanics).\n\nAnother option is to use external tools on top of the classic benchmark tooling. For instance, the `benchstat` tool, which is part of the `golang.org/x` repository, allows us to compute and compare statistics about benchmark executions.\n\nLet’s run the benchmark 10 times using the `-count` option and pipe the output to a specific file:\n\n```\n$ go test -bench=. -count=10 | tee stats.txt\ncpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\nBenchmarkAtomicStoreInt32-4     234935682                5.124 ns/op\nBenchmarkAtomicStoreInt32-4     235307204                5.112 ns/op\n// ...\nBenchmarkAtomicStoreInt64-4     235548591                5.107 ns/op\nBenchmarkAtomicStoreInt64-4     235210292                5.090 ns/op\n// ...\n```\n\nWe can then run `benchstat` on this file:\n\n```\n$ benchstat stats.txt\nname                time/op\nAtomicStoreInt32-4  5.10ns ± 1%\nAtomicStoreInt64-4  5.10ns ± 1%\n```\n\nThe results are the same: both functions take on average 5.10 nanoseconds to complete. We also see the percent variation between the executions of a given benchmark: ± 1%. This metric tells us that both benchmarks are stable, giving us more confidence in the computed average results. Therefore, instead of concluding that `atomic.StoreInt32` is faster or slower, we can conclude that its execution time is similar to that of `atomic.StoreInt64` for the usage we tested (in a specific Go version on a particular machine).\n\nIn general, we should be cautious about micro-benchmarks. Many factors can significantly impact the results and potentially lead to wrong assumptions. Increasing the benchmark time or repeating the benchmark executions and computing stats with tools such as `benchstat` can be an efficient way to limit external factors and get more accurate results, leading to better conclusions.\n\nLet’s also highlight that we should be careful about using the results of a micro-benchmark executed on a given machine if another system ends up running the application. The production system may act quite differently from the one on which we ran the micro-benchmark.\n\n## Not being careful about compiler optimizations\n\nAnother common mistake related to writing benchmarks is being fooled by compiler optimizations, which can also lead to wrong benchmark assumptions. In this section, we look at Go issue 14813 (https://github.com/golang/go/issues/14813, also discussed by Go project member Dave Cheney) with a population count function (a function that counts the number of bits set to 1):\n\n```go\nconst m1 = 0x5555555555555555\nconst m2 = 0x3333333333333333\nconst m4 = 0x0f0f0f0f0f0f0f0f\nconst h01 = 0x0101010101010101\n\nfunc popcnt(x uint64) uint64 {\n\tx -= (x >> 1) & m1\n\tx = (x & m2) + ((x >> 2) & m2)\n\tx = (x + (x >> 4)) & m4\n\treturn (x * h01) >> 56\n}\n```\n\nThis function takes and returns a `uint64`. To benchmark this function, we can write the following:\n\n```go\nfunc BenchmarkPopcnt1(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\tpopcnt(uint64(i))\n\t}\n}\n```\n\nHowever, if we execute this benchmark, we get a surprisingly low result:\n\n```\ncpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\nBenchmarkPopcnt1-4      1000000000               0.2858 ns/op\n```\n\nA duration of 0.28 nanoseconds is roughly one clock cycle, so this number is unreasonably low. The problem is that the developer wasn’t careful enough about compiler optimizations. In this case, the function under test is simple enough to be a candidate for inlining: an optimization that replaces a function call with the body of the called function and lets us prevent a function call, which has a small footprint. Once the function is inlined, the compiler notices that the call has no side effects and replaces it with the following benchmark:\n\n```go\nfunc BenchmarkPopcnt1(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\t// Empty\n\t}\n}\n```\n\nThe benchmark is now empty — which is why we got a result close to one clock cycle. To prevent this from happening, a best practice is to follow this pattern:\n\n1. During each loop iteration, assign the result to a local variable (local in the context of the benchmark function).\n2. Assign the latest result to a global variable.\n\nIn our case, we write the following benchmark:\n\n```go\nvar global uint64 // Define a global variable\n\nfunc BenchmarkPopcnt2(b *testing.B) {\n\tvar v uint64 // Define a local variable\n\tfor i := 0; i < b.N; i++ {\n\t\tv = popcnt(uint64(i)) // Assign the result to the local variable\n\t}\n\tglobal = v // Assign the result to the global variable\n}\n```\n\n`global` is a global variable, whereas v is a local variable whose scope is the benchmark function. During each loop iteration, we assign the result of `popcnt` to the local variable. Then we assign the latest result to the global variable.\n\n???+ note\n\n    Why not assign the result of the popcnt call directly to global to simplify the test? Writing to a global variable is slower than writing to a local variable (these concepts are discussed in 100 Go Mistakes, mistake #95: “[Not understanding stack vs. heap](https://100go.co#not-understanding-stack-vs-heap-95)”). Therefore, we should write each result to a local variable to limit the footprint during each loop iteration.\n\nIf we run these two benchmarks, we now get a significant difference in the results:\n\n```\ncpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\nBenchmarkPopcnt1-4      1000000000               0.2858 ns/op\nBenchmarkPopcnt2-4      606402058                1.993 ns/op\n```\n\n`BenchmarkPopcnt2` is the accurate version of the benchmark. It guarantees that we avoid the inlining optimizations, which can artificially lower the execution time or even remove the call to the function under test. Relying on the results of `BenchmarkPopcnt1` could have led to wrong assumptions.\n\nLet’s remember the pattern to avoid compiler optimizations fooling benchmark results: assign the result of the function under test to a local variable, and then assign the latest result to a global variable. This best practice also prevents us from making incorrect assumptions.\n\n## Being fooled by the observer effect\n\nIn physics, the observer effect is the disturbance of an observed system by the act of observation. This effect can also be seen in benchmarks and can lead to wrong assumptions about results. Let’s look at a concrete example and then try to mitigate it.\n\nWe want to implement a function receiving a matrix of `int64` elements. This matrix has a fixed number of 512 columns, and we want to compute the total sum of the first eight columns, as shown in figure 1.\n\n<figure markdown>\n  ![](img/matrix.png)\n  <figcaption>Figure 1: Computing the sum of the first eight columns.</figcaption>\n</figure>\n\nFor the sake of optimizations, we also want to determine whether varying the number of columns has an impact, so we also implement a second function with 513 columns. The implementation is the following:\n\n```go\nfunc calculateSum512(s [][512]int64) int64 {\n\tvar sum int64\n\tfor i := 0; i < len(s); i++ { // Iterate over each row\n\t\tfor j := 0; j < 8; j++ { // Iterate over the first eight columns\n\t\t\tsum += s[i][j] // Increment sum\n\t\t}\n\t}\n\treturn sum\n}\n\nfunc calculateSum513(s [][513]int64) int64 {\n\t// Same implementation as calculateSum512\n}\n```\n\nWe iterate over each row and then over the first eight columns, and we increment a sum variable that we return. The implementation in `calculateSum513` remains the same.\n\nWe want to benchmark these functions to decide which one is the most performant given a fixed number of rows:\n\n```go\nconst rows = 1000\n\nvar res int64\n\nfunc BenchmarkCalculateSum512(b *testing.B) {\n\tvar sum int64\n\ts := createMatrix512(rows) // Create a matrix of 512 columns\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tsum = calculateSum512(s) // Create a matrix of 512 columns\n\t}\n\tres = sum\n}\n\nfunc BenchmarkCalculateSum513(b *testing.B) {\n\tvar sum int64\n\ts := createMatrix513(rows) // Create a matrix of 513 columns\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tsum = calculateSum513(s) // Calculate the sum\n\t}\n\tres = sum\n}\n```\n\nWe want to create the matrix only once, to limit the footprint on the results. Therefore, we call `createMatrix512` and `createMatrix513` outside of the loop. We may expect the results to be similar as again we only want to iterate on the first eight columns, but this isn’t the case (on my machine):\n\n```\ncpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\nBenchmarkCalculateSum512-4        81854             15073 ns/op\nBenchmarkCalculateSum513-4       161479              7358 ns/op\n```\n\nThe second benchmark with 513 columns is about 50% faster. Again, because we iterate only over the first eight columns, this result is quite surprising.\n\nTo understand this difference, we need to understand the basics of CPU caches. In a nutshell, a CPU is composed of different caches (usually L1, L2, and L3). These caches reduce the average cost of accessing data from the main memory. In some conditions, the CPU can fetch data from the main memory and copy it to L1. In this case, the CPU tries to fetch into L1 the matrix’s subset that `calculateSum` is interested in (the first eight columns of each row). However, the matrix fits in memory in one case (513 columns) but not in the other case (512 columns).\n\n???+ note\n\n    This isn’t in the scope of this post to explain why, but we look at this problem in 100 Go Mistakes, mistake #91: “[Not understanding CPU caches.](https://100go.co#not-understanding-cpu-caches-91)”\n\nComing back to the benchmark, the main issue is that we keep reusing the same matrix in both cases. Because the function is repeated thousands of times, we don’t measure the function’s execution when it receives a plain new matrix. Instead, we measure a function that gets a matrix that already has a subset of the cells present in the cache. Therefore, because `calculateSum513` leads to fewer cache misses, it has a better execution time.\n\nThis is an example of the observer effect. Because we keep observing a repeatedly called CPU-bound function, CPU caching may come into play and significantly affect the results. In this example, to prevent this effect, we should create a matrix during each test instead of reusing one:\n\n```go\nfunc BenchmarkCalculateSum512(b *testing.B) {\n\tvar sum int64\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer()\n\t\ts := createMatrix512(rows) // Create a new matrix during each loop iteration\n\t\tb.StartTimer()\n\t\tsum = calculateSum512(s)\n\t}\n\tres = sum\n}\n```\n\nA new matrix is now created during each loop iteration. If we run the benchmark again (and adjust `benchtime` — otherwise, it takes too long to execute), the results are closer to each other:\n\n```\ncpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\nBenchmarkCalculateSum512-4         1116             33547 ns/op\nBenchmarkCalculateSum513-4          998             35507 ns/op\n```\n\nInstead of making the incorrect assumption that calculateSum513 is faster, we see that both benchmarks lead to similar results when receiving a new matrix.\n\nAs we have seen in this post, because we were reusing the same matrix, CPU caches significantly impacted the results. To prevent this, we had to create a new matrix during each loop iteration. In general, we should remember that observing a function under test may lead to significant differences in results, especially in the context of micro-benchmarks of CPU-bound functions where low-level optimizations matter. Forcing a benchmark to re-create data during each iteration can be a good way to prevent this effect."
  },
  {
    "path": "docs/9-generics.md",
    "content": "---\ntitle: Being confused about when to use generics (#9)\ncomments: true\nhide:\n- toc\n---\n\n# Being confused about when to use generics\n\nGenerics is a fresh addition to the language. In a nutshell, it allows writing code with types that can be specified later and instantiated when needed. However, it can be pretty easy to be confused about when to use generics and when not to. Throughout this post, we will describe the concept of generics in Go and then delve into common use and misuses.\n\n## Concepts\n\nConsider the following function that extracts all the keys from a `map[string]int` type:\n\n```go\nfunc getKeys(m map[string]int) []string {\n    var keys []string\n    for k := range m {\n        keys = append(keys, k)\n    }\n    return keys\n}\n```\n\nWhat if we would like to use a similar feature for another map type such as a `map[int]string`? Before generics, Go developers had a couple of options: using code generation, reflection, or duplicating code.\n\nFor example, we could write two functions, one for each map type, or even try to extend `getKeys` to accept different map types:\n\n```go\nfunc getKeys(m any) ([]any, error) {\n    switch t := m.(type) {\n    default:\n        return nil, fmt.Errorf(\"unknown type: %T\", t)\n    case map[string]int:\n        var keys []any\n        for k := range t {\n            keys = append(keys, k)\n        }\n        return keys, nil\n    case map[int]string:\n        // Copy the extraction logic\n    }\n}\n```\n\nWe can start noticing a couple of issues:\n\n* First, it increases boilerplate code. Indeed, whenever we want to add a case, it will require duplicating the `range` loop.\n*  Meanwhile, the function now accepts an empty interface, which means we are losing some of the benefits of Go being a typed language. Indeed, checking whether a type is supported is done at runtime instead of compile-time. Hence, we also need to return an error if the provided type is unknown.\n* Last but not least, as the key type can be either `int` or `string`, we are obliged to return a slice of empty interfaces to factor out key types. This approach increases the effort on the caller-side as the client may also have to perform a type check of the keys or extra conversion.\n\nThanks to generics, we can now refactor this code using type parameters.\n\nType parameters are generic types we can use with functions and types. For example, the following function accepts a type parameter:\n\n```go\nfunc foo[T any](t T) {\n    // ...\n}\n```\n\nWhen calling `foo`, we will pass a type argument of any type. Passing a type argument is called instantiation because the work is done at compile time which keeps type safety as part of the core language features and avoids runtime overheads.\n\nLet’s get back to the `getKeys` function and use type parameters to write a generic version that would accept any kind of map:\n\n```go\nfunc getKeys[K comparable, V any](m map[K]V) []K {\n  var keys []K\n  for k := range m {\n    keys = append(keys, k)\n  }\n  return keys\n}\n```\n\nTo handle the map, we defined two kinds of type parameters. First, the values can be of any type: `V any`. However, in Go, the map keys can’t be of any type. For example, we cannot use slices:\n\n```go\nvar m map[[]byte]int\n```\n\nThis code leads to a compilation error: `invalid map key type []byte`. Therefore, instead of accepting any key type, we are obliged to restrict type arguments so that the key type meets specific requirements. Here, being comparable (we can use `==` or `!=`). Hence, we defined `K` as `comparable` instead of `any`.\n\nRestricting type arguments to match specific requirements is called a constraint. A constraint is an interface type that can contain:\n\n* A set of behaviors (methods)\n* But also arbitrary type\n\nLet’s see a concrete example for the latter. Imagine we don’t want to accept any `comparable` type for map key type. For instance, we would like to restrict it to either `int` or `string` types. We can define a custom constraint this way:\n\n```go\ntype customConstraint interface {\n   ~int | ~string // Define a custom type that will restrict types to int and string\n}\n\n// Change the type parameter K to be custom\nfunc getKeys[K customConstraint, V any](m map[K]V) []K {\n   // Same implementation\n}\n```\n\nFirst, we define a `customConstraint` interface to restrict the types to be either `int` or `string` using the union operator `|` (we will discuss the use of `~` a bit later). Then, `K` is now a `customConstraint` instead of a `comparable` as before.\n\nNow, the signature of `getKeys` enforces that we can call it with a map of any value type, but the key type has to be an `int` or a `string`. For example, on the caller-side:\n\n```go\nm = map[string]int{\n   \"one\":   1,\n   \"two\":   2,\n   \"three\": 3,\n}\nkeys := getKeys(m)\n```\n\nNote that Go can infer that `getKeys` is called with a `string` type argument. The previous call was similar to this:\n\n```go\nkeys := getKeys[string](m)\n```\n\n???+ note\n\n    What’s the difference between a constraint using `~int` or `int`? Using `int` restricts it to that type, whereas `~int` restricts all the types whose underlying type is an `int`.\n\n    To illustrate it, let’s imagine a constraint where we would like to restrict a type to any `int` type implementing the `String() string` method:\n\n    ```go\n    type customConstraint interface {\n       ~int\n       String() string\n    }\n    ```\n\n    Using this constraint will restrict type arguments to custom types like this one:\n\n    ```go\n    type customInt int\n\n    func (i customInt) String() string {\n       return strconv.Itoa(int(i))\n    }\n    ```\n\n    As `customInt` is an `int` and implements the `String() string` method, the `customInt` type satisfies the constraint defined.\n\n    However, if we change the constraint to contain an `int` instead of an `~int`, using `customInt` would lead to a compilation error because the `int` type doesn’t implement `String() string`.\n\nLet’s also note the `constraints` package contains a set of common constraints such as `Signed` that includes all the signed integer types. Let’s ensure that a constraint doesn’t already exist in this package before creating a new one.\n\nSo far, we have discussed examples using generics for functions. However, we can also use generics with data structures.\n\nFor example, we will create a linked list containing values of any type. Meanwhile, we will write an `Add` method to append a node:\n\n```go\ntype Node[T any] struct { // Use type parameter\n   Val  T\n   next *Node[T]\n}\n\nfunc (n *Node[T]) Add(next *Node[T]) { // Instantiate type receiver\n   n.next = next\n}\n```\n\nWe use type parameters to define `T` and use both fields in `Node`. Regarding the method, the receiver is instantiated. Indeed, because `Node` is generic, it has to follow also the type parameter defined.\n\nOne last thing to note about type parameters: they can’t be used on methods, only on functions. For example, the following method wouldn’t compile:\n\n```go\ntype Foo struct {}\n\nfunc (Foo) bar[T any](t T) {}\n```\n\n```\n./main.go:29:15: methods cannot have type parameters\n```\n\nNow, let’s delve into concrete cases where we should and shouldn’t use generics.\n\n## Common uses and misuses\n\nSo when are generics useful? Let’s discuss a couple of common uses where generics **are** recommended:\n\n* Data structures. For example, we can use generics to factor out the element type if we implement a binary tree, a linked list, or a heap.\n* Functions working with slices, maps, and channels of any type. For example, a function to merge two channels would work with any channel type. Hence, we could use type parameters to factor out the channel type:\n\n  ```go\n  func merge[T any](ch1, ch2 <-chan T) <-chan T {\n      // ...\n  }\n  ```\n\n* Meanwhile, instead of factoring out a type, we can factor out behaviors. For example, the `sort` package contains functions to sort different slice types such as `sort.Ints` or `sort.Float64s`. Using type parameters, we can factor out the sorting behaviors that rely on three methods, `Len`, `Less`, and `Swap`:\n\n  ```go\n  type sliceFn[T any] struct { // Use type parameter\n     s       []T\n     compare func(T, T) bool // Compare two T elements\n  }\n\n  func (s sliceFn[T]) Len() int           { return len(s.s) }\n  func (s sliceFn[T]) Less(i, j int) bool { return s.compare(s.s[i], s.s[j]) }\n  func (s sliceFn[T]) Swap(i, j int)      { s.s[i], s.s[j] = s.s[j], s.s[i] }\n  ```\n\nConversely, when is it recommended **not** to use generics?\n\n* When just calling a method of the type argument. For example, consider a function that receives an `io.Writer` and call the `Write` method:\n\n  ```go\n  func foo[T io.Writer](w T) {\n     b := getBytes()\n     _, _ = w.Write(b)\n  }\n  ```\n\n* When it makes our code more complex. Generics are never mandatory, and as Go developers, we have been able to live without them for more than a decade. If writing generic functions or structures we figure out that it doesn’t make our code clearer, we should probably reconsider our decision for this particular use case.\n\n## Conclusion\n\nThough generics can be very helpful in particular conditions, we should be cautious about when to use them and not use them.\n\nIn general, when we want to answer when not to use generics, we can find similarities with when not to use interfaces. Indeed, generics introduce a form of abstraction, and we have to remember that unnecessary abstractions introduce complexity.\n\nLet’s not pollute our code with needless abstractions, and let’s focus on solving concrete problems for now. It means that we shouldn’t use type parameters prematurely. Let’s wait until we are about to write boilerplate code to consider using generics.\n\n"
  },
  {
    "path": "docs/92-false-sharing.md",
    "content": "---\ntitle: Writing concurrent code that leads to false sharing (#92)\ncomments: true\nhide:\n- toc\nstatus: new\n---\n\n# Writing concurrent code that leads to false sharing\n\n![](img/false-sharing.jpeg)\n\nIn previous sections, we have discussed the fundamental concepts of CPU caching. We have seen that some specific caches (typically, L1 and L2) aren’t shared among all the logical cores but are specific to a physical core. This specificity has some concrete impacts such as concurrency and the concept of false sharing, which can lead to a significant performance decrease. Let’s look at what false sharing is via an example and then see how to prevent it.\n\nIn this example, we use two structs, `Input` and `Result`:\n\n```go\ntype Input struct {\n    a int64\n    b int64\n}\n\ntype Result struct {\n    sumA int64\n    sumB int64\n}\n```\n\nThe goal is to implement a `count` function that receives a slice of `Input` and computes the following:\n\n* The sum of all the `Input.a` fields into `Result.sumA`\n* The sum of all the `Input.b` fields into `Result.sumB`\n\nFor the sake of the example, we implement a concurrent solution with one goroutine that computes `sumA` and another that computes `sumB`:\n\n```go\nfunc count(inputs []Input) Result {\n    wg := sync.WaitGroup{}\n    wg.Add(2)\n\n    result := Result{} // Init the result struct\n\n    go func() {\n        for i := 0; i < len(inputs); i++ {\n            result.sumA += inputs[i].a // Computes sumA\n        }\n        wg.Done()\n    }()\n\n    go func() {\n        for i := 0; i < len(inputs); i++ {\n            result.sumB += inputs[i].b // Computes sumB\n        }\n        wg.Done()\n    }()\n\n    wg.Wait()\n    return result\n}\n```\n\nWe spin up two goroutines: one that iterates over each a field and another that iterates over each b field. This example is fine from a concurrency perspective. For instance, it doesn’t lead to a data race, because each goroutine increments its own variable. But this example illustrates the false sharing concept that degrades expected performance.\n\nLet’s look at the main memory. Because `sumA` and `sumB` are allocated contiguously, in most cases (seven out of eight), both variables are allocated to the same memory block:\n\n<figure markdown>\n  ![](img/false-sharing-1.svg)\n  <figcaption>In this example, sumA and sumB are part of the same memory block.</figcaption>\n</figure>\n\n\nNow, let’s assume that the machine contains two cores. In most cases, we should eventually have two threads scheduled on different cores. So if the CPU decides to copy this memory block to a cache line, it is copied twice:\n\n<figure markdown>\n  ![](img/false-sharing-2.svg)\n  <figcaption>Each block is copied to a cache line on both code 0 and core 1.</figcaption>\n</figure>\n\nBoth cache lines are replicated because L1D (L1 data) is per core. Recall that in our example, each goroutine updates its own variable: `sumA` on one side, and `sumB` on the other side:\n\n<figure markdown>\n  ![](img/false-sharing-3.svg)\n  <figcaption>Each goroutine updates its own variable.</figcaption>\n</figure>\n\nBecause these cache lines are replicated, one of the goals of the CPU is to guarantee cache coherency. For example, if one goroutine updates `sumA` and another reads `sumA` (after some synchronization), we expect our application to get the latest value.\n\nHowever, our example doesn’t do exactly this. Both goroutines access their own variables, not a shared one. We might expect the CPU to know about this and understand that it isn’t a conflict, but this isn’t the case. When we write a variable that’s in a cache, the granularity tracked by the CPU isn’t the variable: it’s the cache line.\n\nWhen a cache line is shared across multiple cores and at least one goroutine is a writer, the entire cache line is invalidated. This happens even if the updates are logically independent (for example, `sumA` and `sumB`). This is the problem of false sharing, and it degrades performance.\n\n???+ note\n\n    Internally, a CPU uses the [MESI protocol](https://en.wikipedia.org/wiki/MESI_protocol) to guarantee cache coherency. It tracks each cache line, marking it modified, exclusive, shared, or invalid (MESI).\n\nOne of the most important aspects to understand about memory and caching is that sharing memory across cores isn’t real—it’s an illusion. This understanding comes from the fact that we don’t consider a machine a black box; instead, we try to have mechanical sympathy with underlying levels.\n\nSo how do we solve false sharing? There are two main solutions.\n\nThe first solution is to use the same approach we’ve shown but ensure that `sumA` and `sumB` aren’t part of the same cache line. For example, we can update the `Result` struct to add _padding_ between the fields. Padding is a technique to allocate extra memory. Because an `int64` requires an 8-byte allocation and a cache line 64 bytes long, we need 64 – 8 = 56 bytes of padding:\n\n```go hl_lines=\"3\"\ntype Result struct {\n    sumA int64\n    _    [56]byte // Padding\n    sumB int64\n}\n```\n\nThe next figure shows a possible memory allocation. Using padding, `sumA` and `sumB` will always be part of different memory blocks and hence different cache lines.\n\n<figure markdown>\n  ![](img/false-sharing-4.svg)\n  <figcaption>sumA and sumB are part of different memory blocks.</figcaption>\n</figure>\n\nIf we benchmark both solutions (with and without padding), we see that the padding solution is significantly faster (about 40% on my machine). This is an important improvement that results from the addition of padding between the two fields to prevent false sharing.\n\nThe second solution is to rework the structure of the algorithm. For example, instead of having both goroutines share the same struct, we can make them communicate their local result via channels. The result benchmark is roughly the same as with padding.\n\nIn summary, we must remember that sharing memory across goroutines is an illusion at the lowest memory levels. False sharing occurs when a cache line is shared across two cores when at least one goroutine is a writer. If we need to optimize an application that relies on concurrency, we should check whether false sharing applies, because this pattern is known to degrade application performance. We can prevent false sharing with either padding or communication.\n"
  },
  {
    "path": "docs/98-profiling-execution-tracing.md",
    "content": "---\ntitle: Not using Go diagnostics tooling (#98)\ncomments: true\nhide:\n- toc\n---\n\n# Not using Go diagnostics tooling\n\n![](img/98-profiling-execution-tracing.png)\n\nGo offers a few excellent diagnostics tools to help us get insights into how an application performs. This post focuses on the most important ones: profiling and the execution tracer. Both tools are so important that they should be part of the core toolset of any Go developer who is interested in optimization. First, let’s discuss profiling.\n\n## Profiling\n\nProfiling provides insights into the execution of an application. It allows us to resolve performance issues, detect contention, locate memory leaks, and more. These insights can be collected via several profiles:\n\n* `CPU`— Determines where an application spends its time\n* `Goroutine`— Reports the stack traces of the ongoing goroutines\n* `Heap`— Reports heap memory allocation to monitor current memory usage and check for possible memory leaks\n* `Mutex`— Reports lock contentions to see the behaviors of the mutexes used in our code and whether an application spends too much time in locking calls\n* `Block`— Shows where goroutines block waiting on synchronization primitives\n\nProfiling is achieved via instrumentation using a tool called a profiler, in Go: `pprof`. First, let’s understand how and when to enable `pprof`; then, we discuss the most critical profile types.\n\n### Enabling pprof\n\nThere are several ways to enable `pprof`. For example, we can use the `net/http/pprof` package to serve the profiling data via HTTP:\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"log\"\n    \"net/http\"\n    _ \"net/http/pprof\" // Blank import to pprof\n)\n\nfunc main() {\n    // Exposes an HTTP endpoint\n    http.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n        fmt.Fprintf(w, \"\")\n    })\n    log.Fatal(http.ListenAndServe(\":80\", nil))\n}\n```\n\nImporting `net/http/pprof` leads to a side effect that allows us to reach the pprof URL: [http://host/debug/pprof](http://host/debug/pprof). Note that enabling `pprof` is safe even in production ([https://go.dev/doc/diagnostics#profiling](https://go.dev/doc/diagnostics#profiling)). The profiles that impact performance, such as CPU profiling, aren’t enabled by default, nor do they run continuously: they are activated only for a specific period.\n\nNow that we have seen how to expose a `pprof` endpoint, let’s discuss the most common profiles.\n\n### CPU Profiling\n\nThe CPU profiler relies on the OS and signaling. When it is activated, the application asks the OS to interrupt it every 10 ms by default via a `SIGPROF` signal. When the application receives a `SIGPROF`, it suspends the current activity and transfers the execution to the profiler. The profiler collects data such as the current goroutine activity and aggregates execution statistics that we can retrieve. Then it stops, and the execution resumes until the next `SIGPROF`.\n\nWe can access the /debug/pprof/profile endpoint to activate CPU profiling. Accessing this endpoint executes CPU profiling for 30 seconds by default. For 30 seconds, our application is interrupted every 10 ms. Note that we can change these two default values: we can use the `seconds` parameter to pass to the endpoint how long the profiling should last (for example, /debug/pprof/profile?seconds=15), and we can change the interruption rate (even to less than 10 ms). But in most cases, 10 ms should be enough, and in decreasing this value (meaning increasing the rate), we should be careful not to harm performance. After 30 seconds, we download the results of the CPU profiler.\n\n???+ note\n\n    We can also enable the CPU profiler using the `-cpuprofile` flag, such as when running a benchmark. For example, the following command produces the same type of file that can be downloaded via /debug/ pprof/profile.\n    \n    ```\n    $ go test -bench=. -cpuprofile profile.out\n    ```\n\nFrom this file, we can navigate to the results using `go tool`:\n\n```\n$ go tool pprof -http=:8080 <file>\n```\n\nThis command opens a web UI showing the call graph. The next figure shows an example taken from an application. The larger the arrow, the more it was a hot path. We can then navigate into this graph and get execution insights.\n\n<figure markdown>\n  ![](img/screen-pprof-cpu.png)\n  <figcaption>Figure 1: The call graph of an application during 30 seconds.</figcaption>\n</figure>\n\nFor example, the graph in the next figure tells us that during 30 seconds, 0.06 seconds were spent in the `decode` method (`*FetchResponse` receiver). Of these 0.06 seconds, 0.02 were spent in `RecordBatch.decode` and 0.01 in `makemap` (creating a map).\n\n<figure markdown>\n  ![](img/screen-pprof-sarama.png)\n  <figcaption>Figure 2: Example call graph.</figcaption>\n</figure>\n\nWe can also access this kind of information from the web UI with different representations. For example, the Top view sorts the functions per execution time, and Flame Graph visualizes the execution time hierarchy. The UI can even display the expensive parts of the source code line by line.\n\n???+ note\n\n    We can also delve into profiling data via a command line. However, we focus on the web UI in this post.\n\nThanks to this data, we can get a general idea of how an application behaves:\n\n* Too many calls to `runtime.mallogc` can mean an excessive number of small heap allocations that we can try to minimize.\n* Too much time spent in channel operations or mutex locks can indicate excessive contention that is harming the application’s performance.\n* Too much time spent on `syscall.Read` or `syscall.Write` means the application spends a significant amount of time in Kernel mode. Working on I/O buffering may be an avenue for improvement.\n\nThese are the kinds of insights we can get from the CPU profiler. It’s valuable to understand the hottest code path and identify bottlenecks. But it won’t determine more than the configured rate because the CPU profiler is executed at a fixed pace (by default, 10 ms). To get finer-grained insights, we should use tracing, which we discuss later in this post.\n\n???+ note\n\n    We can also attach labels to the different functions. For example, imagine a common function called from different clients. To track the time spent for both clients, we can use `pprof.Labels`.\n\n### Heap Profiling\n\nHeap profiling allows us to get statistics about the current heap usage. Like CPU profiling, heap profiling is sample-based. We can change this rate, but we shouldn’t be too granular because the more we decrease the rate, the more effort heap profiling will require to collect data. By default, samples are profiled at one allocation for every 512 KB of heap allocation.\n\nIf we reach /debug/pprof/heap/, we get raw data that can be hard to read. However, we can download a heap profile using /debug/pprof/heap/?debug=0 and then open it with `go tool` (the same command as in the previous section) to navigate into the data using the web UI.\n\nThe next figure shows an example of a heap graph. Calling the `MetadataResponse.decode` method leads to allocating 1536 KB of heap data (which represents 6.32% of the total heap). However, 0 out of these 1536 KB were allocated by this function directly, so we need to inspect the second call. The `TopicMetadata.decode` method allocated 512 KB out of the 1536 KB; the rest — 1024 KB — were allocated in another method.\n\n<figure markdown>\n  ![](img/screen-pprof-heap.png)\n  <figcaption>Figure 3: A heap graph.</figcaption>\n</figure>\n\nThis is how we can navigate the call chain to understand what part of an application is responsible for most of the heap allocations. We can also look at different sample types:\n\n* `alloc_objects`— Total number of objects allocated\n* `alloc_space`— Total amount of memory allocated\n* `inuse_object`s — Number of objects allocated and not yet released\n* `inuse_space`— Amount of memory allocated and not yet released\n\nAnother very helpful capability with heap profiling is tracking memory leaks. With a GC-based language, the usual procedure is the following:\n\n1. Trigger a GC.\n2. Download heap data.\n3. Wait for a few seconds/minutes.\n4. Trigger another GC.\n5. Download another heap data.\n6. Compare.\n\nForcing a GC before downloading data is a way to prevent false assumptions. For example, if we see a peak of retained objects without running a GC first, we cannot be sure whether it’s a leak or objects that the next GC will collect.\n\nUsing `pprof`, we can download a heap profile and force a GC in the meantime. The procedure in Go is the following:\n\n1. Go to /debug/pprof/heap?gc=1 (trigger the GC and download the heap profile).\n2. Wait for a few seconds/minutes.\n3. Go to /debug/pprof/heap?gc=1 again.\n4. Use go tool to compare both heap profiles:\n\n```\n$ go tool pprof -http=:8080 -diff_base <file2> <file1>\n```\n\nThe next figure shows the kind of data we can access. For example, the amount of heap memory held by the newTopicProducer method (top left) has decreased (–513 KB). In contrast, the amount held by updateMetadata (bottom right) has increased (+512 KB). Slow increases are normal. The second heap profile may have been calculated in the middle of a service call, for example. We can repeat this process or wait longer; the important part is to track steady increases in allocations of a specific object.\n\n<figure markdown>\n  ![](img/screen-pprof-heap-diff.png)\n  <figcaption>Figure 4: The differences between the two heap profiles.</figcaption>\n</figure>\n\n???+ note\n\n    Another type of profiling related to the heap is `allocs`, which reports allocations. Heap profiling shows the current state of the heap memory. To get insights about past memory allocations since the application started, we can use allocations profiling. As discussed, because stack allocations are cheap, they aren’t part of this profiling, which only focuses on the heap.\n\n### Goroutine Profiling\n\nThe `goroutine` profile reports the stack trace of all the current goroutines in an application. We can download a file using /debug/pprof/goroutine/?debug=0 and use go tool again. The next figure shows the kind of information we can get.\n\n<figure markdown>\n  ![](img/screen-pprof-goroutines.png)\n  <figcaption>Figure 5: Goroutine graph.</figcaption>\n</figure>\n\nWe can see the current state of the application and how many goroutines were created per function. In this case, `withRecover` has created 296 ongoing goroutines (63%), and 29 were related to a call to `responseFeeder`.\n\nThis kind of information is also beneficial if we suspect goroutine leaks. We can look at goroutine profiler data to know which part of a system is the suspect.\n\n### Block Profiling\n\nThe `block` profile reports where ongoing goroutines block waiting on synchronization primitives. Possibilities include\n\n* Sending or receiving on an unbuffered channel\n* Sending to a full channel\n* Receiving from an empty channel\n* Mutex contention\n* Network or filesystem waits\n\nBlock profiling also records the amount of time a goroutine has been waiting and is accessible via /debug/pprof/block. This profile can be extremely helpful if we suspect that performance is being harmed by blocking calls.\n\nThe `block` profile isn’t enabled by default: we have to call `runtime.SetBlockProfileRate` to enable it. This function controls the fraction of goroutine blocking events that are reported. Once enabled, the profiler will keep collecting data in the background even if we don’t call the /debug/pprof/block endpoint. Let’s be cautious if we want to set a high rate so we don’t harm performance.\n\n???+ note\n\n    If we face a deadlock or suspect that goroutines are in a blocked state, the full goroutine stack dump (/debug/pprof/goroutine/?debug=2) creates a dump of all the current goroutine stack traces. This can be helpful as a first analysis step. For example, the following dump shows a Sarama goroutine blocked for 1,420 minutes on a channel-receive operation:\n\n    ```\n    goroutine 2494290 [chan receive, 1420 minutes]:\n    github.com/Shopify/sarama.(*syncProducer).SendMessages(0xc00071a090,\n    [CA]{0xc0009bb800, 0xfb, 0xfb})\n    /app/vendor/github.com/Shopify/sarama/sync_producer.go:117 +0x149\n    ```\n\n### Mutex Profiling\n\nThe last profile type is related to blocking but only regarding mutexes. If we suspect that our application spends significant time waiting for locking mutexes, thus harming execution, we can use mutex profiling. It’s accessible via /debug/pprof/mutex.\n\nThis profile works in a manner similar to that for blocking. It’s disabled by default: we have to enable it using `runtime.SetMutexProfileFraction`, which controls the fraction of mutex contention events reported.\n\nFollowing are a few additional notes about profiling:\n\n* We haven’t mentioned the `threadcreate` profile because it’s been broken since 2013 ([https://github.com/golang/go/issues/6104](https://github.com/golang/go/issues/6104)).\n* Be sure to enable only one profiler at a time: for example, do not enable CPU and heap profiling simultaneously. Doing so can lead to erroneous observations.\n* `pprof` is extensible, and we can create our own custom profiles using `pprof.Profile`.\n\nWe have seen the most important profiles that we can enable to help us understand how an application performs and possible avenues for optimization. In general, enabling `pprof` is recommended, even in production, because in most cases it offers an excellent balance between its footprint and the amount of insight we can get from it. Some profiles, such as the CPU profile, lead to performance penalties but only during the time they are enabled.\n\nLet’s now look at the execution tracer.\n\n## Execution Tracer\n\nThe execution tracer is a tool that captures a wide range of runtime events with `go tool` to make them available for visualization. It is helpful for the following:\n\n* Understanding runtime events such as how the GC performs\n* Understanding how goroutines execute\n* Identifying poorly parallelized execution\n\nLet’s try it with an example given the Concurrency isn’t Always Faster in Go section. We discussed two parallel versions of the merge sort algorithm. The issue with the first version was poor parallelization, leading to the creation of too many goroutines. Let’s see how the tracer can help us in validating this statement.\n\nWe will write a benchmark for the first version and execute it with the -trace flag to enable the execution tracer:\n\n```\n$ go test -bench=. -v -trace=trace.out\n```\n\n???+ note\n\n    We can also download a remote trace file using the /debug/pprof/ trace?debug=0 pprof endpoint.\n\nThis command creates a trace.out file that we can open using go tool:\n\n```\n$ go tool trace trace.out\n2021/11/26 21:36:03 Parsing trace...\n2021/11/26 21:36:31 Splitting trace...\n2021/11/26 21:37:00 Opening browser. Trace viewer is listening on\n    http://127.0.0.1:54518\n```\n\nThe web browser opens, and we can click View Trace to see all the traces during a specific timeframe, as shown in the next figure. This figure represents about 150 ms. We can see multiple helpful metrics, such as the goroutine count and the heap size. The heap size grows steadily until a GC is triggered. We can also observe the activity of the Go application per CPU core. The timeframe starts with user-level code; then a “stop the\nworld” is executed, which occupies the four CPU cores for approximately 40 ms.\n\n<figure markdown>\n  ![](img/tracing.png)\n  <figcaption>Figure 6: Showing goroutine activity and runtime events such as a GC phase.</figcaption>\n</figure>\n\nRegarding concurrency, we can see that this version uses all the available CPU cores on the machine. However, the next figure zooms in on a portion of 1 ms. Each bar corresponds to a single goroutine execution. Having too many small bars doesn’t look right: it means execution that is poorly parallelized.\n\n<figure markdown>\n  ![](img/screen-mergesort1.png)\n  <figcaption>Figure 7: Too many small bars mean poorly parallelized execution.</figcaption>\n</figure>\n\nThe next figure zooms even closer to see how these goroutines are orchestrated. Roughly 50% of the CPU time isn’t spent executing application code. The white spaces represent the time the Go runtime takes to spin up and orchestrate new goroutines.\n\n<figure markdown>\n  ![](img/screen-mergesort11.png)\n  <figcaption>Figure 8: About 50% of CPU time is spent handling goroutine switches.</figcaption>\n</figure>\n\nLet’s compare this with the second parallel implementation, which was about an order of magnitude faster. The next figure again zooms to a 1 ms timeframe.\n\n<figure markdown>\n  ![](img/screen-mergesort2.png)\n  <figcaption>Figure 9: The number of white spaces has been significantly reduced, proving that the CPU is more fully occupied.</figcaption>\n</figure>\n\nEach goroutine takes more time to execute, and the number of white spaces has been significantly reduced. Hence, the CPU is much more occupied executing application code than it was in the first version. Each millisecond of CPU time is spent more efficiently, explaining the benchmark differences.\n\nNote that the granularity of the traces is per goroutine, not per function like CPU profiling. However, it’s possible to define user-level tasks to get insights per function or group of functions using the `runtime/trace` package.\n\nFor example, imagine a function that computes a Fibonacci number and then writes it to a global variable using atomic. We can define two different tasks:\n\n```go\nvar v int64\n// Creates a fibonacci task\nctx, fibTask := trace.NewTask(context.Background(), \"fibonacci\")\ntrace.WithRegion(ctx, \"main\", func() {\n    v = fibonacci(10)\n})\nfibTask.End()\n\n// Creates a store task\nctx, fibStore := trace.NewTask(ctx, \"store\")\ntrace.WithRegion(ctx, \"main\", func() {\n    atomic.StoreInt64(&result, v)\n})\nfibStore.End()\n```\n\nUsing `go tool`, we can get more precise information about how these two tasks perform. In the previous trace UI, we can see the boundaries for each task per goroutine. In User-Defined Tasks, we can follow the duration distribution:\n\n<figure markdown>\n  ![](img/screen-tracing-user-level.png)\n  <figcaption>Figure 10: Distribution of user-level tasks.</figcaption>\n</figure>\n\n\n\nWe see that in most cases, the `fibonacci` task is executed in less than 15 microseconds, whereas the `store` task takes less than 6309 nanoseconds.\n\nIn the previous section, we discussed the kinds of information we can get from CPU profiling. What are the main differences compared to the data we can get from user-level traces?\n\n* CPU profiling:\n    * Sample-based\n    * Per function\n    * Doesn’t go below the sampling rate (10 ms by default)\n* User-level traces:\n    * Not sample-based\n    * Per-goroutine execution (unless we use the `runtime/trace` package)\n    * Time executions aren’t bound by any rate\n    \nIn summary, the execution tracer is a powerful tool for understanding how an application performs. As we have seen with the merge sort example, we can identify poorly parallelized execution. However, the tracer’s granularity remains per goroutine unless we manually use `runtime/trace` compared to a CPU profile, for example. We can use both profiling and the execution tracer to get the most out of the standard Go diagnostics tools when optimizing an application.\n"
  },
  {
    "path": "docs/CNAME",
    "content": "100go.co\n"
  },
  {
    "path": "docs/book.md",
    "content": "---\nhide:\n- toc\n---\n\n# 100 Go Mistakes and How to Avoid Them\n\n![](img/cover.png)\n\n## Description\n\nIf you're a Go developer looking to improve your skills, the _100 Go Mistakes and How to Avoid Them_ book is for you. With a focus on practical examples, this book covers a wide range of topics from concurrency and error handling to testing and code organization. You'll learn to write more idiomatic, efficient, and maintainable code and become a proficient Go developer.\n\nRead a [summary](index.md) of the 100 mistakes or the [first chapter](chapter-1.md).\n\n## Quotes and Ratings\n\n!!! quote \"Krystian (Goodreads user)\"\n\n    This is an **exceptional book**. Usually, if a book contains either high-quality explanations or is written succinctly, I consider myself lucky to have found it. This one combines these two characteristics, which is **super rare**. It's another Go book for me and I still had quite a lot of \"a-ha!\" moments while reading it, and all of that without the unnecessary fluff, just straight to the point.\n\n!!! quote \"Akash Chetty\"\n\n    The book is completely **exceptional**, especially the examples carved out for each topic are really great. There is one topic that I struggled to understand is Concurrency but the way it is explained in this book is truly an art of genius.\n\n!!! quote \"Neeraj Shah\"\n\n    This should be the **required reading** for all Golang developers before they touch code in **Production**... It's the Golang equivalent of the legendary 'Effective Java' by Joshua Bloch.\n\n!!! quote \"Anupam Sengupta\"\n\n    Not having this will be the **101st mistake** a Go programmer could make.\n\n<figure markdown>\n  ![](img/ratings-goodreads.png){width=\"300\"}\n  ![](img/ratings-amazon.png){width=\"300\"}\n  ![](img/ratings-manning.png)\n  <figcaption>Manning, Goodreads, and Amazon reviews: 4.7/5 avg rating</figcaption>\n</figure>\n\n## Where to Buy?\n\n* _100 Go Mistakes and How to Avoid Them_ (🇬🇧 edition: paper, digital, or audiobook)\n\t* [Manning](https://www.manning.com/books/100-go-mistakes-and-how-to-avoid-them) (please make sure to use my personal discount code for -35%: `au35har`)\n\t* [O’Reilly](https://www.oreilly.com/library/view/100-go-mistakes/9781617299599/)\n\t* Amazon: [.com](https://www.amazon.com/dp/1617299596), [.co.uk](https://www.amazon.co.uk/dp/B0BBSNJR6B), [.de](https://www.amazon.de/dp/B0BBHQD8BQ), [.fr](https://www.amazon.fr/100-Mistakes-How-Avoid-Them/dp/1617299596), [.in](https://www.amazon.in/dp/B0BBHQD8BQ), [.co.jp](https://www.amazon.co.jp/dp/B0BBHQD8BQ), [.es](https://www.amazon.es/dp/B0BBHQD8BQ), [.it](https://www.amazon.it/dp/B0BBHQD8BQ), [.com.br](https://www.amazon.com.br/dp/B0BBHQD8BQ)\n\n* _Go言語100Tips 開発者にありがちな間違いへの対処法_ (🇯🇵 edition: paper or digital)\n\t* Amazon: [.co.jp](https://www.amazon.co.jp/exec/obidos/ASIN/4295017531/)\n\n* _100个Go语言典型错误_ (🇨🇳 edition: paper or digital)\n    * [Douban.com](https://read.douban.com/ebook/455919353/)\n    \n* _Go 100가지 실수 패턴과 솔루션_ (🇰🇷 edition: paper or digital)\n    * [Yes24.com](https://m.yes24.com/Goods/Detail/124158773)\n\n<figure markdown>\n  ![](img/cover-en.jpg){width=\"200\"}\n  ![](img/cover-jp.jpg){width=\"200\"}\n  ![](img/cover-cn.jpg){width=\"170\"}\n  ![](img/cover-kr.png){width=\"200\"}\n  <figcaption>Covers (English, Japanese, Chinese, and Korean)</figcaption>\n</figure>\n\n## About the Author\n\n[Teiva Harsanyi](https://teivah.dev) is a senior software engineer at Google. He has worked in various domains, including insurance, transportation, and safety-critical industries like air traffic management. He is passionate about Go and how to design and implement reliable systems.\n"
  },
  {
    "path": "docs/chapter-1.md",
    "content": "---\ntitle: Read the First Chapter\nhide:\n- toc\n---\n\n# Go: Simple to learn but hard to master\n\nThis chapter covers\n\n* What makes Go an efficient, scalable, and productive language\n* Exploring why Go is simple to learn but hard to master\n* Presenting the common types of mistakes made by developers\n\nMaking mistakes is part of everyone’s life. As Albert Einstein once said,\n\n!!! quote \"Albert Einstein\"\n\n    A person who never made a mistake never tried anything new.\n\nWhat matters in the end isn’t the number of mistakes we make, but our capacity to learn from them. This assertion also applies to programming. The seniority we acquire in a language isn’t a magical process; it involves making many mistakes and learning from them. The purpose of this book is centered around this idea. It will help you, the reader, become a more proficient Go developer by looking at and learning from 100 common mistakes people make in many areas of the language.\n\nThis chapter presents a quick refresher as to why Go has become mainstream over the years. We’ll discuss why, despite Go being considered simple to learn, mastering its nuances can be challenging. Finally, we’ll introduce the concepts this book covers.\n\n## Go outline\n\nIf you are reading this book, it’s likely that you’re already sold on Go. Therefore, this section provides a brief reminder about what makes Go such a powerful language.\n\nSoftware engineering has evolved considerably during the past decades. Most modern systems are no longer written by a single person but by teams consisting of multiple programmers—sometimes even hundreds, if not thousands. Nowadays, code must be readable, expressive, and maintainable to guarantee a system’s durability over the years. Meanwhile, in our fast-moving world, maximizing agility and reducing the time to market is critical for most organizations. Programming should also follow this trend, and companies strive to ensure that software engineers are as productive as possible when reading, writing, and maintaining code.\n\nIn response to these challenges, Google created the Go programming language in 2007. Since then, many organizations have adopted the language to support various use cases: APIs, automation, databases, CLIs (command-line interfaces), and so on. Many today consider Go the language of the cloud.\n\nFeature-wise, Go has no type inheritance, no exceptions, no macros, no partial functions, no support for lazy variable evaluation or immutability, no operator overloading, no pattern matching, and on and on. Why are these features missing from the language? The official [Go FAQ](https://go.dev/doc/faq) gives us some insight:\n\n!!! quote \"Go FAQ\"\n\n    Why does Go not have feature X? Your favorite feature may be missing because it doesn’t fit, because it affects compilation speed or clarity of design, or because it would make the fundamental system model too difficult.\n\nJudging the quality of a programming language via its number of features is probably not an accurate metric. At least, it’s not an objective of Go. Instead, Go utilizes a few essential characteristics when adopting a language at scale for an organization. These include the following:\n\n* _Stability_—Even though Go receives frequent updates (including improvements and security patches), it remains a stable language. Some may even consider this one of the best features of the language.\n* _Expressivity_—We can define expressivity in a programming language by how naturally and intuitively we can write and read code. A reduced number of keywords and limited ways to solve common problems make Go an expressive language for large codebases.\n* _Compilation_—As developers, what can be more exasperating than having to wait for a build to test our application? Targeting fast compilation times has always been a conscious goal for the language designers. This, in turn, enables productivity.\n* _Safety_—Go is a strong, statically typed language. Hence, it has strict compiletime rules, which ensure the code is type-safe in most cases.\n\nGo was built from the ground up with solid features such as outstanding concurrency primitives with goroutines and channels. There’s not a strong need to rely on external libraries to build efficient concurrent applications. Observing how important concurrency is these days also demonstrates why Go is such a suitable language for the present and probably for the foreseeable future.\n\nSome also consider Go a simple language. And, in a sense, this isn’t necessarily wrong. For example, a newcomer can learn the language’s main features in less than a day. So why read a book centered on the concept of mistakes if Go is simple?\n\n## Simple doesn’t mean easy\n\nThere is a subtle difference between simple and easy. _Simple_, applied to a technology, means not complicated to learn or understand. However, _easy_ means that we can achieve anything without much effort. Go is simple to learn but not necessarily easy to master.\n\nLet’s take concurrency, for example. In 2019, a study focusing on concurrency bugs was published: [Understanding Real-World Concurrency Bugs in Go](https://songlh.github.io/paper/go-study.pdf). This study was the first systematic analysis of concurrency bugs. It focused on multiple popular Go repositories such as Docker, gRPC, and Kubernetes. One of the most important takeaways from this study is that most of the blocking bugs are caused by inaccurate use of the message-passing paradigm via channels, despite the belief that message passing is easier to handle and less error-prone than sharing memory.\n\nWhat should be an appropriate reaction to such a takeaway? Should we consider that the language designers were wrong about message passing? Should we reconsider how we deal with concurrency in our project? Of course not.\n\nIt’s not a question of confronting message passing versus sharing memory and determining the winner. However, it’s up to us as Go developers to thoroughly understand how to use concurrency, its implications on modern processors, when to favor one approach over the other, and how to avoid common traps. This example highlights that although a concept such as channels and goroutines can be simple to learn, it isn’t an easy topic in practice.\n\nThis leitmotif—simple doesn’t mean easy—can be generalized to many aspects of Go, not only concurrency. Hence, to be proficient Go developers, we must have a thorough understanding of many aspects of the language, which requires time, effort, and mistakes.\n\nThis book aims to help accelerate our journey toward proficiency by delving into 100 Go mistakes.\n\n## 100 Go mistakes\n\nWhy should we read a book about common Go mistakes? Why not deepen our knowledge with an ordinary book that would dig into different topics?\n\nIn a 2011 article, neuroscientists proved that the best time for brain growth is when we’re facing mistakes. [^1] Haven’t we all experienced the process of learning from a mistake and recalling that occasion after months or even years, when some context related to it? As presented in another article, by Janet Metcalfe, this happens because mistakes have a facilitative effect. [^2] The main idea is that we can remember not only the error but also the context surrounding the mistake. This is one of the reasons why learning from mistakes is so efficient.\n\nTo strengthen this facilitative effect, this book accompanies each mistake as much as possible with real-world examples. This book isn’t only about theory; it also helps us get better at avoiding mistakes and making more well-informed, conscious decisions because we now understand the rationale behind them.\n\n!!! quote \"Unknown\"\n\n    Tell me and I forget. Teach me and I remember. Involve me and I learn.\n\nThis book presents seven main categories of mistakes. Overall, the mistakes can be classified as\n\n* Bugs\n* Needless complexity\n* Weaker readability\n* Suboptimal or unidiomatic organization \n* Lack of API convenience\n* Under-optimized code\n* Lack of productivity\n\nWe introduce each mistake category next.\n\n### Bugs\n\nThe first type of mistake and probably the most obvious is software bugs. In 2020, a study conducted by Synopsys estimated the cost of software bugs in the U.S. alone to be over $2 trillion. [^3]\n\nFurthermore, bugs can also lead to tragic impacts. We can, for example, mention cases such as Therac-25, a radiation therapy machine produced by Atomic Energy of Canada Limited (AECL). Because of a race condition, the machine gave its patients radiation doses that were hundreds of times greater than expected, leading to the death of three patients. Hence, software bugs aren’t only about money. As developers, we should remember how impactful our jobs are.\n\nThis book covers plenty of cases that could lead to various software bugs, including data races, leaks, logic errors, and other defects. Although accurate tests should be a way to discover such bugs as early as possible, we may sometimes miss cases because of different factors such as time constraints or complexity. Therefore, as a Go developer, it’s essential to make sure we avoid common bugs.\n\n### Needless complexity\n\nThe next category of mistakes is related to unnecessary complexity. A significant part of software complexity comes from the fact that, as developers, we strive to think about imaginary futures. Instead of solving concrete problems right now, it can be tempting to build evolutionary software that could tackle whatever future use case arises. However, this leads to more drawbacks than benefits in most cases because it can make a codebase more complex to understand and reason about.\n\nGetting back to Go, we can think of plenty of use cases where developers might be tempted to design abstractions for future needs, such as interfaces or generics. This book discusses topics where we should remain careful not to harm a codebase with needless complexity.\n\n### Weaker readability\n\nAnother kind of mistake is to weaken readability. As Robert C. Martin wrote in his book _Clean Code: A Handbook of Agile Software Craftsmanship_, the ratio of time spent reading versus writing is well over 10 to 1. Most of us started to program on solo projects where readability wasn’t that important. However, today’s software engineering is programming with a time dimension: making sure we can still work with and maintain an application months, years, or perhaps even decades later.\n\nWhen programming in Go, we can make many mistakes that can harm readability. These mistakes may include nested code, data type representations, or not using named result parameters in some cases. Throughout this book, we will learn how to write readable code and care for future readers (including our future selves).\n\n### Suboptimal or unidiomatic organization\n\nBe it while working on a new project or because we acquire inaccurate reflexes, another type of mistake is organizing our code and a project suboptimally and unidiomatically. Such issues can make a project harder to reason about and maintain. This book covers some of these common mistakes in Go. For example, we’ll look at how to structure a project and deal with utility packages or init functions. All in all, looking at these mistakes should help us organize our code and projects more efficiently and idiomatically.\n\n### Lack of API convenience\n\nMaking common mistakes that weaken how convenient an API is for our clients is another type of mistake. If an API isn’t user-friendly, it will be less expressive and, hence, harder to understand and more error-prone.\n\nWe can think about many situations such as overusing any types, using the wrong creational pattern to deal with options, or blindly applying standard practices from object-oriented programming that affect the usability of our APIs. This book covers common mistakes that prevent us from exposing convenient APIs for our users.\n\n### Under-optimized code\n\nUnder-optimized code is another type of mistake made by developers. It can happen for various reasons, such as not understanding language features or even a lack of fundamental knowledge. Performance is one of the most obvious impacts of this mistake, but not the only one.\n\nWe can think about optimizing code for other goals, such as accuracy. For example, this book provides some common techniques to ensure that floating-point operations are accurate. Meanwhile, we will cover plenty of cases that can negatively impact performance code because of poorly parallelized executions, not knowing how to reduce allocations, or the impacts of data alignment, for example. We will tackle optimization via different prisms.\n\n### Lack of productivity\n\nIn most cases, what’s the best language we can choose when working on a new project? The one we’re the most productive with. Being comfortable with how a language works and exploiting it to get the best out of it is crucial to reach proficiency.\n\nIn this book, we will cover many cases and concrete examples that will help us to be more productive while working in Go. For instance, we’ll look at writing efficient tests to ensure that our code works, relying on the standard library to be more effective, and getting the best out of the profiling tools and linters. Now, it’s time to delve into those 100 common Go mistakes.\n\n## Summary\n\n* Go is a modern programming language that enables developer productivity, which is crucial for most companies today.\n* Go is simple to learn but not easy to master. This is why we need to deepen our knowledge to make the most effective use of the language.\n* Learning via mistakes and concrete examples is a powerful way to be proficient in a language. This book will accelerate our path to proficiency by exploring 100 common mistakes.\n\n[^1]: J. S. Moser, H. S. Schroder, et al., “Mind Your Errors: Evidence for a Neural Mechanism Linking Growth Mindset to Adaptive Posterror Adjustments,” Psychological Science, vol. 22, no. 12, pp. 1484–1489, Dec. 2011. \n[^2]: J. Metcalfe, “Learning from Errors,” Annual Review of Psychology, vol. 68, pp. 465–489, Jan. 2017.\n[^3]: Synopsys, “The Cost of Poor Software Quality in the US: A 2020 Report.” 2020. [https://news.synopsys.com/2021-01-06-Synopsys-Sponsored-CISQ-Research-Estimates-Cost-of-Poor-Software-Quality-in-the-US-2-08-Trillion-in-2020](https://news.synopsys.com/2021-01-06-Synopsys-Sponsored-CISQ-Research-Estimates-Cost-of-Poor-Software-Quality-in-the-US-2-08-Trillion-in-2020). \n"
  },
  {
    "path": "docs/external.md",
    "content": "# External Resources\n\n## English\n\n### The Best Golang Book | Prime Reacts\n\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/a-lYYYr-5a8?si=hWm7um5GS19KVbog\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n\n### Book Review: 100 Go Mistakes (And How to Avoid Them)\n\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/tcRYU9g5wtw?si=2s10hXwxL7ButfRm\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n\n[Post](https://boldlygo.tech/posts/2023-08-09-review-100-go-mistakes/)\n\n### The Most Useful Book for a Go Programmer?\n\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/8pqgv4_Yjq0?si=CunG1j2Uh2isXm4b\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n\n### How to make mistakes in Go - Go Time #190\n\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/VGOgDqDe30E?si=HErewJsxDjie92AU\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n\n* [Episode](https://changelog.com/gotime/190)\n* [Spotify](https://open.spotify.com/episode/0K1DImrxHCy6E7zVY4AxMZ?si=akroInsPQ1mM5B5V2tHLUw&dl_branch=1)\n\n### Go is AMAZING\n\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/iQBdVqnB0Ss?si=6lX1-oj28s_OZPwp&amp;start=281\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n\n### 8LU - 100% Test Coverage\n\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/V3FBDav6wgQ?si=iA58zxZHQewKF6Jz&amp;start=1210\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n\n### Some Tips I learned from 100 Mistakes in Go\n\n[Post](https://raygervais.dev/articles/2023/04/100_mistakes_in_go/)\n\n### What can be summarized from 100 Go Mistakes?\n\n[Post](https://www.sobyte.net/post/2023-05/summarized-from-100-go-mistakes/)\n\n### Book review: 100 Go Mistakes and How to Avoid Them\n\n[Post](https://schfkt.dev/blog/book-10-go-mistakes/)\n\n## Chinese\n\n### 深度阅读之《100 Go Mistakes and How to Avoid Them\n\n[Post](https://qcrao.com/post/100-go-mistakes-reading-notes/)\n\n### 100 Go Mistakes 随记\n\n[Post](https://zhuanlan.zhihu.com/p/592602656)\n\n### 我为什么放弃Go语言？\n\n[Post](https://juejin.cn/post/7241452578125824061)\n\n## Japanese\n\n### 最近読んだGo言語の本の紹介：100 Go Mistakes and How to Avoid Them\n\n[Post](https://qiita.com/kentaro_suzuki/items/c9c31dc81217f237433c)\n\n### 『100 Go Mistakes and How to Avoid Them』を読む\n\n[Post](https://zenn.dev/yukibobier/books/066f07c8a59fa0)\n\n## Portuguese\n\n### Um ÓTIMO livro para programadores Go\n\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/34XShL_jWD4?si=WQZR3QexpwEZ9-EU\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n"
  },
  {
    "path": "docs/index.md",
    "content": "---\ncomments: true\ndescription: Summary of the mistakes in the 100 Go Mistakes book.\nstatus: new\n---\n\n# Common Go Mistakes\n\n???+ tip \"The Coder Cafe\"\n\n    If you enjoyed my book, you may be interested in my latest project: [The Coder Cafe](https://thecoder.cafe?rd=100go.co), a newsletter for coders.\n\n    > Feeling overwhelmed by the endless stream of tech content? At The Coder Cafe, we serve timeless concepts with your coffee. Written by a Google SWE and published author, we help you grow as an engineer, one coffee at a time.\n\n    <center><a href=\"https://thecoder.cafe?rd=100go.co\"><img src=\"../img/thecodercafe.png\" alt=\"\" style=\"width:480px;height:240px;\"></a></center>\n\nThis page is a summary of the mistakes in the [100 Go Mistakes and How to Avoid Them book](book.md). Meanwhile, it's also open to the community. If you believe that a common Go mistake should be added, please create an [issue](https://github.com/teivah/100-go-mistakes/issues/new?assignees=&labels=community+mistake&template=community_mistake.md&title=).\n\n![](img/inside-cover.png)\n\n???+ warning \"Beta\"\n\n    You're viewing a beta version enriched with significantly more content. However, this version is not yet complete, and I'm looking for volunteers to help me summarize the remaining mistakes ([GitHub issue #43](https://github.com/teivah/100-go-mistakes/issues/43)).\n\n    Progress:\n    <progress value=\"81\" max=\"100\"/>\n\n## Code and Project Organization\n\n### Unintended variable shadowing (#1)\n\n???+ info \"TL;DR\"\n\n    Avoiding shadowed variables can help prevent mistakes like referencing the wrong variable or confusing readers.\n\nVariable shadowing occurs when a variable name is redeclared in an inner block, but this practice is prone to mistakes. Imposing a rule to forbid shadowed variables depends on personal taste. For example, sometimes it can be convenient to reuse an existing variable name like `err` for errors. Yet, in general, we should remain cautious because we now know that we can face a scenario where the code compiles, but the variable that receives the value is not the one expected.\n\n[:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/1-variable-shadowing/main.go)\n\n### Unnecessary nested code (#2)\n\n???+ info \"TL;DR\"\n\n    Avoiding nested levels and keeping the happy path aligned on the left makes building a mental code model easier.\n\nIn general, the more nested levels a function requires, the more complex it is to read and understand. Let’s see some different applications of this rule to optimize our code for readability:\n\n* When an `if` block returns, we should omit the `else` block in all cases. For example, we shouldn’t write:\n\n```go\nif foo() {\n    // ...\n    return true\n} else {\n    // ...\n}\n```\n\nInstead, we omit the `else` block like this:\n\n```go\nif foo() {\n    // ...\n    return true\n}\n// ...\n```\n\n* We can also follow this logic with a non-happy path:\n\n```go\nif s != \"\" {\n    // ...\n} else {\n    return errors.New(\"empty string\")\n}\n```\n\n  Here, an empty `s` represents the non-happy path. Hence, we should flip the\n  condition like so:\n\n```go\nif s == \"\" {\n    return errors.New(\"empty string\")\n}\n// ...\n```\n\nWriting readable code is an important challenge for every developer. Striving to reduce the number of nested blocks, aligning the happy path on the left, and returning as early as possible are concrete means to improve our code’s readability.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/2-nested-code/main.go)\n\n### Misusing init functions (#3)\n\n???+ info \"TL;DR\"\n\n    When initializing variables, remember that init functions have limited error handling and make state handling and testing more complex. In most cases, initializations should be handled as specific functions.\n\nAn init function is a function used to initialize the state of an application. It takes no arguments and returns no result (a `func()` function). When a package is initialized, all the constant and variable declarations in the package are evaluated. Then, the init functions are executed.\n\nInit functions can lead to some issues:\n\n* They can limit error management.\n* They can complicate how to implement tests (for example, an external dependency must be set up, which may not be necessary for the scope of unit tests).\n* If the initialization requires us to set a state, that has to be done through global variables.\n\nWe should be cautious with init functions. They can be helpful in some situations, however, such as defining static configuration. Otherwise, and in most cases, we should handle initializations through ad hoc functions.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/3-init-functions/)\n\n### Overusing getters and setters (#4)\n\n???+ info \"TL;DR\"\n\n    Forcing the use of getters and setters isn’t idiomatic in Go. Being pragmatic and finding the right balance between efficiency and blindly following certain idioms should be the way to go.\n\nData encapsulation refers to hiding the values or state of an object. Getters and setters are means to enable encapsulation by providing exported methods on top of unexported object fields.\n\nIn Go, there is no automatic support for getters and setters as we see in some languages. It is also considered neither mandatory nor idiomatic to use getters and setters to access struct fields. We shouldn’t overwhelm our code with getters and setters on structs if they don’t bring any value. We should be pragmatic and strive to find the right balance between efficiency and following idioms that are sometimes considered indisputable in other programming paradigms.\n\nRemember that Go is a unique language designed for many characteristics, including simplicity. However, if we find a need for getters and setters or, as mentioned, foresee a future need while guaranteeing forward compatibility, there’s nothing wrong with using them.\n\n### Interface pollution (#5)\n\n???+ info \"TL;DR\"\n\n    Abstractions should be discovered, not created. To prevent unnecessary complexity, create an interface when you need it and not when you foresee needing it, or if you can at least prove the abstraction to be a valid one.\n\nRead the full section [here](5-interface-pollution.md).\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/5-interface-pollution/)\n\n### Interface on the producer side (#6)\n\n???+ info \"TL;DR\"\n\n    Keeping interfaces on the client side avoids unnecessary abstractions.\n\nInterfaces are satisfied implicitly in Go, which tends to be a gamechanger compared to languages with an explicit implementation. In most cases, the approach to follow is similar to what we described in the previous section: _abstractions should be discovered, not created_. This means that it’s not up to the producer to force a given abstraction for all the clients. Instead, it’s up to the client to decide whether it needs some form of abstraction and then determine the best abstraction level for its needs.\n\nAn interface should live on the consumer side in most cases. However, in particular contexts (for example, when we know—not foresee—that an abstraction will be helpful for consumers), we may want to have it on the producer side. If we do, we should strive to keep it as minimal as possible, increasing its reusability potential and making it more easily composable.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/6-interface-producer/)\n\n### Returning interfaces (#7)\n\n???+ info \"TL;DR\"\n\n    To prevent being restricted in terms of flexibility, a function shouldn’t return interfaces but concrete implementations in most cases. Conversely, a function should accept interfaces whenever possible.\n\nIn most cases, we shouldn’t return interfaces but concrete implementations. Otherwise, it can make our design more complex due to package dependencies and can restrict flexibility because all the clients would have to rely on the same abstraction. Again, the conclusion is similar to the previous sections: if we know (not foresee) that an abstraction will be helpful for clients, we can consider returning an interface. Otherwise, we shouldn’t force abstractions; they should be discovered by clients. If a client needs to abstract an implementation for whatever reason, it can still do that on the client’s side.\n\n### `any` says nothing (#8)\n\n???+ info \"TL;DR\"\n\n    Only use `any` if you need to accept or return any possible type, such as `json.Marshal`. Otherwise, `any` doesn’t provide meaningful information and can lead to compile-time issues by allowing a caller to call methods with any data type.\n\nThe `any` type can be helpful if there is a genuine need for accepting or returning any possible type (for instance, when it comes to marshaling or formatting). In general, we should avoid overgeneralizing the code we write at all costs. Perhaps a little bit of duplicated code might occasionally be better if it improves other aspects such as code expressiveness.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/8-any/main.go)\n\n### Being confused about when to use generics (#9)\n\n???+ info \"TL;DR\"\n\n    Relying on generics and type parameters can prevent writing boilerplate code to factor out elements or behaviors. However, do not use type parameters prematurely, but only when you see a concrete need for them. Otherwise, they introduce unnecessary abstractions and complexity.\n\nRead the full section [here](9-generics.md).\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/9-generics/main.go)\n\n### Not being aware of the possible problems with type embedding (#10)\n\n???+ info \"TL;DR\"\n\n    Using type embedding can also help avoid boilerplate code; however, ensure that doing so doesn’t lead to visibility issues where some fields should have remained hidden.\n\nWhen creating a struct, Go offers the option to embed types. But this can sometimes lead to unexpected behaviors if we don’t understand all the implications of type embedding. Throughout this section, we look at how to embed types, what these bring, and the possible issues.\n\nIn Go, a struct field is called embedded if it’s declared without a name. For example,\n\n```go\ntype Foo struct {\n    Bar // Embedded field\n}\n\ntype Bar struct {\n    Baz int\n}\n```\n\nIn the `Foo` struct, the `Bar` type is declared without an associated name; hence, it’s an embedded field.\n\nWe use embedding to promote the fields and methods of an embedded type. Because `Bar` contains a `Baz` field, this field is\npromoted to `Foo`. Therefore, `Baz` becomes available from `Foo`.\n\nWhat can we say about type embedding? First, let’s note that it’s rarely a necessity, and it means that whatever the use case, we can probably solve it as well without type embedding. Type embedding is mainly used for convenience: in most cases, to promote behaviors.\n\nIf we decide to use type embedding, we need to keep two main constraints in mind:\n\n* It shouldn’t be used solely as some syntactic sugar to simplify accessing a field (such as `Foo.Baz()` instead of `Foo.Bar.Baz()`). If this is the only rationale, let’s not embed the inner type and use a field instead.\n* It shouldn’t promote data (fields) or a behavior (methods) we want to hide from the outside: for example, if it allows clients to access a locking behavior that should remain private to the struct.\n\nUsing type embedding consciously by keeping these constraints in mind can help avoid boilerplate code with additional forwarding methods. However, let’s make sure we don’t do it solely for cosmetics and not promote elements that should remain hidden.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/10-type-embedding/main.go)\n\n### Not using the functional options pattern (#11)\n\n???+ info \"TL;DR\"\n\n    To handle options conveniently and in an API-friendly manner, use the functional options pattern.\n\nAlthough there are different implementations with minor variations, the main idea is as follows:\n\n* An unexported struct holds the configuration: options.\n* Each option is a function that returns the same type: `type Option func(options *options) error`. For example, `WithPort` accepts an `int` argument that represents the port and returns an `Option` type that represents how to update the `options` struct.\n\n![](img/options.png)\n\n```go\ntype options struct {\n  port *int\n}\n\ntype Option func(options *options) error\n\nfunc WithPort(port int) Option {\n  return func(options *options) error {\n    if port < 0 {\n      return errors.New(\"port should be positive\")\n    }\n    options.port = &port\n    return nil\n  }\n}\n\nfunc NewServer(addr string, opts ...Option) ( *http.Server, error) {\n  var options options\n  for _, opt := range opts {\n    err := opt(&options)\n    if err != nil {\n      return nil, err\n    }\n  }\n\n  // At this stage, the options struct is built and contains the config\n  // Therefore, we can implement our logic related to port configuration\n  var port int\n  if options.port == nil {\n    port = defaultHTTPPort\n  } else {\n    if *options.port == 0 {\n      port = randomPort()\n    } else {\n      port = *options.port\n    }\n  }\n\n  // ...\n}\n```\n\nThe functional options pattern provides a handy and API-friendly way to handle options. Although the builder pattern can be a valid option, it has some minor downsides (having to pass a config struct that can be empty or a less handy way to handle error management) that tend to make the functional options pattern the idiomatic way to deal with these kind of problems in Go.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/11-functional-options/)\n\n### Project misorganization (project structure and package organization) (#12)\n\nRegarding the overall organization, there are different schools of thought. For example, should we organize our application by context or by layer? It depends on our preferences. We may favor grouping code per context (such as the customer context, the contract context, etc.), or we may favor following hexagonal architecture principles and group per technical layer. If the decision we make fits our use case, it cannot be a wrong decision, as long as we remain consistent with it.\n\nRegarding packages, there are multiple best practices that we should follow. First, we should avoid premature packaging because it might cause us to overcomplicate a project. Sometimes, it’s better to use a simple organization and have our project evolve when we understand what it contains rather than forcing ourselves to make the perfect structure up front.\nGranularity is another essential thing to consider. We should avoid having dozens of nano packages containing only one or two files. If we do, it’s because we have probably missed some logical connections across these packages, making our project harder for readers to understand. Conversely, we should also avoid huge packages that dilute the meaning of a package name.\n\nPackage naming should also be considered with care. As we all know (as developers), naming is hard. To help clients understand a Go project, we should name our packages after what they provide, not what they contain. Also, naming should be meaningful. Therefore, a package name should be short, concise, expressive, and, by convention, a single lowercase word.\n\nRegarding what to export, the rule is pretty straightforward. We should minimize what should be exported as much as possible to reduce the coupling between packages and keep unnecessary exported elements hidden. If we are unsure whether to export an element or not, we should default to not exporting it. Later, if we discover that we need to export it, we can adjust our code. Let’s also keep in mind some exceptions, such as making fields exported so that a struct can be unmarshaled with encoding/json.\n\nOrganizing a project isn’t straightforward, but following these rules should help make it easier to maintain. However, remember that consistency is also vital to ease maintainability. Therefore, let’s make sure that we keep things as consistent as possible within a codebase.\n\n???+ note\n\n    In 2023, the Go team has published an official guideline for organizing / structuring a Go project: [go.dev/doc/modules/layout](https://go.dev/doc/modules/layout)\n\n### Creating utility packages (#13)\n\n???+ info \"TL;DR\"\n\n    Naming is a critical piece of application design. Creating packages such as `common`, `util`, and `shared` doesn’t bring much value for the reader. Refactor such packages into meaningful and specific package names.\n\nAlso, bear in mind that naming a package after what it provides and not what it contains can be an efficient way to increase its expressiveness.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/13-utility-packages/stringset.go)\n\n### Ignoring package name collisions (#14)\n\n???+ info \"TL;DR\"\n\n    To avoid naming collisions between variables and packages, leading to confusion or perhaps even bugs, use unique names for each one. If this isn’t feasible, use an import alias to change the qualifier to differentiate the package name from the variable name, or think of a better name.\n\nPackage collisions occur when a variable name collides with an existing package name, preventing the package from being reused. We should prevent variable name collisions to avoid ambiguity. If we face a collision, we should either find another meaningful name or use an import alias.\n\n### Missing code documentation (#15)\n\n???+ info \"TL;DR\"\n\n    To help clients and maintainers understand your code’s purpose, document exported elements.\n\nDocumentation is an important aspect of coding. It simplifies how clients can consume an API but can also help in maintaining a project. In Go, we should follow some rules to make our code idiomatic:\n\nFirst, every exported element must be documented. Whether it is a structure, an interface, a function, or something else, if it’s exported, it must be documented. The convention is to add comments, starting with the name of the exported element.\n\nAs a convention, each comment should be a complete sentence that ends with punctuation. Also bear in mind that when we document a function (or a method), we should highlight what the function intends to do, not how it does it; this belongs to the core of a function and comments, not documentation. Furthermore, the documentation should ideally provide enough information that the consumer does not have to look at our code to understand how to use an exported element.\n\nWhen it comes to documenting a variable or a constant, we might be interested in conveying two aspects: its purpose and its content. The former should live as code documentation to be useful for external clients. The latter, though, shouldn’t necessarily be public.\n\nTo help clients and maintainers understand a package’s scope, we should also document each package. The convention is to start the comment with `// Package` followed by the package name. The first line of a package comment should be concise. That’s because it will appear in the package. Then, we can provide all the information we need in the following lines.\n\nDocumenting our code shouldn’t be a constraint. We should take the opportunity to make sure it helps clients and maintainers to understand the purpose of our code.\n\n### Not using linters (#16)\n\n???+ info \"TL;DR\"\n\n    To improve code quality and consistency, use linters and formatters.\n\nA linter is an automatic tool to analyze code and catch errors. The scope of this section isn’t to give an exhaustive list of the existing linters; otherwise, it will become deprecated pretty quickly. But we should understand and remember why linters are essential for most Go projects.\n\nHowever, if you’re not a regular user of linters, here is a list that you may want to use daily:\n\n* [https://golang.org/cmd/vet](https://golang.org/cmd/vet)—A standard Go analyzer\n* [https://github.com/kisielk/errcheck](https://github.com/kisielk/errcheck)—An error checker\n* [https://github.com/fzipp/gocyclo](https://github.com/fzipp/gocyclo)—A cyclomatic complexity analyzer\n* [https://github.com/jgautheron/goconst](https://github.com/jgautheron/goconst)—A repeated string constants analyzer\n\n\nBesides linters, we should also use code formatters to fix code style. Here is a list of some code formatters for you to try:\n\n* [https://golang.org/cmd/gofmt](https://golang.org/cmd/gofmt)—A standard Go code formatter\n* [https://godoc.org/golang.org/x/tools/cmd/goimports](https://godoc.org/golang.org/x/tools/cmd/goimports)—A standard Go imports formatter\n\n\nMeanwhile, we should also look at golangci-lint ([https://github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint)). It’s a linting tool that provides a facade on top of many useful linters and formatters. Also, it allows running the linters in parallel to improve analysis speed, which is quite handy.\n\nLinters and formatters are a powerful way to improve the quality and consistency of our codebase. Let’s take the time to understand which one we should use and make sure we automate their execution (such as a CI or Git precommit hook).\n\n## Data Types\n\n### Creating confusion with octal literals (#17)\n\n???+ info \"TL;DR\"\n\n    When reading existing code, bear in mind that integer literals starting with `0` are octal numbers. Also, to improve readability, make octal integers explicit by prefixing them with `0o`.\n\nOctal numbers start with a 0 (e.g., `010` is equal to 8 in base 10). To improve readability and avoid potential mistakes for future code readers, we should make octal numbers explicit using the `0o` prefix (e.g., `0o10`).\n\nWe should also note the other integer literal representations:\n\n* _Binary_—Uses a `0b` or `0B` prefix (for example, `0b100` is equal to 4 in base 10)\n* _Hexadecimal_—Uses an `0x` or `0X` prefix (for example, `0xF` is equal to 15 in base 10)\n* _Imaginary_—Uses an `i` suffix (for example, `3i`)\n\nWe can also use an underscore character (_) as a separator for readability. For example, we can write 1 billion this way: `1_000_000_000`. We can also use the underscore character with other representations (for example, `0b00_00_01`).\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/17-octal-literals/main.go)\n\n### Neglecting integer overflows (#18)\n\n???+ info \"TL;DR\"\n\n    Because integer overflows and underflows are handled silently in Go, you can implement your own functions to catch them.\n\nIn Go, an integer overflow that can be detected at compile time generates a compilation error. For example,\n\n```go\nvar counter int32 = math.MaxInt32 + 1\n```\n\n```shell\nconstant 2147483648 overflows int32\n```\n\nHowever, at run time, an integer overflow or underflow is silent; this does not lead to an application panic. It is essential to keep this behavior in mind, because it can lead to sneaky bugs (for example, an integer increment or addition of positive integers that leads to a negative result).\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/18-integer-overflows)\n\n### Not understanding floating-points (#19)\n\n???+ info \"TL;DR\"\n\n    Making floating-point comparisons within a given delta can ensure that your code is portable. When performing addition or subtraction, group the operations with a similar order of magnitude to favor accuracy. Also, perform multiplication and division before addition and subtraction.\n\nIn Go, there are two floating-point types (if we omit imaginary numbers): float32 and float64. The concept of a floating point was invented to solve the major problem with integers: their inability to represent fractional values. To avoid bad surprises, we need to know that floating-point arithmetic is an approximation of real arithmetic.\n\nFor that, we’ll look at a multiplication example:\n\n```go\nvar n float32 = 1.0001\nfmt.Println(n * n)\n```\n\nWe may expect this code to print the result of 1.0001 * 1.0001 = 1.00020001, right? However, running it on most x86 processors prints 1.0002, instead.\n\nBecause Go’s `float32` and `float64` types are approximations, we have to bear a few rules in mind:\n\n* When comparing two floating-point numbers, check that their difference is within an acceptable range.\n* When performing additions or subtractions, group operations with a similar order of magnitude for better accuracy.\n* To favor accuracy, if a sequence of operations requires addition, subtraction, multiplication, or division, perform the multiplication and division operations first.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/19-floating-points/main.go)\n\n### Not understanding slice length and capacity (#20)\n\n???+ info \"TL;DR\"\n\n    Understanding the difference between slice length and capacity should be part of a Go developer’s core knowledge. The slice length is the number of available elements in the slice, whereas the slice capacity is the number of elements in the backing array.\n\nRead the full section [here](20-slice.md).\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/20-slice-length-cap/main.go)\n\n### Inefficient slice initialization (#21)\n\n???+ info \"TL;DR\"\n\n    When creating a slice, initialize it with a given length or capacity if its length is already known. This reduces the number of allocations and improves performance.\n\nWhile initializing a slice using `make`, we can provide a length and an optional capacity. Forgetting to pass an appropriate value for both of these parameters when it makes sense is a widespread mistake. Indeed, it can lead to multiple copies and additional effort for the GC to clean the temporary backing arrays. Performance-wise, there’s no good reason not to give the Go runtime a helping hand.\n\nOur options are to allocate a slice with either a given capacity or a given length. Of these two solutions, we have seen that the second tends to be slightly faster. But using a given capacity and append can be easier to implement and read in some contexts.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/21-slice-init/main.go)\n\n### Being confused about nil vs. empty slice (#22)\n\n???+ info \"TL;DR\"\n\n    To prevent common confusions such as when using the `encoding/json` or the `reflect` package, you need to understand the difference between nil and empty slices. Both are zero-length, zero-capacity slices, but only a nil slice doesn’t require allocation.\n\nIn Go, there is a distinction between nil and empty slices. A nil slice is equals to `nil`, whereas an empty slice has a length of zero. A nil slice is empty, but an empty slice isn’t necessarily `nil`. Meanwhile, a nil slice doesn’t require any allocation. We have seen throughout this section how to initialize a slice depending on the context by using\n\n* `var s []string` if we aren’t sure about the final length and the slice can be empty\n* `[]string(nil)` as syntactic sugar to create a nil and empty slice\n* `make([]string, length)` if the future length is known\n\nThe last option, `[]string{}`, should be avoided if we initialize the slice without elements. Finally, let’s check whether the libraries we use make the distinctions between nil and empty slices to prevent unexpected behaviors.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/22-nil-empty-slice/)\n\n### Not properly checking if a slice is empty (#23)\n\n???+ info \"TL;DR\"\n\n    To check if a slice doesn’t contain any element, check its length. This check works regardless of whether the slice is `nil` or empty. The same goes for maps. To design unambiguous APIs, you shouldn’t distinguish between nil and empty slices.\n\nTo determine whether a slice has elements, we can either do it by checking if the slice is nil or if its length is equal to 0. Checking the length is the best option to follow as it will cover both if the slice is empty or if the slice is nil.\n\nMeanwhile, when designing interfaces, we should avoid distinguishing nil and empty slices, which leads to subtle programming errors. When returning slices, it should make neither a semantic nor a technical difference if we return a nil or empty slice. Both should mean the same thing for the callers. This principle is the same with maps. To check if a map is empty, check its length, not whether it’s nil.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/23-checking-slice-empty/main.go)\n\n### Not making slice copies correctly (#24)\n\n???+ info \"TL;DR\"\n\n    To copy one slice to another using the `copy` built-in function, remember that the number of copied elements corresponds to the minimum between the two slice’s lengths.\n\nCopying elements from one slice to another is a reasonably frequent operation. When using copy, we must recall that the number of elements copied to the destination corresponds to the minimum between the two slices’ lengths. Also bear in mind that other alternatives exist to copy a slice, so we shouldn’t be surprised if we find them in a codebase.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/24-slice-copy/main.go)\n\n### Unexpected side effects using slice append (#25)\n\n???+ info \"TL;DR\"\n\n    Using copy or the full slice expression is a way to prevent `append` from creating conflicts if two different functions use slices backed by the same array. However, only a slice copy prevents memory leaks if you want to shrink a large slice.\n\nWhen using slicing, we must remember that we can face a situation leading to unintended side effects. If the resulting slice has a length smaller than its capacity, append can mutate the original slice. If we want to restrict the range of possible side effects, we can use either a slice copy or the full slice expression, which prevents us from doing a copy.\n\n???+ note\n\n    `s[low:high:max]` (full slice expression): This statement creates a slice similar to the one created with `s[low:high]`, except that the resulting slice’s capacity is equal to `max - low`.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/25-slice-append/main.go)\n\n### Slices and memory leaks (#26)\n\n???+ info \"TL;DR\"\n\n    Working with a slice of pointers or structs with pointer fields, you can avoid memory leaks by marking as nil the elements excluded by a slicing operation.\n\n#### Leaking capacity\n\nRemember that slicing a large slice or array can lead to potential high memory consumption. The remaining space won’t be reclaimed by the GC, and we can keep a large backing array despite using only a few elements. Using a slice copy is the solution to prevent such a case.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/26-slice-memory-leak/capacity-leak)\n\n#### Slice and pointers\n\nWhen we use the slicing operation with pointers or structs with pointer fields, we need to know that the GC won’t reclaim these elements. In that case, the two options are to either perform a copy or explicitly mark the remaining elements or their fields to `nil`.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/26-slice-memory-leak/slice-pointers)\n\n### Inefficient map initialization (#27)\n\n???+ info \"TL;DR\"\n\n    When creating a map, initialize it with a given length if its length is already known. This reduces the number of allocations and improves performance.\n\nA map provides an unordered collection of key-value pairs in which all the keys are distinct. In Go, a map is based on the hash table data structure. Internally, a hash table is an array of buckets, and each bucket is a pointer to an array of key-value pairs.\n\nIf we know up front the number of elements a map will contain, we should create it by providing an initial size. Doing this avoids potential map growth, which is quite heavy computation-wise because it requires reallocating enough space and rebalancing all the elements.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/27-map-init/main_test.go)\n\n### Maps and memory leaks (#28)\n\n???+ info \"TL;DR\"\n\n    A map can always grow in memory, but it never shrinks. Hence, if it leads to some memory issues, you can try different options, such as forcing Go to recreate the map or using pointers.\n\nRead the full section [here](28-maps-memory-leaks.md).\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/28-map-memory-leak/main.go)\n\n### Comparing values incorrectly (#29)\n\n???+ info \"TL;DR\"\n\n    To compare types in Go, you can use the == and != operators if two types are comparable: Booleans, numerals, strings, pointers, channels, and structs are composed entirely of comparable types. Otherwise, you can either use `reflect.DeepEqual` and pay the price of reflection or use custom implementations and libraries.\n\nIt’s essential to understand how to use `==` and `!=` to make comparisons effectively. We can use these operators on operands that are comparable:\n\n* _Booleans_—Compare whether two Booleans are equal.\n* _Numerics (int, float, and complex types)_—Compare whether two numerics are equal.\n* _Strings_—Compare whether two strings are equal.\n* _Channels_—Compare whether two channels were created by the same call to make or if both are nil.\n* _Interfaces_—Compare whether two interfaces have identical dynamic types and equal dynamic values or if both are nil.\n* _Pointers_—Compare whether two pointers point to the same value in memory or if both are nil.\n* _Structs and arrays_—Compare whether they are composed of similar types.\n\n???+ note\n\n    We can also use the `?`, `>=`, `<`, and `>` operators with numeric types to compare values and with strings to compare their lexical order.\n\nIf operands are not comparable (e.g., slices and maps), we have to use other options such as reflection. Reflection is a form of metaprogramming, and it refers to the ability of an application to introspect and modify its structure and behavior. For example, in Go, we can use `reflect.DeepEqual`. This function reports whether two elements are deeply equal by recursively traversing two values. The elements it accepts are basic types plus arrays, structs, slices, maps, pointers, interfaces, and functions. Yet, the main catch is the performance penalty.\n\nIf performance is crucial at run time, implementing our custom method might be the best solution.\nOne additional note: we must remember that the standard library has some existing comparison methods. For example, we can use the optimized `bytes.Compare` function to compare two slices of bytes. Before implementing a custom method, we need to make sure we don’t reinvent the wheel.\n\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/29-comparing-values/main.go)\n\n## Control Structures\n\n### Ignoring that elements are copied in `range` loops (#30)\n\n???+ info \"TL;DR\"\n\n    The value element in a `range` loop is a copy. Therefore, to mutate a struct, for example, access it via its index or via a classic `for` loop (unless the element or the field you want to modify is a pointer).\n\nA range loop allows iterating over different data structures:\n\n* String\n* Array\n* Pointer to an array\n* Slice\n* Map\n* Receiving channel\n\nCompared to a classic for `loop`, a `range` loop is a convenient way to iterate over all the elements of one of these data structures, thanks to its concise syntax.\n\nYet, we should remember that the value element in a range loop is a copy. Therefore, if the value is a struct we need to mutate, we will only update the copy, not the element itself, unless the value or field we modify is a pointer. The favored options are to access the element via the index using a range loop or a classic for loop.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/30-range-loop-element-copied/)\n\n### Ignoring how arguments are evaluated in `range` loops (channels and arrays) (#31)\n\n???+ info \"TL;DR\"\n\n    Understanding that the expression passed to the `range` operator is evaluated only once before the beginning of the loop can help you avoid common mistakes such as inefficient assignment in channel or slice iteration.\n\nThe range loop evaluates the provided expression only once, before the beginning of the loop, by doing a copy (regardless of the type). We should remember this behavior to avoid common mistakes that might, for example, lead us to access the wrong element. For example:\n\n```go\na := [3]int{0, 1, 2}\nfor i, v := range a {\n    a[2] = 10\n    if i == 2 {\n        fmt.Println(v)\n    }\n}\n```\n\nThis code updates the last index to 10. However, if we run this code, it does not print 10; it prints 2.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/31-range-loop-arg-evaluation/)\n\n### :warning: Ignoring the impacts of using pointer elements in `range` loops (#32)\n\n???+ warning\n\n    This mistake isn't relevant anymore from Go 1.22 ([details](https://go.dev/blog/loopvar-preview)).\n\n### Making wrong assumptions during map iterations (ordering and map insert during iteration) (#33)\n\n???+ info \"TL;DR\"\n\n    To ensure predictable outputs when using maps, remember that a map data structure:\n\n* Doesn’t order the data by keys\n* Doesn’t preserve the insertion order\n* Doesn’t have a deterministic iteration order\n* Doesn’t guarantee that an element added during an iteration will be produced during this iteration\n\n<!-- TODO -->\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/33-map-iteration/main.go)\n\n### Ignoring how the `break` statement works (#34)\n\n???+ info \"TL;DR\"\n\n    Using `break` or `continue` with a label enforces breaking a specific statement. This can be helpful with `switch` or `select` statements inside loops.\n\nA break statement is commonly used to terminate the execution of a loop. When loops are used in conjunction with switch or select, developers frequently make the mistake of breaking the wrong statement. For example:\n\n```go\nfor i := 0; i < 5; i++ {\n    fmt.Printf(\"%d \", i)\n\n    switch i {\n    default:\n    case 2:\n        break\n    }\n}\n```\n\nThe break statement doesn’t terminate the `for` loop: it terminates the `switch` statement, instead. Hence, instead of iterating from 0 to 2, this code iterates from 0 to 4: `0 1 2 3 4`.\n\nOne essential rule to keep in mind is that a `break` statement terminates the execution of the innermost `for`, `switch`, or `select` statement. In the previous example, it terminates the `switch` statement.\n\nTo break the loop instead of the `switch` statement, the most idiomatic way is to use a label:\n\n```go hl_lines=\"1 8\"\nloop:\n    for i := 0; i < 5; i++ {\n        fmt.Printf(\"%d \", i)\n\n        switch i {\n        default:\n        case 2:\n            break loop\n        }\n    }\n```\n\nHere, we associate the `loop` label with the `for` loop. Then, because we provide the `loop` label to the `break` statement, it breaks the loop, not the switch. Therefore, this new version will print `0 1 2`, as we expected.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/34-break/main.go)\n\n### Using `defer` inside a loop (#35)\n\n???+ info \"TL;DR\"\n\n    Extracting loop logic inside a function leads to executing a `defer` statement at the end of each iteration.\n\nThe `defer` statement delays a call’s execution until the surrounding function returns. It’s mainly used to reduce boilerplate code. For example, if a resource has to be closed eventually, we can use `defer` to avoid repeating the closure calls before every single `return`.\n\nOne common mistake with `defer` is to forget that it schedules a function call when the _surrounding_ function returns. For example:\n\n```go\nfunc readFiles(ch <-chan string) error {\n    for path := range ch {\n        file, err := os.Open(path)\n        if err != nil {\n            return err\n        }\n\n        defer file.Close()\n\n        // Do something with file\n    }\n    return nil\n}\n```\n\nThe `defer` calls are executed not during each loop iteration but when the `readFiles` function returns. If `readFiles` doesn’t return, the file descriptors will be kept open forever, causing leaks.\n\nOne common option to fix this problem is to create a surrounding function after `defer`, called during each iteration:\n\n```go\nfunc readFiles(ch <-chan string) error {\n    for path := range ch {\n        if err := readFile(path); err != nil {\n            return err\n        }\n    }\n    return nil\n}\n\nfunc readFile(path string) error {\n    file, err := os.Open(path)\n    if err != nil {\n        return err\n    }\n\n    defer file.Close()\n\n    // Do something with file\n    return nil\n}\n```\n\nAnother solution is to make the `readFile` function a closure but intrinsically, this remains the same solution: adding another surrounding function to execute the `defer` calls during each iteration.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/35-defer-loop/main.go)\n\n## Strings\n\n### Not understanding the concept of rune (#36)\n\n???+ info \"TL;DR\"\n\n    Understanding that a rune corresponds to the concept of a Unicode code point and that it can be composed of multiple bytes should be part of the Go developer’s core knowledge to work accurately with strings.\n\nAs runes are everywhere in Go, it's important to understand the following:\n\n* A charset is a set of characters, whereas an encoding describes how to translate a charset into binary.\n* In Go, a string references an immutable slice of arbitrary bytes.\n* Go source code is encoded using UTF-8. Hence, all string literals are UTF-8 strings. But because a string can contain arbitrary bytes, if it’s obtained from somewhere else (not the source code), it isn’t guaranteed to be based on the UTF-8 encoding.\n* A `rune` corresponds to the concept of a Unicode code point, meaning an item represented by a single value.\n* Using UTF-8, a Unicode code point can be encoded into 1 to 4 bytes.\n* Using `len()` on a string in Go returns the number of bytes, not the number of runes.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/36-rune/main.go)\n\n### Inaccurate string iteration (#37)\n\n???+ info \"TL;DR\"\n\n    Iterating on a string with the `range` operator iterates on the runes with the index corresponding to the starting index of the rune’s byte sequence. To access a specific rune index (such as the third rune), convert the string into a `[]rune`.\n\nIterating on a string is a common operation for developers. Perhaps we want to perform an operation for each rune in the string or implement a custom function to search for a specific substring. In both cases, we have to iterate on the different runes of a string. But it’s easy to get confused about how iteration works.\n\nFor example, consider the following example:\n\n```go\ns := \"hêllo\"\nfor i := range s {\n    fmt.Printf(\"position %d: %c\\n\", i, s[i])\n}\nfmt.Printf(\"len=%d\\n\", len(s))\n```\n\n```\nposition 0: h\nposition 1: Ã\nposition 3: l\nposition 4: l\nposition 5: o\nlen=6\n```\n\nLet's highlight three points that might be confusing:\n\n* The second rune is Ã in the output instead of ê.\n* We jumped from position 1 to position 3: what is at position 2?\n* len returns a count of 6, whereas s contains only 5 runes.\n\nLet’s start with the last observation. We already mentioned that len returns the number of bytes in a string, not the number of runes. Because we assigned a string literal to `s`, `s` is a UTF-8 string. Meanwhile, the special character \"ê\" isn’t encoded in a single byte; it requires 2 bytes. Therefore, calling `len(s)` returns 6.\n\nMeanwhile, in the previous example, we have to understand that we don't iterate over each rune; instead, we iterate over each starting index of a rune:\n\n![](img/rune.png)\n\nPrinting `s[i]` doesn’t print the ith rune; it prints the UTF-8 representation of the byte at index `i`. Hence, we printed \"hÃllo\" instead of \"hêllo\".\n\nIf we want to print all the different runes, we can either use the value element of the `range` operator:\n\n```go\ns := \"hêllo\"\nfor i, r := range s {\n    fmt.Printf(\"position %d: %c\\n\", i, r)\n}\n```\n\nOr, we can convert the string into a slice of runes and iterate over it:\n\n```go hl_lines=\"2\"\ns := \"hêllo\"\nrunes := []rune(s)\nfor i, r := range runes {\n    fmt.Printf(\"position %d: %c\\n\", i, r)\n}\n```\n\nNote that this solution introduces a run-time overhead compared to the previous one. Indeed, converting a string into a slice of runes requires allocating an additional slice and converting the bytes into runes: an O(n) time complexity with n the number of bytes in the string. Therefore, if we want to iterate over all the runes, we should use the first solution.\n\nHowever, if we want to access the ith rune of a string with the first option, we don’t have access to the rune index; rather, we know the starting index of a rune in the byte sequence.\n\n```go\ns := \"hêllo\"\nr := []rune(s)[4]\nfmt.Printf(\"%c\\n\", r) // o\n```\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/37-string-iteration/main.go)\n\n### Misusing trim functions (#38)\n\n???+ info \"TL;DR\"\n\n    `strings.TrimRight`/`strings.TrimLeft` removes all the trailing/leading runes contained in a given set, whereas `strings.TrimSuffix`/`strings.TrimPrefix` returns a string without a provided suffix/prefix.\n\nFor example:\n\n```go\nfmt.Println(strings.TrimRight(\"123oxo\", \"xo\"))\n```\n\nThe example prints 123:\n\n![](img/trim.png)\n\nConversely, `strings.TrimLeft` removes all the leading runes contained in a set.\n\nOn the other side, `strings.TrimSuffix` / `strings.TrimPrefix` returns a string without the provided trailing suffix / prefix.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/38-trim/main.go)\n\n### Under-optimized strings concatenation (#39)\n\n???+ info \"TL;DR\"\n\n    Concatenating a list of strings should be done with `strings.Builder` to prevent allocating a new string during each iteration.\n\nLet’s consider a `concat` function that concatenates all the string elements of a slice using the `+=` operator:\n\n```go\nfunc concat(values []string) string {\n    s := \"\"\n    for _, value := range values {\n        s += value\n    }\n    return s\n}\n```\n\nDuring each iteration, the `+=` operator concatenates `s` with the value string. At first sight, this function may not look wrong. But with this implementation, we forget one of the core characteristics of a string: its immutability. Therefore, each iteration doesn’t update `s`; it reallocates a new string in memory, which significantly impacts the performance of this function.\n\nFortunately, there is a solution to deal with this problem, using `strings.Builder`:\n\n```go hl_lines=\"2 4\"\nfunc concat(values []string) string {\n    sb := strings.Builder{}\n    for _, value := range values {\n        _, _ = sb.WriteString(value)\n    }\n    return sb.String()\n}\n```\n\nDuring each iteration, we constructed the resulting string by calling the `WriteString` method that appends the content of value to its internal buffer, hence minimizing memory copying.\n\n???+ note\n\n    `WriteString` returns an error as the second output, but we purposely ignore it. Indeed, this method will never return a non-nil error. So what’s the purpose of this method returning an error as part of its signature? `strings.Builder` implements the `io.StringWriter` interface, which contains a single method: `WriteString(s string) (n int, err error)`. Hence, to comply with this interface, `WriteString` must return an error.\n\nInternally, `strings.Builder` holds a byte slice. Each call to `WriteString` results in a call to append on this slice. There are two impacts. First, this struct shouldn’t be used concurrently, as the calls to `append` would lead to race conditions. The second impact is something that we saw in [mistake #21, \"Inefficient slice initialization\"](#inefficient-slice-initialization-21): if the future length of a slice is already known, we should preallocate it. For that purpose, `strings.Builder` exposes a method `Grow(n int)` to guarantee space for another `n` bytes:\n\n```go\nfunc concat(values []string) string {\n    total := 0\n    for i := 0; i < len(values); i++ {\n        total += len(values[i])\n    }\n\n    sb := strings.Builder{}\n    sb.Grow(total) (2)\n    for _, value := range values {\n        _, _ = sb.WriteString(value)\n    }\n    return sb.String()\n}\n```\n\nLet’s run a benchmark to compare the three versions (v1 using `+=`; v2 using `strings.Builder{}` without preallocation; and v3 using `strings.Builder{}` with preallocation). The input slice contains 1,000 strings, and each string contains 1,000 bytes:\n\n```\nBenchmarkConcatV1-4             16      72291485 ns/op\nBenchmarkConcatV2-4           1188        878962 ns/op\nBenchmarkConcatV3-4           5922        190340 ns/op\n```\n\nAs we can see, the latest version is by far the most efficient: 99% faster than v1 and 78% faster than v2.\n\n`strings.Builder` is the recommended solution to concatenate a list of strings. Usually, this solution should be used within a loop. Indeed, if we just have to concatenate a few strings (such as a name and a surname), using `strings.Builder` is not recommended as doing so will make the code a bit less readable than using the `+=` operator or `fmt.Sprintf`.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/39-string-concat/)\n\n### Useless string conversions (#40)\n\n???+ info \"TL;DR\"\n\n    Remembering that the `bytes` package offers the same operations as the `strings` package can help avoid extra byte/string conversions.\n\nWhen choosing to work with a string or a `[]byte`, most programmers tend to favor strings for convenience. But most I/O is actually done with `[]byte`. For example, `io.Reader`, `io.Writer`, and `io.ReadAll` work with `[]byte`, not strings.\n\nWhen we’re wondering whether we should work with strings or `[]byte`, let’s recall that working with `[]byte` isn’t necessarily less convenient. Indeed, all the exported functions of the strings package also have alternatives in the `bytes` package: `Split`, `Count`, `Contains`, `Index`, and so on. Hence, whether we’re doing I/O or not, we should first check whether we could implement a whole workflow using bytes instead of strings and avoid the price of additional conversions.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/40-string-conversion/main.go)\n\n### Substring and memory leaks (#41)\n\n???+ info \"TL;DR\"\n\n    Using copies instead of substrings can prevent memory leaks, as the string returned by a substring operation will be backed by the same byte array.\n\nIn mistake [#26, “Slices and memory leaks,”](#slice-and-memory-leaks--26-) we saw how slicing a slice or array may lead to memory leak situations. This principle also applies to string and substring operations.\n\nWe need to keep two things in mind while using the substring operation in Go. First, the interval provided is based on the number of bytes, not the number of runes. Second, a substring operation may lead to a memory leak as the resulting substring will share the same backing array as the initial string. The solutions to prevent this case from happening are to perform a string copy manually or to use `strings.Clone` from Go 1.18.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/41-substring-memory-leak/main.go)\n\n## Functions and Methods\n\n### Not knowing which type of receiver to use (#42)\n\n???+ info \"TL;DR\"\n\n    The decision whether to use a value or a pointer receiver should be made based on factors such as the type, whether it has to be mutated, whether it contains a field that can’t be copied, and how large the object is. When in doubt, use a pointer receiver.\n\nChoosing between value and pointer receivers isn’t always straightforward. Let’s discuss some of the conditions to help us choose.\n\nA receiver _must_ be a pointer\n\n* If the method needs to mutate the receiver. This rule is also valid if the receiver is a slice and a method needs to append elements:\n\n  ```go\n  type slice []int\n\n  func (s *slice) add(element int) {\n      *s = append(*s, element)\n  }\n  ```\n\n* If the method receiver contains a field that cannot be copied: for example, a type part of the sync package (see [#74, “Copying a sync type”](#copying-a-sync-type--74-)).\n\nA receiver _should_ be a pointer\n\n* If the receiver is a large object. Using a pointer can make the call more efficient, as doing so prevents making an extensive copy. When in doubt about how large is large, benchmarking can be the solution; it’s pretty much impossible to state a specific size, because it depends on many factors.\n\nA receiver _must_ be a value\n\n* If we have to enforce a receiver’s immutability.\n* If the receiver is a map, function, or channel. Otherwise, a compilation error\n  occurs.\n\nA receiver _should_ be a value\n\n* If the receiver is a slice that doesn’t have to be mutated.\n* If the receiver is a small array or struct that is naturally a value type without mutable fields, such as `time.Time`.\n* If the receiver is a basic type such as `int`, `float64`, or `string`.\n\nOf course, it’s impossible to be exhaustive, as there will always be edge cases, but this section’s goal was to provide guidance to cover most cases. By default, we can choose to go with a value receiver unless there’s a good reason not to do so. In doubt, we should use a pointer receiver.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/42-receiver/)\n\n### Never using named result parameters (#43)\n\n???+ info \"TL;DR\"\n\n    Using named result parameters can be an efficient way to improve the readability of a function/method, especially if multiple result parameters have the same type. In some cases, this approach can also be convenient because named result parameters are initialized to their zero value. But be cautious about potential side effects.\n\nWhen we return parameters in a function or a method, we can attach names to these parameters and use them as regular variables. When a result parameter is named, it’s initialized to its zero value when the function/method begins. With named result parameters, we can also call a naked return statement (without arguments). In that case, the current values of the result parameters are used as the returned values.\n\nHere’s an example that uses a named result parameter `b`:\n\n```go\nfunc f(a int) (b int) {\n    b = a\n    return\n}\n```\n\nIn this example, we attach a name to the result parameter: `b`. When we call return without arguments, it returns the current value of `b`.\n\nIn some cases, named result parameters can also increase readability: for example, if two parameters have the same type. In other cases, they can also be used for convenience. Therefore, we should use named result parameters sparingly when there’s a clear benefit.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/43-named-result-parameters/main.go)\n\n### Unintended side effects with named result parameters (#44)\n\n???+ info \"TL;DR\"\n\n    See [#43](#never-using-named-result-parameters-43).\n\nWe mentioned why named result parameters can be useful in some situations. But as these result parameters are initialized to their zero value, using them can sometimes lead to subtle bugs if we’re not careful enough. For example, can you spot what’s wrong with this code?\n\n```go\nfunc (l loc) getCoordinates(ctx context.Context, address string) (\n    lat, lng float32, err error) {\n    isValid := l.validateAddress(address) (1)\n    if !isValid {\n        return 0, 0, errors.New(\"invalid address\")\n    }\n\n    if ctx.Err() != nil { (2)\n        return 0, 0, err\n    }\n\n    // Get and return coordinates\n}\n```\n\nThe error might not be obvious at first glance. Here, the error returned in the `if ctx.Err() != nil` scope is `err`. But we haven’t assigned any value to the `err` variable. It’s still assigned to the zero value of an `error` type: `nil`. Hence, this code will always return a nil error.\n\n\nWhen using named result parameters, we must recall that each parameter is initialized to its zero value. As we have seen in this section, this can lead to subtle bugs that aren’t always straightforward to spot while reading code. Therefore, let’s remain cautious when using named result parameters, to avoid potential side effects.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/44-side-effects-named-result-parameters/main.go)\n\n### Returning a nil receiver (#45)\n\n???+ info \"TL;DR\"\n\n    When returning an interface, be cautious about not returning a nil pointer but an explicit nil value. Otherwise, unintended consequences may occur and the caller will receive a non-nil value.\n\n<!-- TODO -->\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/45-nil-receiver/main.go)\n\n### Using a filename as a function input (#46)\n\n???+ info \"TL;DR\"\n\n    Designing functions to receive `io.Reader` types instead of filenames improves the reusability of a function and makes testing easier.\n\nAccepting a filename as a function input to read from a file should, in most cases, be considered a code smell (except in specific functions such as `os.Open`). Indeed, it makes unit tests more complex because we may have to create multiple files. It also reduces the reusability of a function (although not all functions are meant to be reused). Using the `io.Reader` interface abstracts the data source. Regardless of whether the input is a file, a string, an HTTP request, or a gRPC request, the implementation can be reused and easily tested.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/46-function-input/)\n\n### Ignoring how `defer` arguments and receivers are evaluated (argument evaluation, pointer, and value receivers) (#47)\n\n???+ info \"TL;DR\"\n\n    Passing a pointer to a `defer` function and wrapping a call inside a closure are two possible solutions to overcome the immediate evaluation of arguments and receivers.\n\nIn a `defer` function the arguments are evaluated right away, not once the surrounding function returns. For example, in this code, we always call `notify` and `incrementCounter` with the same status: an empty string.\n\n```go\nconst (\n    StatusSuccess  = \"success\"\n    StatusErrorFoo = \"error_foo\"\n    StatusErrorBar = \"error_bar\"\n)\n\nfunc f() error {\n    var status string\n    defer notify(status)\n    defer incrementCounter(status)\n\n    if err := foo(); err != nil {\n        status = StatusErrorFoo\n        return err\n    }\n\n    if err := bar(); err != nil {\n        status = StatusErrorBar\n        return err\n    }\n\n    status = StatusSuccess\n    return nil\n}\n```\n\nIndeed, we call `notify(status)` and `incrementCounter(status)` as `defer` functions. Therefore, Go will delay these calls to be executed once `f` returns with the current value of status at the stage we used defer, hence passing an empty string.\n\nTwo leading options if we want to keep using `defer`.\n\nThe first solution is to pass a string pointer:\n\n```go hl_lines=\"3 4\"\nfunc f() error {\n    var status string\n    defer notify(&status) \n    defer incrementCounter(&status)\n\n    // The rest of the function unchanged\n}\n```\n\nUsing `defer` evaluates the arguments right away: here, the address of status. Yes, status itself is modified throughout the function, but its address remains constant, regardless of the assignments. Hence, if `notify` or `incrementCounter` uses the value referenced by the string pointer, it will work as expected. But this solution requires changing the signature of the two functions, which may not always be possible.\n\nThere’s another solution: calling a closure (an anonymous function value that references variables from outside its body) as a `defer` statement:\n\n```go hl_lines=\"3 4 5 6\"\nfunc f() error {\n    var status string\n    defer func() {\n        notify(status)\n        incrementCounter(status)\n    }()\n\n    // The rest of the function unchanged\n}\n```\n\nHere, we wrap the calls to both `notify` and `incrementCounter` within a closure. This closure references the status variable from outside its body. Therefore, `status` is evaluated once the closure is executed, not when we call `defer`. This solution also works and doesn’t require `notify` and `incrementCounter` to change their signature.\n\nLet's also note this behavior applies with method receiver: the receiver is evaluated immediately.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/47-defer-evaluation/)\n\n## Error Management\n\n### Panicking (#48)\n\n???+ info \"TL;DR\"\n\n    Using `panic` is an option to deal with errors in Go. However, it should only be used sparingly in unrecoverable conditions: for example, to signal a programmer error or when you fail to load a mandatory dependency.\n\nIn Go, panic is a built-in function that stops the ordinary flow:\n\n```go\nfunc main() {\n    fmt.Println(\"a\")\n    panic(\"foo\")\n    fmt.Println(\"b\")\n}\n```\n\nThis code prints a and then stops before printing b:\n\n```\na\npanic: foo\n\ngoroutine 1 [running]:\nmain.main()\n        main.go:7 +0xb3\n```\n\nPanicking in Go should be used sparingly. There are two prominent cases, one to signal a programmer error (e.g., [`sql.Register`](https://cs.opensource.google/go/go/+/refs/tags/go1.20.7:src/database/sql/sql.go;l=44) that panics if the driver is `nil` or has already been register) and another where our application fails to create a mandatory dependency. Hence, exceptional conditions that lead us to stop the application. In most other cases, error management should be done with a function that returns a proper error type as the last return argument.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/48-panic/main.go)\n\n### Ignoring when to wrap an error (#49)\n\n???+ info \"TL;DR\"\n\n    Wrapping an error allows you to mark an error and/or provide additional context. However, error wrapping creates potential coupling as it makes the source error available for the caller. If you want to prevent that, don’t use error wrapping.\n\nSince Go 1.13, the %w directive allows us to wrap errors conveniently. Error wrapping is about wrapping or packing an error inside a wrapper container that also makes the source error available. In general, the two main use cases for error wrapping are the following:\n\n* Adding additional context to an error\n* Marking an error as a specific error\n\nWhen handling an error, we can decide to wrap it. Wrapping is about adding additional context to an error and/or marking an error as a specific type. If we need to mark an error, we should create a custom error type. However, if we just want to add extra context, we should use fmt.Errorf with the %w directive as it doesn’t require creating a new error type. Yet, error wrapping creates potential coupling as it makes the source error available for the caller. If we want to prevent it, we shouldn’t use error wrapping but error transformation, for example, using fmt.Errorf with the %v directive.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/49-error-wrapping/main.go)\n\n### Comparing an error type inaccurately (#50)\n\n???+ info \"TL;DR\"\n\n    If you use Go 1.13 error wrapping with the `%w` directive and `fmt.Errorf`, comparing an error against a type has to be done using `errors.As`. Otherwise, if the returned error you want to check is wrapped, it will fail the checks.\n\n<!-- TODO -->\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/50-compare-error-type/main.go)\n\n### Comparing an error value inaccurately (#51)\n\n???+ info \"TL;DR\"\n\n    If you use Go 1.13 error wrapping with the `%w` directive and `fmt.Errorf`, comparing an error against or a value has to be done using `errors.As`. Otherwise, if the returned error you want to check is wrapped, it will fail the checks.\n\nA sentinel error is an error defined as a global variable:\n\n```go\nimport \"errors\"\n\nvar ErrFoo = errors.New(\"foo\")\n```\n\nIn general, the convention is to start with `Err` followed by the error type: here, `ErrFoo`. A sentinel error conveys an _expected_ error, an error that clients will expect to check. As general guidelines:\n\n* Expected errors should be designed as error values (sentinel errors): `var ErrFoo = errors.New(\"foo\")`.\n* Unexpected errors should be designed as error types: `type BarError struct { ... }`, with `BarError` implementing the `error` interface.\n\nIf we use error wrapping in our application with the `%w` directive and `fmt.Errorf`, checking an error against a specific value should be done using `errors.Is` instead of `==`. Thus, even if the sentinel error is wrapped, `errors.Is` can recursively unwrap it and compare each error in the chain against the provided value.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/51-comparing-error-value/main.go)\n\n### Handling an error twice (#52)\n\n???+ info \"TL;DR\"\n\n    In most situations, an error should be handled only once. Logging an error is handling an error. Therefore, you have to choose between logging or returning an error. In many cases, error wrapping is the solution as it allows you to provide additional context to an error and return the source error.\n\nHandling an error multiple times is a mistake made frequently by developers, not specifically in Go. This can cause situations where the same error is logged multiple times make debugging harder.\n\nLet's remind us that handling an error should be done only once. Logging an error is handling an error. Hence, we should either log or return an error. By doing this, we simplify our code and gain better insights into the error situation. Using error wrapping is the most convenient approach as it allows us to propagate the source error and add context to an error.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/52-handling-error-twice/main.go)\n\n### Not handling an error (#53)\n\n???+ info \"TL;DR\"\n\n    Ignoring an error, whether during a function call or in a `defer` function, should be done explicitly using the blank identifier. Otherwise, future readers may be confused about whether it was intentional or a miss.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/53-not-handling-error/main.go)\n\n### Not handling `defer` errors (#54)\n\n???+ info \"TL;DR\"\n\n    In many cases, you shouldn’t ignore an error returned by a `defer` function. Either handle it directly or propagate it to the caller, depending on the context. If you want to ignore it, use the blank identifier.\n\nConsider the following code:\n\n```go\nfunc f() {\n  // ...\n  notify() // Error handling is omitted\n}\n\nfunc notify() error {\n  // ...\n}\n```\n\nFrom a maintainability perspective, the code can lead to some issues. Let’s consider a new reader looking at it. This reader notices that notify returns an error but that the error isn’t handled by the parent function. How can they guess whether or not handling the error was intentional? How can they know whether the previous developer forgot to handle it or did it purposely?\n\nFor these reasons, when we want to ignore an error, there's only one way to do it, using the blank identifier (`_`):\n\n```go\n_ = notify\n```\n\nIn terms of compilation and run time, this approach doesn’t change anything compared to the first piece of code. But this new version makes explicit that we aren’t interested in the error. Also, we can add a comment that indicates the rationale for why an error is ignored:\n\n```go\n// At-most once delivery.\n// Hence, it's accepted to miss some of them in case of errors.\n_ = notify()\n```\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/54-defer-errors/main.go)\n\n## Concurrency: Foundations\n\n### Mixing up concurrency and parallelism (#55)\n\n???+ info \"TL;DR\"\n\n    Understanding the fundamental differences between concurrency and parallelism is a cornerstone of the Go developer’s knowledge. Concurrency is about structure, whereas parallelism is about execution.\n\nConcurrency and parallelism are not the same:\n\n* Concurrency is about structure. We can change a sequential implementation into a concurrent one by introducing different steps that separate concurrent goroutines can tackle.\n* Meanwhile, parallelism is about execution. We can use parallism at the steps level by adding more parallel goroutines.\n\nIn summary, concurrency provides a structure to solve a problem with parts that may be parallelized. Therefore, _concurrency enables parallelism_.\n\n<!-- TODO Include Rob Pike's talk link-->\n\n### Thinking concurrency is always faster (#56)\n\n???+ info \"TL;DR\"\n\n    To be a proficient developer, you must acknowledge that concurrency isn’t always faster. Solutions involving parallelization of minimal workloads may not necessarily be faster than a sequential implementation. Benchmarking sequential versus concurrent solutions should be the way to validate assumptions.\n\nRead the full section [here](56-concurrency-faster.md).\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/56-faster/)\n\n### Being puzzled about when to use channels or mutexes (#57)\n\n???+ info \"TL;DR\"\n\n    Being aware of goroutine interactions can also be helpful when deciding between channels and mutexes. In general, parallel goroutines require synchronization and hence mutexes. Conversely, concurrent goroutines generally require coordination and orchestration and hence channels.\n\nGiven a concurrency problem, it may not always be clear whether we can implement a\nsolution using channels or mutexes. Because Go promotes sharing memory by communication, one mistake could be to always force the use of channels, regardless of\nthe use case. However, we should see the two options as complementary. \n\nWhen should we use channels or mutexes? We will use the example in the next figure as a backbone. Our example has three different goroutines with specific relationships:\n\n* G1 and G2 are parallel goroutines. They may be two goroutines executing the same function that keeps receiving messages from a channel, or perhaps two goroutines executing the same HTTP handler at the same time.\n* On the other hand, G1 and G3 are concurrent goroutines, as are G2 and G3. All the goroutines are part of an overall concurrent structure, but G1 and G2 perform the first step, whereas G3 does the next step.\n\n<!-- TODO Include figure-->\n\nIn general, parallel goroutines have to _synchronize_: for example, when they need to access or mutate a shared resource such as a slice. Synchronization is enforced with mutexes but not with any channel types (not with buffered channels). Hence, in general, synchronization between parallel goroutines should be achieved via mutexes.\n\nConversely, in general, concurrent goroutines have to _coordinate and orchestrate_. For example, if G3 needs to aggregate results from both G1 and G2, G1 and G2 need to signal to G3 that a new intermediate result is available. This coordination falls under the scope of communication—therefore, channels.\n\nRegarding concurrent goroutines, there’s also the case where we want to transfer the ownership of a resource from one step (G1 and G2) to another (G3); for example, if G1 and G2 are enriching a shared resource and at some point, we consider this job as complete. Here, we should use channels to signal that a specific resource is ready and handle the ownership transfer.\n\nMutexes and channels have different semantics. Whenever we want to share a state or access a shared resource, mutexes ensure exclusive access to this resource. Conversely, channels are a mechanic for signaling with or without data (`chan struct{}` or not). Coordination or ownership transfer should be achieved via channels. It’s important to know whether goroutines are parallel or concurrent because, in general, we need mutexes for parallel goroutines and channels for concurrent ones.\n\n### Not understanding race problems (data races vs. race conditions and the Go memory model) (#58)\n\n???+ info \"TL;DR\"\n\n    Being proficient in concurrency also means understanding that data races and race conditions are different concepts. Data races occur when multiple goroutines simultaneously access the same memory location and at least one of them is writing. Meanwhile, being data-race-free doesn’t necessarily mean deterministic execution. When a behavior depends on the sequence or the timing of events that can’t be controlled, this is a race condition.\n\nRace problems can be among the hardest and most insidious bugs a programmer can face. As Go developers, we must understand crucial aspects such as data races and race conditions, their possible impacts, and how to avoid them.\n\n#### Data Race\n\nA data race occurs when two or more goroutines simultaneously access the same memory location and at least one is writing. In this case, the result can be hazardous. Even worse, in some situations, the memory location may end up holding a value containing a meaningless combination of bits.\n\nWe can prevent a data race from happening using different techniques. For example: \n\n* Using the `sync/atomic` package\n* In synchronizing the two goroutines with an ad hoc data structure like a mutex\n* Using channels to make the two goroutines communicating to ensure that a variable is updated by only one goroutine at a time\n\n#### Race Condition\n\nDepending on the operation we want to perform, does a data-race-free application necessarily mean a deterministic result? Not necessarily.\n\nA race condition occurs when the behavior depends on the sequence or the timing of events that can’t be controlled. Here, the timing of events is the goroutines’ execution order.\n\nIn summary, when we work in concurrent applications, it’s essential to understand that a data race is different from a race condition. A data race occurs when multiple goroutines simultaneously access the same memory location and at least one of them is writing. A data race means unexpected behavior. However, a data-race-free application doesn’t necessarily mean deterministic results. An application can be free of data races but still have behavior that depends on uncontrolled events (such as goroutine execution, how fast a message is published to a channel, or how long a call to a database lasts); this is a race condition. Understanding both concepts is crucial to becoming proficient in designing concurrent applications.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/58-races/)\n\n### Not understanding the concurrency impacts of a workload type (#59)\n\n???+ info \"TL;DR\"\n\n    When creating a certain number of goroutines, consider the workload type. Creating CPU-bound goroutines means bounding this number close to the GOMAXPROCS variable (based by default on the number of CPU cores on the host). Creating I/O-bound goroutines depends on other factors, such as the external system.\n\nIn programming, the execution time of a workload is limited by one of the following:\n\n* The speed of the CPU—For example, running a merge sort algorithm. The workload is called CPU-bound.\n* The speed of I/O—For example, making a REST call or a database query. The workload is called I/O-bound.\n* The amount of available memory—The workload is called memory-bound.\n\n???+ note\n\n    The last is the rarest nowadays, given that memory has become very cheap in recent decades. Hence, this section focuses on the two first workload types: CPU- and I/O-bound.\n\nIf the workload executed by the workers is I/O-bound, the value mainly depends on the external system. Conversely, if the workload is CPU-bound, the optimal number of goroutines is close to the number of available CPU cores (a best practice can be to use `runtime.GOMAXPROCS`). Knowing the workload type (I/O or CPU) is crucial when designing concurrent applications.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/59-workload-type/main.go)\n\n### Misunderstanding Go contexts (#60)\n\n???+ info \"TL;DR\"\n\n    Go contexts are also one of the cornerstones of concurrency in Go. A context allows you to carry a deadline, a cancellation signal, and/or a list of keys-values.\n\n!!! quote \"https://pkg.go.dev/context\"\n\n    A Context carries a deadline, a cancellation signal, and other values across API boundaries.\n\n#### Deadline\n\nA deadline refers to a specific point in time determined with one of the following:\n\n* A `time.Duration` from now (for example, in 250 ms)\n* A `time.Time` (for example, 2023-02-07 00:00:00 UTC)\n\nThe semantics of a deadline convey that an ongoing activity should be stopped if this deadline is met. An activity is, for example, an I/O request or a goroutine waiting to receive a message from a channel.\n\n#### Cancellation signals\n\nAnother use case for Go contexts is to carry a cancellation signal. Let’s imagine that we want to create an application that calls `CreateFileWatcher(ctx context.Context, filename string)` within another goroutine. This function creates a specific file watcher that keeps reading from a file and catches updates. When the provided context expires or is canceled, this function handles it to close the file descriptor.\n\n#### Context values\n\nThe last use case for Go contexts is to carry a key-value list. What’s the point of having a context carrying a key-value list? Because Go contexts are generic and mainstream, there are infinite use cases.\n\nFor example, if we use tracing, we may want different subfunctions to share the same correlation ID. Some developers may consider this ID too invasive to be part of the function signature. In this regard, we could also decide to include it as part of the provided context.\n\n#### Catching a context cancellation\n\nThe `context.Context` type exports a `Done` method that returns a receive-only notification channel: `<-chan struct{}`. This channel is closed when the work associated with the context should be canceled. For example,\n\n* The Done channel related to a context created with `context.WithCancel` is closed when the cancel function is called.\n* The Done channel related to a context created with `context.WithDeadline` is closed when the deadline has expired.\n\nOne thing to note is that the internal channel should be closed when a context is canceled or has met a deadline, instead of when it receives a specific value, because the closure of a channel is the only channel action that all the consumer goroutines will receive. This way, all the consumers will be notified once a context is canceled or a deadline is reached.\n\nIn summary, to be a proficient Go developer, we have to understand what a context is and how to use it. In general, a function that users wait for should take a context, as doing so allows upstream callers to decide when calling this function should be aborted. \n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/60-contexts/main.go)\n\n## Concurrency: Practice\n\n### Propagating an inappropriate context (#61)\n\n???+ info \"TL;DR\"\n\n    Understanding the conditions when a context can be canceled should matter when propagating it: for example, an HTTP handler canceling the context when the response has been sent.\n\nIn many situations, it is recommended to propagate Go contexts. However, context propagation can sometimes lead to subtle bugs, preventing subfunctions from being correctly executed.\n\nLet’s consider the following example. We expose an HTTP handler that performs some tasks and returns a response. But just before returning the response, we also want to send it to a Kafka topic. We don’t want to penalize the HTTP consumer latency-wise, so we want the publish action to be handled asynchronously within a new goroutine. We assume that we have at our disposal a `publish` function that accepts a context so the action of publishing a message can be interrupted if the context is canceled, for example. Here is a possible implementation:\n\n```go\nfunc handler(w http.ResponseWriter, r *http.Request) {\n    response, err := doSomeTask(r.Context(), r)\n    if err != nil {\n        http.Error(w, err.Error(), http.StatusInternalServerError)\n    return\n    }\n    go func() {\n        err := publish(r.Context(), response)\n        // Do something with err\n    }()\n    writeResponse(response)\n}\n```\n\nWhat’s wrong with this piece of code? We have to know that the context attached to an HTTP request can cancel in different conditions:\n\n* When the client’s connection closes\n* In the case of an HTTP/2 request, when the request is canceled\n* When the response has been written back to the client\n\nIn the first two cases, we probably handle things correctly. For example, if we get a response from doSomeTask but the client has closed the connection, it’s probably OK to call publish with a context already canceled so the message isn’t published. But what about the last case?\n\nWhen the response has been written to the client, the context associated with the request will be canceled. Therefore, we are facing a race condition:\n\n* If the response is written after the Kafka publication, we both return a response and publish a message successfully\n* However, if the response is written before or during the Kafka publication, the message shouldn’t be published.\n\nIn the latter case, calling publish will return an error because we returned the HTTP response quickly.\n\n???+ note\n\n    From Go 1.21, there is a way to create a new context without cancel. [`context.WithoutCancel`](https://pkg.go.dev/context#WithoutCancel) returns a copy of parent that is not canceled when parent is canceled.\n\nIn summary, propagating a context should be done cautiously.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/61-inappropriate-context/main.go)\n\n### Starting a goroutine without knowing when to stop it (#62)\n\n???+ info \"TL;DR\"\n\n    Avoiding leaks means being mindful that whenever a goroutine is started, you should have a plan to stop it eventually.\n\nGoroutines are easy and cheap to start—so easy and cheap that we may not necessarily have a plan for when to stop a new goroutine, which can lead to leaks. Not knowing when to stop a goroutine is a design issue and a common concurrency mistake in Go.\n\nLet’s discuss a concrete example. We will design an application that needs to watch some external configuration (for example, using a database connection). Here’s a first implementation:\n\n```go\nfunc main() {\n    newWatcher()\n    // Run the application\n}\n\ntype watcher struct { /* Some resources */ }\n\nfunc newWatcher() {\n    w := watcher{}\n    go w.watch() // Creates a goroutine that watches some external configuration\n}\n```\n\nThe problem with this code is that when the main goroutine exits (perhaps because of an OS signal or because it has a finite workload), the application is stopped. Hence, the resources created by watcher aren’t closed gracefully. How can we prevent this from happening?\n\nOne option could be to pass to newWatcher a context that will be canceled when main returns:\n\n```go\nfunc main() {\n    ctx, cancel := context.WithCancel(context.Background())\n    defer cancel()\n    newWatcher(ctx)\n    // Run the application\n}\n\nfunc newWatcher(ctx context.Context) {\n    w := watcher{}\n    go w.watch(ctx)\n}\n```\n\nWe propagate the context created to the watch method. When the context is canceled, the watcher struct should close its resources. However, can we guarantee that watch will have time to do so? Absolutely not—and that’s a design flaw.\n\n The problem is that we used signaling to convey that a goroutine had to be stopped. We didn’t block the parent goroutine until the resources had been closed.  Let’s make sure we do:\n\n```go\nfunc main() {\n    w := newWatcher()\n    defer w.close()\n    // Run the application\n}\n\nfunc newWatcher() watcher {\n    w := watcher{}\n    go w.watch()\n    return w\n}\n\nfunc (w watcher) close() {\n    // Close the resources\n}\n```\n\nInstead of signaling `watcher` that it’s time to close its resources, we now call this `close` method, using `defer` to guarantee that the resources are closed before the application exits.\n\nIn summary, let’s be mindful that a goroutine is a resource like any other that must eventually be closed to free memory or other resources. Starting a goroutine without knowing when to stop it is a design issue. Whenever a goroutine is started, we should have a clear plan about when it will stop. Last but not least, if a goroutine creates resources and its lifetime is bound to the lifetime of the application, it’s probably safer to wait for this goroutine to complete before exiting the application. This way, we can ensure that the resources can be freed.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/62-starting-goroutine/)\n\n### :warning: Not being careful with goroutines and loop variables (#63)\n\n???+ warning\n\n    This mistake isn't relevant anymore from Go 1.22 ([details](https://go.dev/blog/loopvar-preview)).\n\n### Expecting a deterministic behavior using select and channels (#64)\n\n???+ info \"TL;DR\"\n\n    Understanding that `select` with multiple channels chooses the case randomly if multiple options are possible prevents making wrong assumptions that can lead to subtle concurrency bugs.\n\nOne common mistake made by Go developers while working with channels is to make wrong assumptions about how select behaves with multiple channels.\n\nFor example, let's consider the following case (`disconnectCh` is a unbuffered channel):\n\n```go\ngo func() {\n  for i := 0; i < 10; i++ {\n      messageCh <- i\n    }\n    disconnectCh <- struct{}{}\n}()\n\nfor {\n    select {\n    case v := <-messageCh:\n        fmt.Println(v)\n    case <-disconnectCh:\n        fmt.Println(\"disconnection, return\")\n        return\n    }\n}\n```\n\nIf we run this example multiple times, the result will be random:\n\n```\n0\n1\n2\ndisconnection, return\n\n0\ndisconnection, return\n```\n\nInstead of consuming the 10 messages, we only received a few of them. What’s the reason? It lies in the specification of the select statement with multiple channels (https:// go.dev/ref/spec):\n\n!!! quote \n\n    If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection.\n\nUnlike a switch statement, where the first case with a match wins, the select statement selects randomly if multiple options are possible.\n\nThis behavior might look odd at first, but there’s a good reason for it: to prevent possible starvation. Suppose the first possible communication chosen is based on the source order. In that case, we may fall into a situation where, for example, we only receive from one channel because of a fast sender. To prevent this, the language designers decided to use a random selection.\n\nWhen using `select` with multiple channels, we must remember that if multiple options are possible, the first case in the source order does not automatically win. Instead, Go selects randomly, so there’s no guarantee about which option will be chosen. To overcome this behavior, in the case of a single producer goroutine, we can use either unbuffered channels or a single channel.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/64-select-behavior/main.go)\n\n### Not using notification channels (#65)\n\n???+ info \"TL;DR\"\n\n    Send notifications using a `chan struct{}` type.\n\nChannels are a mechanism for communicating across goroutines via signaling. A signal can be either with or without data.\n\nLet’s look at a concrete example. We will create a channel that will notify us whenever a certain disconnection occurs. One idea is to handle it as a `chan bool`:\n\n```go\ndisconnectCh := make(chan bool)\n```\n\nNow, let’s say we interact with an API that provides us with such a channel. Because it’s a channel of Booleans, we can receive either `true` or `false` messages. It’s probably clear what `true` conveys. But what does `false` mean? Does it mean we haven’t been disconnected? And in this case, how frequently will we receive such a signal? Does it mean we have reconnected? Should we even expect to receive `false`? Perhaps we should only expect to receive `true` messages.\n\nIf that’s the case, meaning we don’t need a specific value to convey some information, we need a channel _without_ data. The idiomatic way to handle it is a channel of empty structs: `chan struct{}`.\n\n### Not using nil channels (#66)\n\n???+ info \"TL;DR\"\n\n    Using nil channels should be part of your concurrency toolset because it allows you to _remove_ cases from `select` statements, for example.\n\nWhat should this code do?\n\n```go\nvar ch chan int\n<-ch\n```\n\n`ch` is a `chan int` type. The zero value of a channel being nil, `ch` is `nil`. The goroutine won’t panic; however, it will block forever.\n\nThe principle is the same if we send a message to a nil channel. This goroutine blocks forever:\n\n```go\nvar ch chan int\nch <- 0\n```\n\nThen what’s the purpose of Go allowing messages to be received from or sent to a nil channel? For example, we can use nil channels to implement an idiomatic way to merge two channels:\n\n```go hl_lines=\"5 9 15\"\nfunc merge(ch1, ch2 <-chan int) <-chan int {\n    ch := make(chan int, 1)\n\n    go func() {\n        for ch1 != nil || ch2 != nil { // Continue if at least one channel isn’t nil\n            select {\n            case v, open := <-ch1:\n                if !open {\n                    ch1 = nil // Assign ch1 to a nil channel once closed\n                    break\n                }\n                ch <- v\n            case v, open := <-ch2:\n                if !open {\n                    ch2 = nil // Assigns ch2 to a nil channel once closed\n                    break\n                }\n                ch <- v\n            }\n        }\n        close(ch)\n    }()\n\n    return ch\n}\n```\n\nThis elegant solution relies on nil channels to somehow _remove_ one case from the `select` statement.\n\nLet’s keep this idea in mind: nil channels are useful in some conditions and should be part of the Go developer’s toolset when dealing with concurrent code.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/66-nil-channels/main.go)\n\n### Being puzzled about channel size (#67)\n\n???+ info \"TL;DR\"\n\n    Carefully decide on the right channel type to use, given a problem. Only unbuffered channels provide strong synchronization guarantees. For buffered channels, you should have a good reason to specify a channel size other than one.\n\nAn unbuffered channel is a channel without any capacity. It can be created by either omitting the size or providing a 0 size:\n\n```go\nch1 := make(chan int)\nch2 := make(chan int, 0)\n```\n\nWith an unbuffered channel (sometimes called a synchronous channel), the sender will block until the receiver receives data from the channel.\n\nConversely, a buffered channel has a capacity, and it must be created with a size greater than or equal to 1:\n\n```go\nch3 := make(chan int, 1)\n```\n\nWith a buffered channel, a sender can send messages while the channel isn’t full. Once the channel is full, it will block until a receiver goroutine receives a message:\n\n```go\nch3 := make(chan int, 1)\nch3 <-1 // Non-blocking\nch3 <-2 // Blocking\n```\n\nThe first send isn’t blocking, whereas the second one is, as the channel is full at this stage.\n\nWhat's the main difference between unbuffered and buffered channels:\n\n* An unbuffered channel enables synchronization. We have the guarantee that two goroutines will be in a known state: one receiving and another sending a message.\n* A buffered channel doesn’t provide any strong synchronization. Indeed, a producer goroutine can send a message and then continue its execution if the channel isn’t full. The only guarantee is that a goroutine won’t receive a message before it is sent. But this is only a guarantee because of causality (you don’t drink your coffee before you prepare it).\n\nIf we need a buffered channel, what size should we provide?\n\nThe default value we should use for buffered channels is its minimum: 1. So, we may approach the problem from this standpoint: is there any good reason not to use a value of 1? Here’s a list of possible cases where we should use another size:\n\n* While using a worker pooling-like pattern, meaning spinning a fixed number of goroutines that need to send data to a shared channel. In that case, we can tie the channel size to the number of goroutines created.\n* When using channels for rate-limiting problems. For example, if we need to enforce resource utilization by bounding the number of requests, we should set up the channel size according to the limit.\n\nIf we are outside of these cases, using a different channel size should be done cautiously. Let’s bear in mind that deciding about an accurate queue size isn’t an easy problem:\n\n!!! quote \"Martin Thompson\"\n\n    Queues are typically always close to full or close to empty due to the differences in pace between consumers and producers. They very rarely operate in a balanced middle ground where the rate of production and consumption is evenly matched.\n\n### Forgetting about possible side effects with string formatting (#68)\n\n???+ info \"TL;DR\"\n\n    Being aware that string formatting may lead to calling existing functions means watching out for possible deadlocks and other data races.\n\nIt’s pretty easy to forget the potential side effects of string formatting while working in a concurrent application.\n\n#### [etcd](https://github.com/etcd-io/etcd) data race\n\n[github.com/etcd-io/etcd/pull/7816](https://github.com/etcd-io/etcd/pull/7816) shows an example of an issue where a map's key was formatted based on a mutable values from a context.\n\n#### Deadlock\n\nCan you see what the problem is in this code with a `Customer` struct exposing an `UpdateAge` method and implementing the `fmt.Stringer` interface?\n\n```go\ntype Customer struct {\n    mutex sync.RWMutex // Uses a sync.RWMutex to protect concurrent accesses\n    id    string\n    age   int\n}\n\nfunc (c *Customer) UpdateAge(age int) error {\n    c.mutex.Lock() // Locks and defers unlock as we update Customer\n    defer c.mutex.Unlock()\n\n    if age < 0 { // Returns an error if age is negative\n        return fmt.Errorf(\"age should be positive for customer %v\", c)\n    }\n\n    c.age = age\n    return nil\n}\n\nfunc (c *Customer) String() string {\n    c.mutex.RLock() // Locks and defers unlock as we read Customer\n    defer c.mutex.RUnlock()\n    return fmt.Sprintf(\"id %s, age %d\", c.id, c.age)\n}\n```\n\nThe problem here may not be straightforward. If the provided age is negative, we return an error. Because the error is formatted, using the `%s` directive on the receiver, it will call the `String` method to format `Customer`. But because `UpdateAge` already acquires the mutex lock, the `String` method won’t be able to acquire it. Hence, this leads to a deadlock situation. If all goroutines are also asleep, it leads to a panic.\n\nOne possible solution is to restrict the scope of the mutex lock:\n\n```go hl_lines=\"2 3 4\"\nfunc (c *Customer) UpdateAge(age int) error {\n    if age < 0 {\n        return fmt.Errorf(\"age should be positive for customer %v\", c)\n    }\n\n    c.mutex.Lock()\n    defer c.mutex.Unlock()\n\n    c.age = age\n    return nil\n}\n```\n\nYet, such an approach isn't always possible. In these conditions, we have to be extremely careful with string formatting.\n\nAnother approach is to access the `id` field directly:\n\n```go hl_lines=\"6\"\nfunc (c *Customer) UpdateAge(age int) error {\n    c.mutex.Lock()\n    defer c.mutex.Unlock()\n\n    if age < 0 {\n        return fmt.Errorf(\"age should be positive for customer id %s\", c.id)\n    }\n\n    c.age = age\n    return nil\n}\n```\n\nIn concurrent applications, we should remain cautious about the possible side effects of string formatting.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/68-string-formatting/main.go)\n\n### Creating data races with append (#69)\n\n???+ info \"TL;DR\"\n\n    Calling `append` isn’t always data-race-free; hence, it shouldn’t be used concurrently on a shared slice.\n\nShould adding an element to a slice using `append` is data-race-free? Spoiler: it depends.\n\nDo you believe this example has a data race? \n\n```go\ns := make([]int, 1)\n\ngo func() { // In a new goroutine, appends a new element on s\n    s1 := append(s, 1)\n    fmt.Println(s1)\n}()\n\ngo func() { // Same\n    s2 := append(s, 1)\n    fmt.Println(s2)\n}()\n```\n\nThe answer is no.\n\nIn this example, we create a slice with `make([]int, 1)`. The code creates a one-length, one-capacity slice. Thus, because the slice is full, using append in each goroutine returns a slice backed by a new array. It doesn’t mutate the existing array; hence, it doesn’t lead to a data race.\n\nNow, let’s run the same example with a slight change in how we initialize `s`. Instead of creating a slice with a length of 1, we create it with a length of 0 but a capacity of 1. How about this new example? Does it contain a data race?\n\n```go hl_lines=\"1\"\ns := make([]int, 0, 1)\n\ngo func() { \n    s1 := append(s, 1)\n    fmt.Println(s1)\n}()\n\ngo func() {\n    s2 := append(s, 1)\n    fmt.Println(s2)\n}()\n```\n\nThe answer is yes. We create a slice with `make([]int, 0, 1)`. Therefore, the array isn’t full. Both goroutines attempt to update the same index of the backing array (index 1), which is a data race.\n\nHow can we prevent the data race if we want both goroutines to work on a slice containing the initial elements of `s` plus an extra element? One solution is to create a copy of `s`.\n\nWe should remember that using append on a shared slice in concurrent applications can lead to a data race. Hence, it should be avoided.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/69-data-race-append/main.go)\n\n### Using mutexes inaccurately with slices and maps (#70)\n\n???+ info \"TL;DR\"\n\n    Remembering that slices and maps are pointers can prevent common data races.\n\nLet's implement a `Cache` struct used to handle caching for customer balances. This struct will contain a map of balances per customer ID and a mutex to protect concurrent accesses:\n\n```go\ntype Cache struct {\n    mu       sync.RWMutex\n    balances map[string]float64\n}\n```\n\nNext, we add an `AddBalance` method that mutates the `balances` map. The mutation is done in a critical section (within a mutex lock and a mutex unlock):\n\n```go\nfunc (c *Cache) AddBalance(id string, balance float64) {\n    c.mu.Lock()\n    c.balances[id] = balance\n    c.mu.Unlock()\n}\n```\n\nMeanwhile, we have to implement a method to calculate the average balance for all the customers. One idea is to handle a minimal critical section this way:\n\n```go\nfunc (c *Cache) AverageBalance() float64 {\n    c.mu.RLock()\n    balances := c.balances // Creates a copy of the balances map\n    c.mu.RUnlock()\n\n    sum := 0.\n    for _, balance := range balances { // Iterates over the copy, outside of the critical section\n        sum += balance\n    }\n    return sum / float64(len(balances))\n}\n```\n\nWhat's the problem with this code?\n\nIf we run a test using the `-race` flag with two concurrent goroutines, one calling `AddBalance` (hence mutating balances) and another calling `AverageBalance`, a data race occurs. What’s the problem here?\n\nInternally, a map is a `runtime.hmap` struct containing mostly metadata (for example, a counter) and a pointer referencing data buckets. So, `balances := c.balances` doesn’t copy the actual data. Therefore, the two goroutines perform operations on the same data set, and one mutates it. Hence, it's a data race.\n\nOne possible solution is to protect the whole `AverageBalance` function:\n\n```go hl_lines=\"2 3\"\nfunc (c *Cache) AverageBalance() float64 {\n    c.mu.RLock()\n    defer c.mu.RUnlock() // Unlocks when the function returns\n\n    sum := 0.\n    for _, balance := range c.balances {\n        sum += balance\n    }\n    return sum / float64(len(c.balances))\n}\n```\n\nAnother option, if the iteration operation isn’t lightweight, is to work on an actual copy of the data and protect only the copy:\n\n```go hl_lines=\"2 3 4 5 6 7\"\nfunc (c *Cache) AverageBalance() float64 {\n    c.mu.RLock()\n    m := maps.Clone(c.balances)\n    c.mu.RUnlock()\n\n    sum := 0.\n    for _, balance := range m {\n        sum += balance\n    }\n    return sum / float64(len(m))\n}\n```\n\nOnce we have made a deep copy, we release the mutex. The iterations are done on the copy outside of the critical section.\n\nIn summary, we have to be careful with the boundaries of a mutex lock. In this section, we have seen why assigning an existing map (or an existing slice) to a map isn’t enough to protect against data races. The new variable, whether a map or a slice, is backed by the same data set. There are two leading solutions to prevent this: protect the whole function, or work on a copy of the actual data. In all cases, let’s be cautious when designing critical sections and make sure the boundaries are accurately defined.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/70-mutex-slices-maps/main.go)\n\n### Misusing `sync.WaitGroup` (#71)\n\n???+ info \"TL;DR\"\n\n    To accurately use `sync.WaitGroup`, call the `Add` method before spinning up goroutines.\n\nIn the following example, we will initialize a wait group, start three goroutines that will update a counter atomically, and then wait for them to complete. We want to wait for these three goroutines to print the value of the counter (which should be 3):\n\n```go\nwg := sync.WaitGroup{}\nvar v uint64\nfor i := 0; i < 3; i++ {\n    go func() {\n        wg.Add(1)\n        atomic.AddUint64(&v, 1)\n        wg.Done()\n    }()\n}\nwg.Wait()\nfmt.Println(v)\n```\n\nIf we run this example, we get a non-deterministic value: the code can print any value from 0 to 3. Also, if we enable the `-race` flag, Go will even catch a data race.\n\nThe problem is that `wg.Add(1)` is called within the newly created goroutine, not in the parent goroutine. Hence, there is no guarantee that we have indicated to the wait group that we want to wait for three goroutines before calling `wg.Wait()`.\n\nTo fix this issue, we can call `wg.Add` before the loop:\n\n```go\nwg := sync.WaitGroup{}\nvar v uint64\nwg.Add(3)\nfor i := 0; i < 3; i++ {\n    go func() {\n        atomic.AddUint64(&v, 1)\n        wg.Done()\n    }()\n}\nwg.Wait()\nfmt.Println(v)\n```\n\nOr inside the loop but not in the newly created goroutine:\n\n```go\nwg := sync.WaitGroup{}\nvar v uint64\nfor i := 0; i < 3; i++ {\n    wg.Add(1)\n    go func() {\n        atomic.AddUint64(&v, 1)\n        wg.Done()\n    }()\n}\nwg.Wait()\nfmt.Println(v)\n```\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/71-wait-group/main.go)\n\n### Forgetting about `sync.Cond` (#72)\n\n???+ info \"TL;DR\"\n\n    You can send repeated notifications to multiple goroutines with `sync.Cond`.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/72-cond/main.go)\n\n### Not using `errgroup` (#73)\n\n???+ info \"TL;DR\"\n\n    You can synchronize a group of goroutines and handle errors and contexts with the `errgroup` package.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/73-errgroup/main.go)\n\n### Copying a `sync` type (#74)\n\n???+ info \"TL;DR\"\n\n    `sync` types shouldn’t be copied.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/74-copying-sync/main.go)\n\n## Standard Library\n\n### Providing a wrong time duration (#75)\n\n???+ info \"TL;DR\"\n\n    Remain cautious with functions accepting a `time.Duration`. Even though passing an integer is allowed, strive to use the time API to prevent any possible confusion.\n\nMany common functions in the standard library accept a `time.Duration`, which is an alias for the `int64` type. However, one `time.Duration` unit represents one nanosecond, instead of one millisecond, as commonly seen in other programming languages. As a result, passing numeric types instead of using the `time.Duration` API can lead to unexpected behavior.\n\nA developer with experience in other languages might assume that the following code creates a new `time.Ticker` that delivers ticks every second, given the value `1000`:\n\n```go\nticker := time.NewTicker(1000)\nfor {\n\tselect {\n\tcase <-ticker.C:\n\t\t// Do something\n\t}\n}\n```\n\nHowever, because 1,000 `time.Duration` units = 1,000 nanoseconds, ticks are delivered every 1,000 nanoseconds = 1 microsecond, not every second as assumed.\n\nWe should always use the `time.Duration` API to avoid confusion and unexpected behavior:\n```go\nticker = time.NewTicker(time.Microsecond)\n// Or\nticker = time.NewTicker(1000 * time.Nanosecond)\n```\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/75-wrong-time-duration/main.go)\n\n### `time.After` and memory leaks (#76)\n\n???+ warning\n\n    This mistake isn't relevant anymore from Go 1.23 ([details](https://go.dev/wiki/Go123Timer)).\n\n### JSON handling common mistakes (#77)\n\n* Unexpected behavior because of type embedding\n\n  Be careful about using embedded fields in Go structs. Doing so may lead to sneaky bugs like an embedded time.Time field implementing the `json.Marshaler` interface, hence overriding the default marshaling behavior.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/type-embedding/main.go)\n\n* JSON and the monotonic clock\n\n  When comparing two `time.Time` structs, recall that `time.Time` contains both a wall clock and a monotonic clock, and the comparison using the == operator is done on both clocks.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/monotonic-clock/main.go)\n\n* Map of `any`\n\n  To avoid wrong assumptions when you provide a map while unmarshaling JSON data, remember that numerics are converted to `float64` by default.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/map-any/main.go)\n\n### Common SQL mistakes (#78)\n\n* Forgetting that `sql.Open` doesn't necessarily establish connections to a database\n\n  Call the `Ping` or `PingContext` method if you need to test your configuration and make sure a database is reachable.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/sql-open)\n\n* Forgetting about connections pooling\n\n  Configure the database connection parameters for production-grade applications.\n\n* Not using prepared statements\n\n  Using SQL prepared statements makes queries more efficient and more secure.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/prepared-statements)\n\n* Mishandling null values\n\n  Deal with nullable columns in tables using pointers or `sql.NullXXX` types.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/null-values/main.go)\n\n* Not handling rows iteration errors\n\n  Call the `Err` method of `sql.Rows` after row iterations to ensure that you haven’t missed an error while preparing the next row.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/rows-iterations-errors)\n\n### Not closing transient resources (HTTP body, `sql.Rows`, and `os.File`) (#79)\n\n???+ info \"TL;DR\"\n\n    Eventually close all structs implementing `io.Closer` to avoid possible leaks.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/79-closing-resources/)\n\n### Forgetting the return statement after replying to an HTTP request (#80)\n\n???+ info \"TL;DR\"\n\n    To avoid unexpected behaviors in HTTP handler implementations, make sure you don’t miss the `return` statement if you want a handler to stop after `http.Error`.\n\nConsider the following HTTP handler that handles an error from `foo` using `http.Error`:\n\n```go\nfunc handler(w http.ResponseWriter, req *http.Request) {\n\terr := foo(req)\n\tif err != nil {\n\t\thttp.Error(w, \"foo\", http.StatusInternalServerError)\n\t}\n\n\t_, _ = w.Write([]byte(\"all good\"))\n\tw.WriteHeader(http.StatusCreated)\n}\n```\n\nIf we run this code and `err != nil`, the HTTP response would be:\n\n```\nfoo\nall good\n```\n\nThe response contains both the error and success messages, and also the first HTTP status code, 500. There would also be a warning log indicating that we attempted to write the status code multiple times:\n\n```\n2023/10/10 16:45:33 http: superfluous response.WriteHeader call from main.handler (main.go:20)\n```\n\nThe mistake in this code is that `http.Error` does not stop the handler's execution, which means the success message and status code get written in addition to the error. Beyond an incorrect response, failing to return after writing an error can lead to the unwanted execution of code and unexpected side-effects. The following code adds the `return` statement following the `http.Error` and exhibits the desired behavior when ran:\n\n```go\nfunc handler(w http.ResponseWriter, req *http.Request) {\n\terr := foo(req)\n\tif err != nil {\n\t\thttp.Error(w, \"foo\", http.StatusInternalServerError)\n\t\treturn // Adds the return statement\n\t}\n\n\t_, _ = w.Write([]byte(\"all good\"))\n\tw.WriteHeader(http.StatusCreated)\n}\n```\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/80-http-return/main.go)\n\n### Using the default HTTP client and server (#81)\n\n???+ info \"TL;DR\"\n\n    For production-grade applications, don’t use the default HTTP client and server implementations. These implementations are missing timeouts and behaviors that should be mandatory in production.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/81-default-http-client-server/)\n\n## Testing\n\n### Not categorizing tests (build tags, environment variables, and short mode) (#82)\n\n???+ info \"TL;DR\"\n\n    Categorizing tests using build flags, environment variables, or short mode makes the testing process more efficient. You can create test categories using build flags or environment variables (for example, unit versus integration tests) and differentiate short from long-running tests to decide which kinds of tests to execute.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/82-categorizing-tests/)\n\n### Not enabling the race flag (#83)\n\n???+ info \"TL;DR\"\n\n    Enabling the `-race` flag is highly recommended when writing concurrent applications. Doing so allows you to catch potential data races that can lead to software bugs.\n\nIn Go, the race detector isn’t a static analysis tool used during compilation; instead, it’s a tool to find data races that occur at runtime. To enable it, we have to enable the -race flag while compiling or running a test. For example:\n\n```bash\ngo test -race ./...\n```\n\nOnce the race detector is enabled, the compiler instruments the code to detect data races. Instrumentation refers to a compiler adding extra instructions: here, tracking all memory accesses and recording when and how they occur.\n\nEnabling the race detector adds an overhead in terms of memory and execution time; hence, it's generally recommended to enable it only during local testing or continuous integration, not production.\n\nIf a race is detected, Go raises a warning. For example:\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n)\n\nfunc main() {\n    i := 0\n    go func() { i++ }()\n    fmt.Println(i)\n}\n```\n\nRunning this code with the `-race` logs the following warning:\n\n```bash hl_lines=\"3 7 11\"\n==================\nWARNING: DATA RACE\nWrite at 0x00c000026078 by goroutine 7: # (1)\n  main.main.func1()\n      /tmp/app/main.go:9 +0x4e\n\nPrevious read at 0x00c000026078 by main goroutine: # (2)\n  main.main()\n      /tmp/app/main.go:10 +0x88\n\nGoroutine 7 (running) created at: # (3)\n  main.main()\n      /tmp/app/main.go:9 +0x7a\n==================\n```\n\n1.  Indicates that goroutine 7 was writing\n2.  Indicates that the main goroutine was reading\n3.  Indicates when the goroutine 7 was created\n\nLet’s make sure we are comfortable reading these messages. Go always logs the following:\n\n* The concurrent goroutines that are incriminated: here, the main goroutine and goroutine 7.\n* Where accesses occur in the code: in this case, lines 9 and 10.\n* When these goroutines were created: goroutine 7 was created in main().\n\nIn addition, if a specific file contains tests that lead to data races, we can exclude it :material-information-outline:{ title=\"temporarily! 😉\" } from race detection using the `!race` build tag:\n\n```go\n//go:build !race\n\npackage main\n\nimport (\n    \"testing\"\n)\n\nfunc TestFoo(t *testing.T) {\n    // ...\n}\n```\n\n### Not using test execution modes (parallel and shuffle) (#84)\n\n???+ info \"TL;DR\"\n\n    Using the `-parallel` flag is an efficient way to speed up tests, especially long-running ones. Use the `-shuffle` flag to help ensure that a test suite doesn’t rely on wrong assumptions that could hide bugs.\n\n### Not using table-driven tests (#85)\n\n???+ info \"TL;DR\"\n\n    Table-driven tests are an efficient way to group a set of similar tests to prevent code duplication and make future updates easier to handle.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/85-table-driven-tests/main_test.go)\n\n### Sleeping in unit tests (#86)\n\n???+ info \"TL;DR\"\n\n    Avoid sleeps using synchronization to make a test less flaky and more robust. If synchronization isn’t possible, consider a retry approach.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/86-sleeping/main_test.go)\n\n### Not dealing with the time API efficiently (#87)\n\n???+ info \"TL;DR\"\n\n    Understanding how to deal with functions using the time API is another way to make a test less flaky. You can use standard techniques such as handling the time as part of a hidden dependency or asking clients to provide it.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/87-time-api/)\n\n### Not using testing utility packages (`httptest` and `iotest`) (#88)\n\n* The `httptest` package is helpful for dealing with HTTP applications. It provides a set of utilities to test both clients and servers.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/88-utility-package/httptest/main_test.go)\n\n* The `iotest` package helps write io.Reader and test that an application is tolerant to errors.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/88-utility-package/iotest/main_test.go)\n\n### Writing inaccurate benchmarks (#89)\n\n???+ info \"TL;DR\"\n\n    Regarding benchmarks:\n\n    * Use time methods to preserve the accuracy of a benchmark.\n    * Increasing benchtime or using tools such as benchstat can be helpful when dealing with micro-benchmarks.\n    * Be careful with the results of a micro-benchmark if the system that ends up running the application is different from the one running the micro-benchmark.\n    * Make sure the function under test leads to a side effect, to prevent compiler optimizations from fooling you about the benchmark results.\n    * To prevent the observer effect, force a benchmark to re-create the data used by a CPU-bound function.\n\nRead the full section [here](89-benchmarks.md).\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/89-benchmark/)\n\n### Not exploring all the Go testing features (#90)\n\n* Code coverage\n\n  Use code coverage with the `-coverprofile` flag to quickly see which part of the code needs more attention.\n\n* Testing from a different package\n\n  Place unit tests in a different package to enforce writing tests that focus on an exposed behavior, not internals.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/different-package/main_test.go)\n\n* Utility functions\n\n  Handling errors using the `*testing.T` variable instead of the classic `if err != nil` makes code shorter and easier to read.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/utility-function/main_test.go)\n\n* Setup and teardown\n\n  You can use setup and teardown functions to configure a complex environment, such as in the case of integration tests.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/setup-teardown/main_test.go)\n\n### Not using fuzzing (community mistake)\n\n???+ info \"TL;DR\"\n\n    Fuzzing is an efficient strategy to detect random, unexpected, or malformed inputs to complex functions and methods in order to discover vulnerabilities, bugs, or even potential crashes.\n\nCredits: [@jeromedoucet](https://github.com/jeromedoucet)\n\n## Optimizations\n\n### Not understanding CPU caches (#91)\n\n* CPU architecture\n\n  Understanding how to use CPU caches is important for optimizing CPU-bound applications because the L1 cache is about 50 to 100 times faster than the main memory.\n\n* Cache line\n\n  Being conscious of the cache line concept is critical to understanding how to organize data in data-intensive applications. A CPU doesn’t fetch memory word by word; instead, it usually copies a memory block to a 64-byte cache line. To get the most out of each individual cache line, enforce spatial locality.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/cache-line/)\n\n* Slice of structs vs. struct of slices\n\n<!-- TODO -->\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/slice-structs/)\n\n* Predictability\n\n  Making code predictable for the CPU can also be an efficient way to optimize certain functions. For example, a unit or constant stride is predictable for the CPU, but a non-unit stride (for example, a linked list) isn’t predictable.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/predictability/)\n\n* Cache placement policy\n\n  To avoid a critical stride, hence utilizing only a tiny portion of the cache, be aware that caches are partitioned.\n\n### Writing concurrent code that leads to false sharing (#92)\n\n???+ info \"TL;DR\"\n\n    Knowing that lower levels of CPU caches aren’t shared across all the cores helps avoid performance-degrading patterns such as false sharing while writing concurrency code. Sharing memory is an illusion.\n\nRead the full section [here](92-false-sharing.md).\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/92-false-sharing/)\n\n### Not taking into account instruction-level parallelism (#93)\n\n???+ info \"TL;DR\"\n\n    Use ILP to optimize specific parts of your code to allow a CPU to execute as many parallel instructions as possible. Identifying data hazards is one of the main steps.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/93-instruction-level-parallelism/)\n\n### Not being aware of data alignment (#94)\n\n???+ info \"TL;DR\"\n\n    You can avoid common mistakes by remembering that in Go, basic types are aligned with their own size. For example, keep in mind that reorganizing the fields of a struct by size in descending order can lead to more compact structs (less memory allocation and potentially a better spatial locality).\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/94-data-alignment/)\n\n### Not understanding stack vs. heap (#95)\n\n???+ info \"TL;DR\"\n\n    Understanding the fundamental differences between heap and stack should also be part of your core knowledge when optimizing a Go application. Stack allocations are almost free, whereas heap allocations are slower and rely on the GC to clean the memory.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/95-stack-heap/)\n\n### Not knowing how to reduce allocations (API change, compiler optimizations, and `sync.Pool`) (#96)\n\n???+ info \"TL;DR\"\n\n    Reducing allocations is also an essential aspect of optimizing a Go application. This can be done in different ways, such as designing the API carefully to prevent sharing up, understanding the common Go compiler optimizations, and using `sync.Pool`.\n\n [:simple-github: Source code](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/96-reduce-allocations/)\n\n### Not relying on inlining (#97)\n\n???+ info \"TL;DR\"\n\n    Use the fast-path inlining technique to efficiently reduce the amortized time to call a function.\n\n### Not using Go diagnostics tooling (#98)\n\n???+ info \"TL;DR\"\n\n    Rely on profiling and the execution tracer to understand how an application performs and the parts to optimize.\n\nRead the full section [here](98-profiling-execution-tracing.md).\n\n### Not understanding how the GC works (#99)\n\n???+ info \"TL;DR\"\n\n    Understanding how to tune the GC can lead to multiple benefits such as handling sudden load increases more efficiently.\n\n### :warning: Not understanding the impacts of running Go in Docker and Kubernetes (#100)\n\n???+ warning\n\n\tThis mistake isn't relevant anymore from Go 1.25 ([details](https://go.dev/blog/container-aware-gomaxprocs)).\n\n## Community\n\nThanks to all the contributors:\n\n<a href=\"https://contrib.rocks/image?repo=teivah/100-go-mistakes\">\n    <img src=\"https://contrib.rocks/image?repo=teivah/100-go-mistakes\" alt=\"Description of the image\">\n</a>\n\n## Powered by\n\n[![JetBrains logo.](https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.svg)](https://jb.gg/OpenSource)"
  },
  {
    "path": "docs/ja.md",
    "content": "---\r\ntitle: Japanese Version\r\ncomments: true\r\n---\r\n\r\n# Go言語でありがちな間違い\r\n\r\n???+ tip \"The Coder Cafe\"\r\n\r\n    もし私の本を楽しんでいただけたなら、私の最新プロジェクトにもご興味があるかもしれません。[The Coder Cafe](https://thecoder.cafe?rd=100go.co/ja)は、コーダー向けの日刊ニュースレターです。\r\n\r\n    > Feeling overwhelmed by the endless stream of tech content? At The Coder Cafe, we serve one essential concept for coders. Written by a senior software engineer at Google, it's perfectly brewed for your morning coffee, helping you grow your skills deeply.\r\n\r\n    <center><a href=\"https://thecoder.cafe?rd=100go.co/ja\"><img src=\"../img/thecodercafe.png\" alt=\"\" style=\"width:480px;height:240px;\"></a></center>\r\n\r\nこのページは『100 Go Mistakes』の内容をまとめたものです。一方で、コミュニティに開かれたページでもあります。「ありがちな間違い」が新たに追加されるべきだとお考えでしたら [community mistake issue](https://github.com/teivah/100-go-mistakes/issues/new?assignees=&labels=community+mistake&template=community_mistake.md&title=) を作成してください。\r\n\r\n![](img/inside-cover.png)\r\n\r\n???+ warning \"注意\"\r\n\r\n    現在、大幅に多くのコンテンツを追加して強化している新しいバージョンを閲覧しています。このバージョンはまだ開発中です。問題を見つけた場合はどうぞ気軽にPRを作成してください。\r\n\r\n## コードとプロジェクト構成\r\n\r\n### 意図的でない変数のシャドーイング (#1)\r\n\r\n???+ info \"要約\"\r\n\r\n    変数のシャドーイングを避けることは、誤った変数の参照や読み手の混乱を防ぎます。\r\n\r\n変数のシャドーイングは、変数名がブロック内で再宣言されることで生じますが、これは間違いを引き起こしやすくします。変数のシャドーイングを禁止するかどうかは個人の好みによります。たとえば、エラーに対して `err` のような既存の変数名を再利用すると便利な場合があります。とはいえ、コードはコンパイルされたものの、値を受け取った変数が予期したものではないというシナリオに直面する可能性があるため、原則として引き続き注意を払う必要があります。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/1-variable-shadowing/main.go)\r\n\r\n### 不必要にネストされたコード (#2)\r\n\r\n???+ info \"要約\"\r\n\r\n    ネストが深くならないようにし、ハッピーパスを左側に揃えることでメンタルコードモデルを構築することが容易になります。\r\n\r\n一般的に、関数がより深いネストを要求するほど、読んで理解することがより複雑になります。私たちのコードの可読性を最適化するために、このルールの適用方法を見ていきましょう。\r\n\r\n* `if` ブロックが返されるとき、すべての場合において `else` ブロックを省略する必要があります。 たとえば、次のように書くべきではありません。\r\n\r\n```go\r\nif foo() {\r\n    // ...\r\n    return true\r\n} else {\r\n    // ...\r\n}\r\n```\r\n\r\n代わりに、次のように `else` ブロックを省略します。\r\n\r\n```go\r\nif foo() {\r\n    // ...\r\n    return true\r\n}\r\n// ...\r\n```\r\n\r\n* ノンハッピーパスでもこのロジックに従うことが可能です。\r\n\r\n```go\r\nif s != \"\" {\r\n    // ...\r\n} else {\r\n    return errors.New(\"empty string\")\r\n}\r\n```\r\n\r\nここでは、空の `s` がノンハッピーパスを表します。したがって、次のように条件をひっくり返す必要があります。\r\n\r\n```go\r\nif s == \"\" {\r\n    return errors.New(\"empty string\")\r\n}\r\n// ...\r\n```\r\n\r\n読みやすいコードを書くことは、すべての開発者にとって重要な課題です。ネストされたブロックの数を減らすよう努め、ハッピーパスを左側に揃え、できるだけ早く戻ることが、コードの可読性を向上させる具体的な手段です。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/2-nested-code/main.go)\r\n\r\n### init関数の誤用 (#3)\r\n\r\n???+ info \"要約\"\r\n\r\n    変数を初期化するときは、init関数のエラー処理が制限されており、ステートの処理とテストがより複雑になることに注意してください。ほとんどの場合、初期化は特定の関数として処理されるべきです。\r\n\r\ninit関数は、アプリケーションのステートを初期化するために使用される関数です。引数を取らず、結果も返しません（ `func()` 関数）。パッケージが初期化されると、パッケージ内のすべての定数および変数の宣言が評価されます。次に、init関数が実行されます。\r\n\r\ninit関数はいくつかの問題を引き起こす可能性があります。\r\n\r\n* エラー処理が制限される可能性があります。\r\n* テストの実装方法が複雑になる可能性があります（たとえば、外部依存関係を設定する必要がありますが、単体テストの範囲では必要ない可能性があります）。\r\n* 初期化でステートを設定する必要がある場合は、グローバル変数を使用して行う必要があります。\r\n\r\ninit関数には注意が必要です。ただし、静的構成の定義など、状況によっては役立つ場合があります。それ以外のほとんどの場合、初期化処理は特定の関数を通じて行われるべきです。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/3-init-functions/)\r\n\r\n### ゲッターとセッターの乱用 (#4)\r\n\r\n???+ info \"要約\"\r\n\r\n    Go言語では、慣用的にゲッターとセッターの使用を強制することはありません。実利を重視し、効率性と特定の慣習に従うこととの間の適切なバランスを見つけることが、進むべき道であるはずです。\r\n\r\nデータのカプセル化とは、オブジェクトの値または状態を隠すことを指します。ゲッターとセッターは、エクスポートされていないオブジェクトフィールドの上にエクスポートされたメソッドを提供することでカプセル化を可能にする手段です。\r\n\r\nGo言語では、一部の言語で見られるようなゲッターとセッターの自動サポートはありません。また、ゲッターとセッターを使用して構造体フィールドにアクセスすることは必須でも慣用的でもありません。値をもたらさない構造体のゲッターとセッターでコードを埋めるべきではありません。実利を重視し、他のプログラミングパラダイムで時には議論の余地がないと考えられている慣習に従うことと、効率性との間の適切なバランスを見つけるよう努めるべきです。\r\n\r\nGo言語は、シンプルさを含む多くの特性を考慮して設計された独自の言語であることを忘れないでください。ただし、ゲッターとセッターの必要性が見つかった場合、または前述のように、前方互換性を保証しながら将来の必要性が予測される場合は、それらを使用することに問題はありません。\r\n\r\n### インタフェース汚染 (#5)\r\n\r\n???+ info \"要約\"\r\n\r\n    抽象化は作成されるべきものではなく、発見されるべきものです。不必要な複雑さを避けるために、インタフェースは、必要になると予測したときではなく、必要になったときに作成するか、少なくとも抽象化が有効であることを証明できる場合に作成してください。\r\n\r\nインタフェースは、オブジェクトの動作を指定する方法を提供します。複数のオブジェクトが実装できる共通項を抽出するために、インタフェースは使用されます。Go言語のインタフェースが大きく異なるのは、暗黙的に満たされることです。オブジェクト `X` がインタフェース `Y` を実装していることを示す `implements` のような明示的なキーワードはありません。\r\n\r\n一般に、インタフェースが価値をもたらすと考えられる主要な使用例は３つあります。それは、共通の動作を除外する、何らかの分離を作成する、および型を特定の動作に制限するというものです。ただし、このリストはすべてを網羅しているわけではなく、直面する状況によっても異なります。\r\n\r\n多くの場合、インタフェースは抽象化するために作成されます。そして、プログラミングで抽象化するときの主な注意点は、抽象化は作成されるべきではなく、発見されるべきであるということを覚えておくことです。すなわち、そうする直接の理由がない限り、コード内で抽象化すべきではないということです。インタフェースを使って設計するのではなく、具体的なニーズを待つべきです。別の言い方をすれば、インタフェースは必要になると予測したときではなく、必要になったときに作成する必要があります。\r\nインタフェースの過度な使用をした場合の主な問題は何でしょうか。答えは、コードフローがより複雑になることです。役に立たない間接参照を追加しても何の価値もありません。それは価値のない抽象化をすることで、コードを読み、理解し、推論することをさらに困難にします。インタフェースを追加する明確な理由がなく、インタフェースによってコードがどのように改善されるかが不明瞭な場合は、そのインタフェースの目的に異議を唱える必要があります。実装を直接呼び出すのも一つの手です。\r\n\r\nコード内で抽象化するときは注意が必要です（抽象化は作成するのではなく、発見する必要があります）。後で必要になる可能性があるものを考慮し、完璧な抽象化レベルを推測して、私たちソフトウェア開発者はコードをオーバーエンジニアリングすることがよくあります。ほとんどの場合、コードが不必要な抽象化で汚染され、読みにくくなるため、このプロセスは避けるべきです。\r\n\r\n!!! quote \"ロブ・パイク\"\r\n\r\n    インタフェースでデザインするな。インタフェースを見つけ出せ。\r\n\r\n抽象的に問題を解決しようとするのではなく、今解決すべきことを解決しましょう。最後に重要なことですが、インタフェースによってコードがどのように改善されるかが不明瞭な場合は、コードを簡素化するためにインタフェースを削除することを検討する必要があるでしょう。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/5-interface-pollution/)\r\n\r\n### 生産者側のインタフェース (#6)\r\n\r\n???+ info \"要約\"\r\n\r\n    インタフェースをクライアント側で保持することで不必要な抽象化を回避できます。\r\n\r\nGo言語ではインタフェースが暗黙的に満たされます。これは、明示的な実装を持つ言語と比較して大きな変化をもたらす傾向があります。ほとんどの場合、従うべきアプローチは前のセクションで説明したもの――_抽象化は作成するのではなく、発見する必要がある_――に似ています。これは、すべてのクライアントに対して特定の抽象化を強制するのは生産者の役割ではないことを意味します。代わりに、何らかの形式の抽象化が必要かどうかを判断し、そのニーズに最適な抽象化レベルを決定するのはクライアントの責任です。\r\n\r\nほとんどの場合、インタフェースは消費者側に存在する必要があります。ただし、特定の状況（たとえば、抽象化が消費者にとって役立つことがわかっている――予測はしていない――場合）では、それを生産者側で使用したい場合があります。そうした場合、可能な限り最小限に抑え、再利用可能性を高め、より簡単に構成できるように努めるべきです。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/6-interface-producer/)\r\n\r\n### インタフェースを返す (#7)\r\n\r\n???+ info \"要約\"\r\n\r\n    柔軟性に問題がないようにするために、関数はほとんどの場合、インタフェースではなく具体的​​な実装を返す必要があります。逆に、関数は可能な限りインタフェースを受け入れる必要があります。\r\n\r\nほとんどの場合、インタフェースではなく具体的な実装を返す必要があります。そうでないとパッケージの依存関係により設計がいっそう複雑になり、すべてのクライアントが同じ抽象化に依存する必要があるため、柔軟性に欠ける可能性があります。結論は前のセクションと似ています。抽象化がクライアントにとって役立つことが（予測されるではなく）わかっている場合は、インタフェースを返すことを検討してもよいでしょう。それ以外の場合は、抽象化を強制すべきではありません。それらはクライアントによって発見される必要があります。何らかの理由でクライアントが実装を抽象化する必要がある場合でも、クライアント側でそれを行うことができます。\r\n\r\n### `any` は何も言わない (#8)\r\n\r\n???+ info \"要約\"\r\n\r\n    `json.Marshal` など考えうるすべての型を受け入れるか返す必要がある場合にのみ `any` を使用してください。それ以外の場合、`any` は意味のある情報を提供せず、呼び出し元が任意のデータ型のメソッドを呼び出すことを許可するため、コンパイル時に問題が発生する可能性があります。\r\n\r\n`any` 型は、考えうるすべての型を受け入れるか返す必要がある場合（たとえば、マーシャリングやフォーマットの場合）に役立ちます。原則としてコードを過度に一般化することは何としても避けるべきです。コードの表現力などの他の側面が向上する場合は、コードを少し重複させたほうが良いこともあります。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/8-any/main.go)\r\n\r\n### ジェネリックスをいつ使用するべきか理解していない (#9)\r\n\r\n???+ info \"要約\"\r\n\r\n    ジェネリックスと型パラメーターを利用することで、要素や動作を除外するためのボイラープレートコードを避けることができます。ただし、型パラメータは時期尚早に使用せず、具体的な必要性がわかった場合にのみ使用してください。そうでなければ、不必要な抽象化と複雑さが生じます。\r\n\r\nセクション全文は[こちら](9-generics.md)。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/9-generics/main.go)\r\n\r\n### 型の埋め込みで起こりうる問題を把握していない (#10)\r\n\r\n???+ info \"要約\"\r\n\r\n    型埋め込みを使用すると、ボイラープレートコードを回避することもできます。ただし、そうすることで、一部のフィールドを非表示にしておく必要がある場合に問題が発生しないようにしてください。\r\n\r\n構造体を作成するとき、Go言語は型を埋め込むオプションを提供します。ただし、型埋め込みの意味をすべて理解していないと、予想外の動作が発生する可能性があります。このセクションでは、型を埋め込む方法、それがもたらすもの、および考えられる問題について見ていきます。\r\n\r\nGo言語では、名前なしで宣言された構造体フィールドは、埋め込みと呼ばれます。たとえば、次のようなものです。\r\n\r\n```go\r\ntype Foo struct {\r\n    Bar // 埋め込みフィールド\r\n}\r\n\r\ntype Bar struct {\r\n    Baz int\r\n}\r\n```\r\n\r\n`Foo` 構造体では、`Bar` 型が関連付けられた名前なしで宣言されています。したがって、これは埋め込みフィールドです。\r\n\r\n埋め込みを使用することで、埋め込み型のフィールドとメソッドは昇格します。Bar には Baz フィールドが含まれているため、このフィールドは `Foo` に昇格します。したがって、Foo から Baz を利用できるようになります。\r\n\r\n型の埋め込みについて何が言えるでしょうか。まず、これが必要になることはほとんどなく、ユースケースが何であれ、おそらく型埋め込みなしでも同様に解決できることを意味します。型の埋め込みは主に利便性を目的として使用されます。ほとんどの場合、それは動作を昇格するために使用されます。\r\n\r\n型埋め込みを使用する場合は、次の 2 つの主な制約を念頭に置く必要があります。\r\n\r\n* フィールドへのアクセスを簡素化するための糖衣構文としてのみ使用しないでください（ `Foo.Bar.Baz()` の代わりに `Foo.Baz()` など）。 これが唯一の根拠である場合は、内部型を埋め込まず、代わりにフィールドを使いましょう。\r\n* 外部から隠したいデータ（フィールド）や動作（メソッド）を昇格してはなりません。たとえば、構造体に対してプライベートなままにしておく必要があるロック動作にクライアントがアクセスできるようにする場合などです。\r\n\r\nこれらの制約を念頭に置いて型埋め込みを意識的に使用すると、追加の転送メソッドによるボイラープレートコードを回避するのに役立ちます。ただし、見た目だけを目的としたり、隠すべき要素を昇格したりしないように注意しましょう。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/10-type-embedding/main.go)\r\n\r\n### Functional Options パターンを使用していない (#11)\r\n\r\n???+ info \"要約\"\r\n\r\n    API に適した方法でオプションを便利に処理するには、Functional Options パターンを使用しましょう。\r\n\r\nさまざまな実装方法が存在し、多少の違いはありますが、主な考え方は次のとおりです。\r\n\r\n* 未エクスポートの構造体はオプション設定を保持します。\r\n* 各オプションは同じ型、`type Option func(options *options)` エラーを返す関数です。たとえば、`WithPort` はポートを表す `int` 引数を受け取り、`options` 構造体の更新方法を表す `Option` 型を返します。\r\n\r\n![](img/options.png)\r\n\r\n```go\r\ntype options struct {\r\n  port *int\r\n}\r\n\r\ntype Option func(options *options) error\r\n\r\nfunc WithPort(port int) Option {\r\n  return func(options *options) error {\r\n    if port < 0 {\r\n    return errors.New(\"port should be positive\")\r\n  }\r\n  options.port = &port\r\n  return nil\r\n  }\r\n}\r\n\r\nfunc NewServer(addr string, opts ...Option) ( *http.Server, error) {\r\n  var options options\r\n  for _, opt := range opts { \r\n    err := opt(&options) \r\n    if err != nil {\r\n      return nil, err\r\n    }\r\n  }\r\n\r\n// この段階で、options 構造体が構築され、構成が含まれます。\r\n// したがって、ポート設定に関連するロジックを実装できます。\r\n  var port int\r\n  if options.port == nil {\r\n    port = defaultHTTPPort\r\n  } else {\r\n      if *options.port == 0 {\r\n      port = randomPort()\r\n    } else {\r\n      port = *options.port\r\n    }\r\n  }\r\n\r\n  // ...\r\n}\r\n```\r\n\r\nFunctional Options パターンは、オプションを処理するための手軽で API フレンドリーな方法を提供します。 Builder パターンは有効なオプションですが、いくつかの小さな欠点（空の可能性がある構成構造体を渡さなければならない、またはエラーを処理する方法があまり便利ではない）があり、この種の問題において Functional Options パターンがGo言語における慣用的な対処方法になる傾向があります。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/11-functional-options/)\r\n\r\n### 誤ったプロジェクト構成 (プロジェクト構造とパッケージ構成) (#12)\r\n\r\n全体的な構成に関しては、さまざまな考え方があります。たとえば、アプリケーションをコンテキストごとに整理すべきか、それともレイヤーごとに整理すべきか、それは好みによって異なります。コンテキスト（顧客コンテキスト、契約コンテキストなど）ごとにコードをグループ化することを選ぶ場合もあれば、六角形のアーキテクチャ原則に従うことと、技術層ごとにグループ化することを選ぶ場合もあります。私たちが行う決定が一貫している限り、それがユースケースに適合するなら、それが間違っていることはありません。\r\n\r\nパッケージに関しては、従うべきベストプラクティスが複数あります。まず、プロジェクトが過度に複雑になる可能性があるため、時期尚早なパッケージ化は避けるべきです。場合によっては、完璧な構造を最初から無理に作ろうとするよりも、単純な構成を使用し、その内容を理解した上でプロジェクトを発展させるほうが良い場合があります。\r\n粒度も考慮すべき重要な点です。 1 つまたは 2 つのファイルだけを含む数十のナノパッケージを作成することは避けるべきです。その場合、おそらくこれらのパッケージ間の論理的な接続の一部が抜け落ち、読み手にとってプロジェクトが理解しにくくなるからです。逆に、パッケージ名の意味を薄めるような巨大なパッケージも避けるべきです。\r\n\r\nパッケージの名前付けも注意して行う必要があります。（開発者なら）誰もが知っているように、名前を付けるのは難しいです。クライアントが Go プロジェクトを理解しやすいように、パッケージに含まれるものではなく、提供するものに基づいてパッケージに名前を付ける必要があります。また、ネーミングには意味のあるものを付ける必要があります。したがって、パッケージ名は短く、簡潔で、表現力豊かで、慣例により単一の小文字にする必要があります。\r\n\r\n何をエクスポートするかについてのルールは非常に簡単です。パッケージ間の結合を減らし、エクスポートされる不要な要素を非表示にするために、エクスポートする必要があるものをできる限り最小限に抑える必要があります。要素をエクスポートするかどうか不明な場合は、デフォルトでエクスポートしないようにする必要があります。後でエクスポートする必要があることが判明した場合は、コードを調整できます。また、構造体を encoding/json でアンマーシャリングできるようにフィールドをエクスポートするなど、いくつかの例外にも留意してください。\r\n\r\nプロジェクトを構成するのは簡単ではありませんが、これらのルールに従うことで維持が容易になります。ただし、保守性を容易にするためには一貫性も重要であることに注意してください。したがって、コードベース内で可能な限り一貫性を保つようにしましょう。\r\n\r\n???+ note \"補足\"\r\n\r\n    Go チームは Go プロジェクトの組織化/構造化に関する公式ガイドラインを 2023 年に発行しました： [go.dev/doc/modules/layout](https://go.dev/doc/modules/layout)\r\n\r\n### ユーティリティパッケージの作成 (#13)\r\n\r\n???+ info \"要約\"\r\n\r\n    名前付けはアプリケーション設計の重要な部分です。`common` 、`util` 、`shared` のようなパッケージを作成しても、読み手にそれほどの価値をもたらしません。このようなパッケージを意味のある具体的なパッケージ名にリファクタリングしましょう。\r\n\r\nまた、パッケージに含まれるものではなく、パッケージが提供するものに基づいてパッケージに名前を付けると、その表現力を高める効率的な方法になることにも留意してください。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/13-utility-packages/stringset.go)\r\n\r\n### パッケージ名の衝突を無視する (#14)\r\n\r\n???+ info \"要約\"\r\n\r\n     混乱、さらにはバグにつながりかねない、変数とパッケージ間の名前の衝突を回避するために、それぞれに一意の名前を使用しましょう。これが不可能な場合は、インポートエイリアスを使用して修飾子を変更してパッケージ名と変数名を区別するか、より良い名前を考えてください。\r\n\r\nパッケージの衝突は、変数名が既存のパッケージ名と衝突する場合に発生し、パッケージの再利用が妨げられます。曖昧さを避けるために、変数名の衝突を防ぐ必要があります。衝突が発生した場合は、別の意味のある名前を見つけるか、インポートエイリアスを使用する必要があります。\r\n\r\n### コードの文章化が行われていない (#15)\r\n\r\n???+ info \"要約\"\r\n\r\n    クライアントとメンテナがコードの意図を理解できるように、エクスポートされた要素を文章化しましょう。\r\n\r\n文章化はコーディングの重要な側面です。これにより、クライアントが API をより簡単に使用することができますが、プロジェクトの維持にも役立ちます。Go言語では、コードを慣用的なものにするために、いくつかのルールに従う必要があります。\r\n\r\nまず、エクスポートされたすべての要素を文章化する必要があります。構造、インタフェース、関数など、エクスポートする場合は文章化する必要があります。慣例として、エクスポートされた要素の名前から始まるコメントを追加します。\r\n\r\n慣例として、各コメントは句読点で終わる完全な文である必要があります。また、関数（またはメソッド）を文章化するときは、関数がどのように実行するかではなく、その関数が何を実行するつもりであるかを強調する必要があることにも留意してください。これはドキュメントではなく、関数とコメントについてです。ドキュメントは理想的には、利用者がエクスポートされた要素の使用方法を理解するためにコードを見る必要がないほど十分な情報を提供する必要があります。\r\n\r\n変数または定数を文章化する場合、その目的と内容という 2 つの側面を伝えることが重要かもしれません。前者は、外部クライアントにとって役立つように、コードドキュメントとして存在する必要があります。ただし、後者は必ずしも公開されるべきではありません。\r\n\r\nクライアントとメンテナがパッケージの目的を理解できるように、各パッケージをドキュメントする必要もあります。慣例として、コメントは `//Package` で始まり、その後にパッケージ名が続きます。パッケージコメントの最初の行は、パッケージに表示されるため簡潔にする必要があります。そして、次の行に必要な情報をすべて入力します。\r\n\r\nコードを文章化することが制約になるべきではありません。クライアントやメンテナがコードの意図を理解するのに役立つ必要があります。\r\n\r\n### リンターを使用してない (#16)\r\n\r\n???+ info \"要約\"\r\n\r\n    コードの品質と一貫性を向上させるには、リンターとフォーマッターを使用しましょう\r\n\r\nリンターは、コードを分析してエラーを検出する自動ツールです。このセクションの目的は、既存のリンターの完全なリストを提供することではありません。そうした場合、すぐに使い物にならなくなってしまうからです。ただし、ほとんどの Go プロジェクトにリンターが不可欠であるということは理解し、覚えておきましょう。\r\n\r\n* [https://golang.org/cmd/vet](https://golang.org/cmd/vet)――Go言語の標準コードアナライザー\r\n* [https://github.com/kisielk/errcheck](https://github.com/kisielk/errcheck)――エラーチェッカー\r\n* [https://github.com/fzipp/gocyclo](https://github.com/fzipp/gocyclo)――循環的複雑度アナライザー\r\n* [https://github.com/jgautheron/goconst](https://github.com/jgautheron/goconst)――複数回使用文字列アナライザー\r\n\r\n\r\nリンターのほかに、コードスタイルを修正するためにコードフォーマッターも使用しましょう。以下に、いくつかのコードフォーマッターを示します。\r\n\r\n* [https://golang.org/cmd/gofmt](https://golang.org/cmd/gofmt)――Go言語の標準コードフォーマッター\r\n* [https://godoc.org/golang.org/x/tools/cmd/goimports](https://godoc.org/golang.org/x/tools/cmd/goimports)――Go言語の標準インポートフォーマッター\r\n\r\nほかに golangci-lint ([https://github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint)) というものがあります。これは、多くの便利なリンターやフォーマッターの上にファサードを提供するリンティングツールです。また、リンターを並列実行して分析速度を向上させることができ、非常に便利です。\r\n\r\nリンターとフォーマッターは、コードベースの品質と一貫性を向上させる強力な方法です。時間をかけてどれを使用すべきかを理解し、それらの実行（ CI や Git プリコミットフックなど）を自動化しましょう。\r\n\r\n## データ型\r\n\r\n### 8 進数リテラルで混乱を招いてしまう (#17)\r\n\r\n???+ info \"要約\"\r\n\r\n    既存のコードを読むときは、 `0` で始まる整数リテラルが 8 進数であることに留意してください。また、接頭辞 `0o` を付けることで8進数であることを明確にし、読みやすさを向上させましょう。\r\n\r\n8 進数は 0 で始まります（たとえば、`010` は 10 進数の 8 に相当します）。可読性を向上させ、将来のコードリーダーの潜在的な間違いを回避するには、 `0o` 接頭辞を使用して 8 進数であることを明らかにしましょう（例: `0o10` ）。\r\n\r\n他の整数リテラル表現にも注意してください。 \r\n\r\n * _バイナリ_ - 接頭辞 `0b` あるいは `0B` を使用します（たとえば、 `0b` は 10 進数の 4 に相当します）\r\n * _16進数_ - 接頭辞 `0x` あるいは `0X` を使用します（たとえば、 `0xF` は 10 進数の 15 に相当します）。 \r\n * _虚数_ - 接尾辞 `i` を使用します（たとえば、 `3i` ）\r\n\r\n読みやすくするために、区切り文字としてアンダースコア（ _ ）を使用することもできます。たとえば、 10 億は `1_000_000_000` のように書くことができます。アンダースコアは `0b)00_00_01` のように他の表現と併用することもできます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/17-octal-literals/main.go)\r\n\r\n### 整数オーバーフローを無視している (#18)\r\n\r\n???+ info \"要約\"\r\n\r\n    Go言語では整数のオーバーフローとアンダーフローが裏側で処理されるため、それらをキャッチする独自の関数を実装できます。\r\n\r\nGo言語では、コンパイル時に検出できる整数オーバーフローによってコンパイルエラーが生成されます。たとえば、次のようになります。\r\n\r\n```go\r\nvar counter int32 = math.MaxInt32 + 1\r\n```\r\n\r\n```shell\r\nconstant 2147483648 overflows int32\r\n```\r\n\r\nただし、実行時には、整数のオーバーフローまたはアンダーフローは発生しません。これによってアプリケーションのパニックが発生することはありません。この動作はやっかいなバグ（たとえば、負の結果につながる整数の増分や正の整数の加算など）につながる可能性があるため、頭に入れておくことが重要です。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/18-integer-overflows)\r\n\r\n### 浮動小数点を理解していない (#19)\r\n\r\n???+ info \"要約\"\r\n\r\n    特定のデルタ内で浮動小数点比較を行うと、コードの移植性を確保できます。加算または減算を実行するときは、精度を向上させるために、同程度の大きさの演算をグループ化してください。また、乗算と除算は加算と減算の前に実行してください。\r\n\r\nGo言語には、（虚数を除いた場合） `float32` と `float64` という 2 つの浮動小数点型があります。浮動小数点の概念は、小数値を表現できないという整数の大きな問題を解決するために発明されました。予想外の事態を避けるために、浮動小数点演算は実際の演算の近似であることを知っておく必要があります。 \r\n\r\nそのために、乗算の例を見てみましょう。\r\n\r\n```go\r\nvar n float32 = 1.0001\r\nfmt.Println(n * n)\r\n```\r\n\r\nこのコードにおいては 1.0001 * 1.0001 = 1.00020001 という結果が出力されることを期待すると思います。しかしながら、ほとんどの x86 プロセッサでは、代わりに 1.0002 が出力されます。 \r\n\r\nGo言語の `float32` および `float64` 型は近似値であるため、いくつかのルールを念頭に置く必要があります。\r\n\r\n* 2 つの浮動小数点数を比較する場合は、その差が許容範囲内であることを確認する。\r\n* 加算または減算を実行する場合、精度を高めるために、同じ桁数の演算をグループ化する。\r\n* 精度を高めるため、一連の演算で加算、減算、乗算、除算が必要な場合は、乗算と除算を最初に実行する。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/19-floating-points/main.go)\r\n\r\n### スライスの長さと容量を理解していない (#20)\r\n\r\n???+ info \"要約\"\r\n\r\n    Go 開発者ならば、スライスの長さと容量の違いを理解するべきです。スライスの長さはスライス内の使用可能な要素の数であり、スライスの容量はバッキング配列内の要素の数です。\r\n\r\nセクション全文は[こちら](20-slice.md)。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/20-slice-length-cap/main.go)\r\n\r\n### 非効率なスライスの初期化 (#21)\r\n\r\n???+ info \"要約\"\r\n\r\n    スライスを作成するとき、長さがすでにわかっている場合は、指定された長さまたは容量でスライスを初期化しましょう。これにより、割り当ての数が減り、パフォーマンスが向上します。\r\n\r\n`make` を使用してスライスを初期化するときに、長さとオプションの容量を指定できます。これらのパラメータの両方に適切な値を渡すことが適当であるにもかかわらず、それを忘れるのはよくある間違いです。実際、複数のコピーが必要になり、一時的なバッキング配列をクリーンアップするために GC に追加の労力がかかる可能性があります。パフォーマンスの観点から言えば、Go ランタイムに手を差し伸べない理由はありません。 \r\n\r\nオプションは、指定された容量または指定された長さのスライスを割り当てることです。 これら 2 つの解決策のうち、2 番目の解決策の方がわずかに高速である傾向があることがわかりました。ただし、特定の容量と追加を使用すると、場合によっては実装と読み取りが容易になることがあります。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/21-slice-init/main.go)\r\n\r\n### nil と空のスライスを混同している (#22)\r\n\r\n???+ info \"要約\"\r\n\r\n    `encoding/json` や `reflect` パッケージなどを使用するときによくある混乱を避けるためには、nil スライスと空のスライスの違いを理解する必要があります。どちらも長さゼロ、容量ゼロのスライスですが、割り当てを必要としないのは nil スライスだけです。\r\n\r\nGo言語では、nil と空のスライスは区別されます。nil スライスは `nil` に等しいのに対し、空のスライスの長さはゼロです。nil スライスは空ですが、空のスライスは必ずしも`nil` であるとは限りません。一方、nil スライスには割り当ては必要ありません。このセクション全体を通して、以下の方法を使用することによって、状況に応じてスライスを初期化することを見てきました。\r\n\r\n * 最終的な長さが不明でスライスが空の場合は `var s []string` \r\n * nil と空のスライスを作成する糖衣構文としての `[]string(nil)` \r\n * 将来の長さがわかっている場合は `make([]string, length)` \r\n\r\n要素なしでスライスを初期化する場合、最後のオプション `[]string{}` は避けるべきです。最後に、予想外の動作を防ぐために、使用するライブラリが nil と空のスライスを区別しているかどうかを確認してみましょう。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/22-nil-empty-slice/)\r\n\r\n### スライスが空かどうかを適切に確認しない (#23)\r\n\r\n???+ info \"要約\"\r\n\r\n    スライスに要素が含まれていないことを確認するには、その長さを確認しましょう。これは、スライスが `nil` であるか空であるかに関係なく機能します。マップについても同様です。明確な API を設計するには、nil スライスと空のスライスを区別しないでください。\r\n\r\nスライスに要素があるかどうかを判断するには、スライスが nil かどうか、またはその長さが 0 に等しいかどうかを確認することで判断できます。スライスが空である場合とスライスが nil である場合の両方をカバーできるため、長さを確かめることが最良の方法です。\r\n\r\n一方、インタフェースを設計するときは、軽微なプログラミングエラーを起こさないよう nil スライスと空のスライスを区別しないようにする必要があります。スライスを返すときに、nil または空のスライスを返すかどうかは、意味的にも技術的にも違いはありません。コーラーにとってはどちらも同じことを意味するはずです。この原理はマップでも同じです。マップが空かどうかを確認するには、それが nil かどうかではなく、その長さを確認しましょう。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/23-checking-slice-empty/main.go)\r\n\r\n### スライスのコピーを正しく作成していない (#24)\r\n\r\n???+ info \"要約\"\r\n\r\n    組み込み関数 `copy` を使用してあるスライスを別のスライスにコピーするには、コピーされる要素の数が 2 つのスライスの長さの間の最小値に相当することに注意してください。\r\n\r\n要素をあるスライスから別のスライスにコピーする操作は、かなり頻繁に行われます。コピーを使用する場合、コピー先にコピーされる要素の数は 2 つのスライスの長さの間の最小値に相当することに注意する必要があります。また、スライスをコピーするための他の代替手段が存在することにも留意してください。そのため、コードベースでそれらを見つけても驚くことはありません。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/24-slice-copy/main.go)\r\n\r\n### `append` の使用による予想外の副作用 (#25)\r\n\r\n???+ info \"要約\"\r\n\r\n    2つの異なる関数が同じ配列に基づくスライスを使用する場合に、copy または完全スライス式を使用することで `append` による衝突を防ぐことができます。ただし、大きなスライスを縮小する場合、メモリリークを防ぐことができるのはスライスのコピーだけです。\r\n\r\nスライスを使用するときは、予想外の副作用につながる状況に直面する可能性があることを覚えておく必要があります。結果のスライスの長さがその容量より小さい場合、追加によって元のスライスが変更される可能性があります。起こり得る副作用の範囲を制限したい場合は、スライスのコピーまたは完全スライス式を使用できます。これにより、コピーを実行できなくなります。\r\n\r\n???+ note \"補足\"\r\n\r\n    `s[low:high:max]`（完全スライス式）――この命令文は、容量が `max - low` に等しいことを除けば、`s[low:high]` で作成されたスライスと同様のスライスを作成します。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/25-slice-append/main.go)\r\n\r\n### スライスとメモリリーク (#26)\r\n\r\n???+ info \"要約\"\r\n\r\n    ポインタのスライスまたはポインタフィールドを持つ構造体を操作する場合、スライス操作によって除外された要素を nil とすることでメモリリークを回避できます。\r\n\r\n#### 容量漏れ\r\n\r\n大きなスライスまたは配列をスライスすると、メモリ消費が高くなる可能性があることに注意してください。残りのスペースは GC によって再利用されず、少数の要素しか使用しないにもかかわらず、大きなバッキング配列が保持されます。スライスのコピーをすることで、このような事態を防ぐことができます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/26-slice-memory-leak/capacity-leak)\r\n\r\n#### スライスとポインタ\r\n\r\nポインタまたはポインタフィールドを含む構造体を使用してスライス操作をする場合、GC がこれらの要素を再利用しないことを知っておく必要があります。その場合の選択肢は、コピーを実行するか、残りの要素またはそのフィールドを明示的に `nil` とすることです。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/26-slice-memory-leak/slice-pointers)\r\n\r\n### 非効率なマップの初期化 (#27)\r\n\r\n???+ info \"要約\"\r\n\r\n    マップを作成するとき、その長さがすでにわかっている場合は、指定された長さで初期化します。これにより、割り当ての数が減り、パフォーマンスが向上します。\r\n\r\nマップは、キー・値ペアの順序なしコレクションを提供します。なお、それぞれのペアは固有のキーを持ちます。Go言語では、マップはハッシュテーブルデータ構造に基づいています。内部的には、ハッシュテーブルはバケットの配列であり、各バケットはキー・値ペアの配列へのポインタです。 \r\n\r\nマップに含まれる要素の数が事前にわかっている場合は、その初期サイズを指定して作成する必要があります。マップの増大は、十分なスペースを再割り当てし、すべての要素のバランスを再調整する必要があるため、計算量が非常に多くなりますが、これによりそれを回避することができます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/27-map-init/main_test.go)\r\n\r\n### マップとメモリリーク (#28)\r\n\r\n???+ info \"要約\"\r\n\r\n    マップはメモリ内で常に増大する可能性がありますが、縮小することはありません。したがって、メモリの問題が発生する場合は、マップを強制的に再生成したり、ポインタを使用したりするなど、さまざまな手段を試すことができます。\r\n\r\nセクション全文は[こちら](28-maps-memory-leaks.md)。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/28-map-memory-leak/main.go)\r\n\r\n### 誤った方法による値の比較 (#29)\r\n\r\n???+ info \"要約\"\r\n\r\n    Go言語で型を比較す​​るには、2 つの型が比較可能ならば、== 演算子と != 演算子を使用できます。真偽値、数値、文字列、ポインタ、チャネル、および構造体が完全に比較可能な型で構成されています。それ以外は、 `reflect.DeepEqual` を使用してリフレクションの代償を支払うか、独自の実装とライブラリを使用することができます。\r\n\r\n効果的に比較するには、 `==` と `!=` の使用方法を理解することが不可欠です。これらの演算子は、比較可能な被演算子で使用できます。 \r\n\r\n* _真偽値_ - 2 つの真偽値が等しいかどうかを比較します。 \r\n* _数値 (int、float、および complex 型)_ - 2 つの数値が等しいかどうかを比較します。 \r\n* _文字列_ - 2 つの文字列が等しいかどうかを比較します。 \r\n* _チャネル_ - 2 つのチャネルが同じ make 呼び出しによって作成されたか、または両方が nil であるかを比較します。 \r\n* _インタフェース_ - 2 つのインタフェースが同じ動的タイプと等しい動的値を持つかどうか、または両方が nil であるかどうかを比較します。 \r\n* _ポインタ_ - 2 つのポインタがメモリ内の同じ値を指しているか、または両方とも nil であるかを比較します。 \r\n* _構造体と配列_ - 類似した型で構成されているかどうかを比較します。\r\n\r\n???+ note \"補足\"\r\n\r\n    `?` 、 `>=` 、 `<` 、および `>` 演算子を数値型で使用して値を比較したり、文字列で字句順序を比較したりすることもできます。\r\n\r\n被演算子が比較できない場合（スライスとマップなど）、リフレクションなどの他の方法を利用する必要があります。リフレクションはメタプログラミングの一種であり、アプリケーションがその構造と動作を内省して変更する機能を指します。たとえば、Go言語では `reflect.DeepEqual` を使用できます。この関数は、2つの値を再帰的に調べることによって、2つの要素が完全に等しいかどうかを報告します。受け入れられる要素は、基本型に加えて、配列、構造体、スライス、マップ、ポインタ、インタフェース、関数です。しかし、最大の落とし穴はパフォーマンス上のペナルティです。 \r\n\r\n実行時のパフォーマンスが重要な場合は、独自のメソッドを実装することが最善となる可能性があります。\r\n\r\n追記：標準ライブラリには既に比較メソッドがいくつかあることを覚えておく必要があります。たとえば、最適化された `bytes.Compare` 関数を使用して、2つのバイトスライスを比較できます。独自のメソッドを実装する前に、車輪の再発明をしないようにしましょう。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/29-comparing-values/main.go)\r\n\r\n## 制御構造\r\n\r\n### 要素が `range` ループ内でコピーされることを知らない  (#30)\r\n\r\n???+ info \"要約\"\r\n\r\n    `range` ループ内の value 要素はコピーです。したがって、たとえば構造体を変更するには、そのインデックスを介してアクセスするか、従来の `for` ループを介してアクセスしましょう（変更する要素またはフィールドがポインタである場合を除く）。\r\n\r\nrange ループを使用すると、さまざまなデータ構造に反復処理を行うことができます。 \r\n\r\n * 文字列\r\n * 配列\r\n * 配列へのポインタ\r\n * スライス\r\n * マップ\r\n * 受信チャネル \r\n\r\n古典的な `for` ループと比較すると、`range` ループはその簡潔な構文のおかげで、これらのデータ構造のすべての要素に反復処理をするのに便利です。\r\n\r\nただし、range ループ内の値要素はコピーであることを覚えておく必要があります。したがって、値を変更する必要がある構造体の場合、変更する値またはフィールドがポインタでない限り、要素自体ではなくコピーのみを更新します。range ループまたは従来の for ループを使用してインデックス経由で要素にアクセスすることが推奨されます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/30-range-loop-element-copied/)\r\n\r\n### `range` ループ（チャネルと配列）での引数の評価方法を知らない (#31)\r\n\r\n???+ info \"要約\"\r\n\r\n    `range` 演算子に渡される式はループの開始前に 1 回だけ評価されることを理解すると、チャネルまたはスライスの反復処理における非効率な割り当てなどのありがちな間違いを回避できます。\r\n\r\nrange ループは、（タイプに関係なく）コピーを実行することにより、ループの開始前に、指定された式を 1 回だけ評価します。たとえば、誤った要素にアクセスしてしまう、というようなありがちな間違いを避けるために、この動作を覚えておく必要があります。たとえば\r\n\r\n```go\r\na := [3]int{0, 1, 2}\r\nfor i, v := range a {\r\n    a[2] = 10\r\n    if i == 2 {\r\n        fmt.Println(v)\r\n    }\r\n}\r\n```\r\n\r\nこのコードは、最後のインデックスを 10 に更新します。しかし、このコードを実行すると、10 は出力されません。 2 が出力されます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/31-range-loop-arg-evaluation/)\r\n\r\n###  `range` ループ内におけるポインタ要素の使用が及ぼす影響を分かっていない (#32)\r\n\r\n???+ info \"要約\"\r\n\r\n    ローカル変数を使用するか、インデックスを使用して要素にアクセスすると、ループ内でポインタをコピーする際の間違いを防ぐことができます。\r\n\r\n`range` ループを使用してデータ構造に反復処理を施す場合、すべての値が単一の一意のアドレスを持つ一意の変数に割り当てられることを思い出してください。ゆえに、各反復処理中にこの変数を参照するポインタを保存すると、同じ要素、つまり最新の要素を参照する同じポインタを保存することになります。この問題は、ループのスコープ内にローカル変数を強制的に作成するか、インデックスを介してスライス要素を参照するポインタを作成することで解決できます。どちらの解決策でも問題ありません。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/32-range-loop-pointers/)\r\n\r\n\r\n### マップの反復処理中に誤った仮定をする（反復処理中の順序付けとマップの挿入） (#33)\r\n\r\n???+ info \"要約\"\r\n\r\n    マップを使用するときに予測可能な出力を保証するには、マップのデータ構造が次のとおりであることに注意してください。 \r\n\r\n * データをキーで並べ替えません \r\n * 挿入順序は保持されません \r\n * 反復処理順序は決まっていません\r\n * ある反復処理中に追加された要素がその処理中に生成されることを保証しません\r\n\r\n<!-- TODO -->\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/33-map-iteration/main.go)\r\n\r\n### `break` 文がどのように機能するかを分かっていない (#34)\r\n\r\n???+ info \"要約\"\r\n\r\n    ラベルと `break` または `continue` の併用は、特定の命令文を強制的に中断します。これは、ループ内の `switch` または `select` 文で役立ちます。 \r\n\r\n通常、break 文はループの実行を終了するために使用されます。ループが switch または select と組み合わせて使用​​される場合、目的の命令文ではないのに中断させてしまう、というミスをすることが開発者にはよくあります。たとえば\r\n\r\n```go\r\nfor i := 0; i < 5; i++ {\r\n    fmt.Printf(\"%d \", i)\r\n\r\n    switch i {\r\n    default:\r\n    case 2:\r\n        break\r\n    }\r\n}\r\n```\r\n\r\nbreak 文は `for` ループを終了させるのではなく、代わりに `switch` 文を終了させます。したがって、このコードは 0 から 2 までを反復する代わりに、0 から 4 までを反復します（`0 1 2 3 4`）。\r\n\r\n覚えておくべき重要なルールの1つは、 `break` 文は最も内側の `for` 、`switch` 、または `select` 文の実行を終了するということです。前の例では、`switch` 文を終了します。 \r\n\r\n`switch` 文の代わりにループを中断する最も慣用的な方法はラベルを使用することです。\r\n\r\n```go hl_lines=\"1 8\"\r\nloop:\r\n    for i := 0; i < 5; i++ {\r\n        fmt.Printf(\"%d \", i)\r\n\r\n        switch i {\r\n        default:\r\n        case 2:\r\n            break loop\r\n        }\r\n    }\r\n```\r\n\r\nここでは、`loop` ラベルを `for` ループに関連付けます。 次に、`break` 文に `loop` ラベルを指定するので、switch ではなく loop が中断されます。よって、この新しいバージョンは予想どおり `0 1 2` を出力します。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/34-break/main.go)\r\n\r\n### ループ内で `defer` を使用する (#35)\r\n\r\n???+ info \"要約\"\r\n\r\n    関数内のループロジックの抽出は、各反復の最後での `defer` 文の実行につながります。\r\n\r\n`defer` 文は、上位ブロックの関数が戻るまで呼び出しの実行を遅らせます。これは主に定型コードを削減するために使用されます。たとえば、リソースを最終的に閉じる必要がある場合は、`defer` を使用して、`return` を実行する前にクロージャ呼び出しを繰り返すことを避けることができます。 \r\n\r\n`defer` でよくあるミスの1つは、_上位ブロック_ の関数が戻ったときに関数呼び出しがスケジュールされることを忘れることです。たとえば\r\n\r\n```go\r\nfunc readFiles(ch <-chan string) error {\r\n    for path := range ch {\r\n        file, err := os.Open(path)\r\n        if err != nil {\r\n            return err\r\n        }\r\n\r\n        defer file.Close()\r\n\r\n        // ファイルの処理をする\r\n    }\r\n    return nil\r\n}\r\n```\r\n\r\n`defer` 呼び出しは、各ループ反復中ではなく、`readFiles` 関数が返されたときに実行されます。 `readFiles` が返らない場合、ファイル記述子は永久に開いたままになり、リークが発生します。 \r\n\r\nこの問題を解決するための一般的な手段の1つは、 `defer` の後に、各反復中に呼び出される上位ブロックの関数を作成することです。\r\n\r\n```go\r\nfunc readFiles(ch <-chan string) error {\r\n    for path := range ch {\r\n        if err := readFile(path); err != nil {\r\n            return err\r\n        }\r\n    }\r\n    return nil\r\n}\r\n\r\nfunc readFile(path string) error {\r\n    file, err := os.Open(path)\r\n    if err != nil {\r\n        return err\r\n    }\r\n\r\n    defer file.Close()\r\n\r\n    // ファイルの処理をする\r\n    return nil\r\n}\r\n```\r\n\r\n別の解決策は、`readFile` 関数をクロージャにすることですが、本質的には同じです。別の上位ブロックの関数を追加して、各反復中に `defer` 呼び出しを実行します。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/35-defer-loop/main.go)\r\n\r\n## 文字列\r\n\r\n### ルーンを理解していない (#36)\r\n\r\n???+ info \"要約\"\r\n\r\n    ルーンが Unicode コードポイントの概念に対応し、複数のバイトで構成される可能性があることを理解することは、 Go 開発者が文字列を正確に操作するために不可欠です。\r\n\r\nGo言語ではルーンがあらゆる場所に使用されるため、次の点を理解することが重要です。 \r\n\r\n* 文字セットは文字の集合ですが、エンコーディングは文字セットをバイナリに変換する方法を記述します。\r\n* Go言語では、文字列は任意のバイトの不変スライスを参照します。\r\n* Go言語のソースコードは UTF-8 でエンコードされています。したがって、すべの文字列リテラルは UTF-8 文字列です。ただし、文字列には任意のバイトが含まれる可能性があるため、文字列が（ソースコードではない）他の場所から取得された場合、その文字列が UTF-8 エンコーディングに基づいている保証はありません。\r\n* `rune` は Unicode コードポイントの概念に対応し、単一の値で表されるアイテムを意味します。\r\n* UTF-8 を使用すると、Unicode コードポイントを 1 ～ 4 バイトにエンコードできます。\r\n* Go言語で文字列に対して `len()` を使用すると、ルーン数ではなくバイト数が返されます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/36-rune/main.go)\r\n\r\n### 文字列に対する不正な反復処理 (#37)\r\n\r\n???+ info \"要約\"\r\n\r\n    `range` 演算子を使用して文字列を反復処理すると、ルーンのバイトシーケンスの開始インデックスに対応するインデックスを使用してルーンが反復処理されます。特定のルーンインデックス（ 3 番目のルーンなど）にアクセスするには、文字列を `[]rune` に変換します。 \r\n\r\n文字列の反復処理は、開発者にとって一般的な操作です。おそらく、文字列内の各ルーンに対して操作を実行するか、特定の部分文字列を検索する独自の関数を実装する必要があるでしょう。どちらの場合も、文字列の異なるルーンを反復処理する必要があります。しかし、反復処理がどのように機能するかについては困惑しやすいです。 \r\n\r\n次の例を考えてみましょう。\r\n\r\n```go\r\ns := \"hêllo\"\r\nfor i := range s {\r\n    fmt.Printf(\"position %d: %c\\n\", i, s[i])\r\n}\r\nfmt.Printf(\"len=%d\\n\", len(s))\r\n```\r\n\r\n```\r\nposition 0: h\r\nposition 1: Ã\r\nposition 3: l\r\nposition 4: l\r\nposition 5: o\r\nlen=6\r\n```\r\n\r\n混乱を招く可能性のある 3 点を取り上げましょう。 \r\n\r\n* 2 番目のルーンは、出力では ê ではなく Ã になります。 \r\n* position 1 から position 3 にジャンプしました。 position 2 には何があるのでしょうか。\r\n* len は 6 を返しますが、s には 5 つのルーンしか含まれていません。 \r\n\r\n結果の最後から見ていきましょう。len はルーン数ではなく、文字列内のバイト数を返すことはすでに述べました。文字列リテラルを `s` に割り当てているため、`s` は UTF-8 文字列です。一方、特殊文字「ê」は 1 バイトでエンコードされません。 2 バイト必要です。したがって、`len(s)` を呼び出すと 6 が返されます。 \r\n\r\n前の例では、各ルーンを反復処理していないことを理解する必要があります。代わりに、ルーンの各開始インデックスを反復処理します。 \r\n\r\n![](img/rune.png) \r\n\r\n`s[i]` を出力しても i 番目のルーンは出力されません。インデックス `i` のバイトの UTF-8 表現を出力します。したがって、 `hêllo` の代わりに `hÃllo` を出力がされます。 \r\n\r\nさまざまなルーン文字をすべて出力したい場合は、 `range` 演算子の value 要素を使用することができます。\r\n\r\n```go\r\ns := \"hêllo\"\r\nfor i, r := range s {\r\n    fmt.Printf(\"position %d: %c\\n\", i, r)\r\n}\r\n```\r\n\r\nまたは、文字列をルーンのスライスに変換し、それを反復処理することもできます。\r\n\r\n```go hl_lines=\"2\"\r\ns := \"hêllo\"\r\nrunes := []rune(s)\r\nfor i, r := range runes {\r\n    fmt.Printf(\"position %d: %c\\n\", i, r)\r\n}\r\n```\r\n\r\nこの解決策では、以前の解決策と比較して実行時のオーバーヘッドが発生することに注意してください。実際、文字列をルーンのスライスに変換するには、追加のスライスを割り当て、バイトをルーンに変換する必要があります。文字列のバイト数を n とすると、時間計算量は O(n) になります。したがって、すべてのルーンを反復処理する場合は、最初の解決策を使用するべきです。 \r\n\r\nただし、最初の方法を使用して文字列の i 番目のルーンにアクセスしたい場合は、ルーンインデックスにアクセスできません。代わりに、バイトシーケンス内のルーンの開始インデックスがわかります。\r\n\r\n```go\r\ns := \"hêllo\"\r\nr := []rune(s)[4]\r\nfmt.Printf(\"%c\\n\", r) // o\r\n```\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/37-string-iteration/main.go)\r\n\r\n### trim 関数の誤用 (#38)\r\n\r\n???+ info \"要約\"\r\n\r\n    `strings.TrimRight` ・ `strings.TrimLeft` は、指定されたセットに含まれるすべての末尾・先頭のルーンを削除しますが、 `strings.TrimSuffix` ・ `strings.TrimPrefix` は、指定された接尾辞・接頭辞のない文字列を返します。\r\n\r\nたとえば\r\n\r\n```go\r\nfmt.Println(strings.TrimRight(\"123oxo\", \"xo\"))\r\n```\r\n\r\nは 123 を出力します\r\n\r\n![](img/trim.png)\r\n\r\n逆に、 `strings.TrimLeft` は、セットに含まれる先頭のルーンをすべて削除します。 \r\n\r\n一方、`strings.TrimSuffix` ・ `strings.TrimPrefix` は、指定された末尾の接尾辞・接頭辞を除いた文字列を返します。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/38-trim/main.go)\r\n\r\n### 最適化が不十分な文字列の連結 (#39)\r\n\r\n???+ info \"要約\"\r\n\r\n    文字列のリストの連結は、反復ごとに新しい文字列が割り当てられないように、`strings.Builder` を使用して行う必要があります。\r\n\r\n`+=` 演算子を用いてスライスのすべての文字列要素を連結する `concat` 関数を考えてみましょう。\r\n\r\n```go\r\nfunc concat(values []string) string {\r\n    s := \"\"\r\n    for _, value := range values {\r\n        s += value\r\n    }\r\n    return s\r\n}\r\n```\r\n\r\n各反復中に、 `+=` 演算子は `s` と value 文字列を連結します。一見すると、この関数は間違っていないように見えるかもしれません。しかし、この実装は、文字列の核となる特性の1つである不変性を忘れています。したがって、各反復では `s` は更新されません。メモリ内に新しい文字列を再割り当てするため、この関数のパフォーマンスに大きな影響を与えます。 \r\n\r\n幸いなことに、 `strings.Builder` を用いることで、この問題に対処する解決策があります。\r\n\r\n```go hl_lines=\"2 4\"\r\nfunc concat(values []string) string {\r\n    sb := strings.Builder{}\r\n    for _, value := range values {\r\n        _, _ = sb.WriteString(value)\r\n    }\r\n    return sb.String()\r\n}\r\n```\r\n\r\n各反復中に、value の内容を内部バッファに追加する `WriteString` メソッドを呼び出して結果の文字列を構築し、メモリのコピーを最小限に抑えることができました。\r\n\r\n???+ note \"補足\"\r\n\r\n    `WriteString` は 2 番目の出力としてエラーを返しますが、意図的に無視しましょう。実際、このメソッドは nil エラー以外を返すことはありません。では、このメソッドがシグネチャの一部としてエラーを返す目的は何でしょうか。`strings.Builder` は `io.StringWriter` インタフェースを実装しており、これには `WriteString(s string) (n int, err error)` という1つのメソッドが含まれています。したがって、このインタフェースに準拠するには、`WriteString` はエラーを返さなければならないのです。\r\n\r\n内部的には、`strings.Builder` はバイトスライスを保持します。 `WriteString` を呼び出すたびに、このスライスに追加する呼び出しが行われます。これには2つの影響があります。まず、 `append` の呼び出しが衝突状態を引き起こす可能性があるため、この構造体は同時に使用されるべきではありません。2番目の影響は、 [非効率なスライスの初期化 (#21)](#21) で見たものです。スライスの将来の長さがすでにわかっている場合は、それを事前に割り当てる必要があります。そのために、`strings.Builder` は別の `n` バイトのためのスペースを保証するメソッド `Grow(n int)` を持っています。\r\n\r\n```go\r\nfunc concat(values []string) string {\r\n    total := 0\r\n    for i := 0; i < len(values); i++ {\r\n        total += len(values[i])\r\n    }\r\n\r\n    sb := strings.Builder{}\r\n    sb.Grow(total) (2)\r\n    for _, value := range values {\r\n        _, _ = sb.WriteString(value)\r\n    }\r\n    return sb.String()\r\n}\r\n```\r\n\r\nベンチマークを実行して 3 つのバージョン（ `+=` を使用した V1 、事前割り当てなしで `strings.Builder{}` を使用した V2 、事前割り当てありの `strings.Builder{}` を使用した V3 ）を比較してみましょう。入力スライスには 1,000 個の文字列が含まれており、各文字列には 1,000 バイトが含まれています。\r\n\r\n```\r\nBenchmarkConcatV1-4             16      72291485 ns/op\r\nBenchmarkConcatV2-4           1188        878962 ns/op\r\nBenchmarkConcatV3-4           5922        190340 ns/op\r\n```\r\n\r\nご覧のとおり、最新バージョンが最も効率的で、V1 より 99% 、V2 より 78% 高速です。 \r\n\r\n`strings.Builder` は、文字列のリストを連結するための解決策として推奨されます。通常、これはループ内で使用する必要があります。いくつかの文字列 （名前と姓など）を連結するだけの場合、 `strings.Builder` の使用は、 `+=` 演算子や `fmt.Sprintf` と比べて可読性が低くなるからです。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/39-string-concat/)\r\n\r\n### 無駄な文字列変換 (#40)\r\n\r\n???+ info \"要約\"\r\n\r\n    `bytes` パッケージは `strings` パッケージと同じ操作を提供してくれることを覚えておくと、余分なバイト・文字列変換を避けることができます。\r\n\r\n文字列または `[]byte` を扱うことを選択する場合、ほとんどのプログラマーは利便性のために文字列を好む傾向があります。しかし、ほとんどの I/O は実際には `[]byte` で行われます。たとえば、`io.Reader`、`io.Writer`、および `io.ReadAll` は文字列ではなく `[]byte` を処理します。 \r\n\r\n文字列と `[]byte` のどちらを扱うべきか迷ったとき、`[]byte` を扱う方が必ずしも面倒だというわけではないことを思い出してください。strings パッケージからエクスポートされたすべての関数には、`bytes` パッケージに代替機能があります。 `Split`、`Count`、`Contains`、`Index` などです。したがって、I/O を実行しているかどうかに関係なく、文字列の代わりにバイトを使用してワークフロー全体を実装でき、追加の変換コストを回避できるかどうかを最初に確認しましょう。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/40-string-conversion/main.go)\r\n\r\n### 部分文字列とメモリリーク (#41)\r\n\r\n???+ info \"要約\"\r\n\r\n    部分文字列の代わりにコピーを使用すると、部分文字列操作によって返される文字列が同じバイト配列によってサポートされるため、メモリリークを防ぐことができます。\r\n\r\n[スライスとメモリリーク (#26)](#26) では、スライスまたは配列のスライスがメモリリークの状況を引き起こす可能性があることを確認しました。この原則は、文字列および部分文字列の操作にも当てはまります。 \r\n\r\nGo言語で部分文字列操作を使用するときは、2 つのことに留意する必要があります。まず、提供される間隔はルーン数ではなく、バイト数に基づいています。次に、結果の部分文字列が最初の文字列と同じバッキング配列を共有するため、部分文字列操作によりメモリリークが発生する可能性があります。これを防ぐ方法は、文字列のコピーを手動で実行するか、Go 1.18 から実装されている `strings.Clone` を使用することです。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/41-substring-memory-leak/main.go)\r\n\r\n## 関数とメソッド\r\n\r\n### どの型のレシーバーを使用すればよいかわかっていない (#42)\r\n\r\n???+ info \"要約\"\r\n\r\n    値レシーバーとポインタレシーバーのどちらを使用するかは、どの型なのか、変化させる必要があるかどうか、コピーできないフィールドが含まれているかどうか、オブジェクトはどれくらい大きいのか、などの要素に基づいて決定する必要があります。分からない場合は、ポインタレシーバを使用してください。\r\n\r\n値レシーバーとポインタレシーバーのどちらを選択するかは、必ずしも簡単ではありません。選択に役立ついくつかの条件について説明しましょう。 \r\n\r\n_ポインタレシーバーでなければならない_ とき\r\n\r\n* メソッドがレシーバーを変化させる必要がある場合。このルールは、受信側がスライスであり、メソッドが要素を追加する必要がある場合にも有効です。\r\n\r\n  ```go\r\n  type slice []int\r\n\r\n  func (s *slice) add(element int) {\r\n      *s = append(*s, element)\r\n  }\r\n  ```\r\n\r\n* メソッドレシーバーにコピーできないフィールドが含まれている場合。sync パッケージの型部分はその一例になります（ [sync 型のコピー (#74)](#sync-74) を参照）。\r\n\r\n_ポインタレシーバーであるべき_ とき\r\n\r\n* レシーバーが大きなオブジェクトの場合。ポインタを使用すると、大規模なコピーの作成が防止されるため、呼び出しがより効率的になります。どれくらいの大きさなのか確証がない場合は、ベンチマークが解決策になる可能性があります。多くの要因に依存するため、特定のサイズを指定することはほとんど不可能です。 \r\n\r\n_値レシーバーでなければならない_ とき\r\n\r\n* レシーバーの不変性を強制する必要がある場合。 \r\n* レシーバーがマップ、関数、チャネルの場合。それ以外の場合はコンパイルエラーが発生します。 \r\n\r\n_値レシーバーであるべき_ とき\r\n\r\n* レシーバーが変化させる必要のないスライスの場合。 \r\n* レシーバーが、`time.Time` などの小さな配列または構造体で、可変フィールドを持たない値型である場合。 \r\n* レシーバーが `int`、`float64`、または `string` などの基本型の場合。 \r\n\r\nもちろん、特殊なケースは常に存在するため、すべてを網羅することは不可能ですが、このセクションの目標は、ほとんどのケースをカバーするためのガイダンスを提供することです。通常は、そうしない正当な理由がない限り、値レシーバーを使用して間違いありません。分からない場合は、ポインタレシーバを使用する必要があります。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/42-receiver/)\r\n\r\n### 名前付き結果パラメータをまったく使用していない (#43)\r\n\r\n???+ info \"要約\"\r\n\r\n    名前付き結果パラメーターの使用は、特に複数の結果パラメーターが同じ型を持つ場合、関数・メソッドの読みやすさを向上させる効率的な方法です。場合によっては、名前付き結果パラメータはゼロ値に初期化されるため、この方法が便利ですらあることもあります。ただし潜在的な副作用には注意してください。\r\n\r\n関数またはメソッドでパラメータを返すとき、これらのパラメータに名前を付けて、通常の変数として使用できます。結果パラメーターに名前を付けると、関数・メソッドの開始時にそのパラメーターはゼロ値に初期化されます。名前付き結果パラメータを使用すると、 むき出しの return 文（引数なし） を呼び出すこともできます。その場合、結果パラメータの現在の値が戻り値として使用されます。 \r\n\r\n以下は、名前付き結果パラメータ `b` を用いた例です。\r\n\r\n```go\r\nfunc f(a int) (b int) {\r\n    b = a\r\n    return\r\n}\r\n```\r\n\r\nこの例では、結果パラメータに名前 `b` を付けています。引数なしで return を呼び出すと、`b` の現在の値が返されます。 \r\n\r\n場合によっては、名前付きの結果パラメーターによって可読性が向上することもあります。たとえば、2 つのパラメーターが同じ型である場合などです。その他にも、利便性のために用いることができます。ゆえに、明確な利点がある場合は、慎重になりながらも名前付き結果パラメータを使用するべきです。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/43-named-result-parameters/main.go)\r\n\r\n### 名前付き結果パラメータによる予想外の副作用 (#44)\r\n\r\n???+ info \"要約\"\r\n\r\n    [#43](#43) を参照してください。\r\n\r\n名前付き結果パラメータが状況によっては役立つ理由について説明しました。 ただし、これらはゼロ値に初期化されるため、十分に注意しないと、軽微なバグが発生する可能性があります。たとえば、このコードはどこが間違っているでしょうか。\r\n\r\n```go\r\nfunc (l loc) getCoordinates(ctx context.Context, address string) (\r\n    lat, lng float32, err error) {\r\n    isValid := l.validateAddress(address) (1)\r\n    if !isValid {\r\n        return 0, 0, errors.New(\"invalid address\")\r\n    }\r\n\r\n    if ctx.Err() != nil { (2)\r\n        return 0, 0, err\r\n    }\r\n\r\n    // 座標を取得して返す\r\n}\r\n```\r\n\r\n一瞥しただけではエラーは明らかではないかもしれません。`if ctx.Err() != nil` スコープで返されるエラーは `err` です。しかし、`err` 変数には値を割り当てていません。`error` 型のゼロ値、 `nil` に割り当てられたままです。したがって、このコードは常に nil エラーを返します。 \r\n\r\n名前付き結果パラメータを使用する場合、各パラメータはゼロ値に初期化されることに注意してください。このセクションで説明したように、これにより、見つけるのが必ずしも簡単ではない軽微なバグが発生する可能性があります。ゆえに、潜在的な副作用を避けるために、名前付き結果パラメーターを使用するときは注意してください。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/44-side-effects-named-result-parameters/main.go)\r\n\r\n### nil レシーバーを返す (#45)\r\n\r\n???+ info \"要約\"\r\n\r\n    インタフェースを返すときは、nil ポインタを返すのではなく、明示的な nil 値を返すように注意してください。そうしなければ、意図しない結果が発生し、呼び出し元が nil ではない値を受け取る可能性があります。\r\n\r\n<!-- TODO -->\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/45-nil-receiver/main.go)\r\n\r\n### 関数入力にファイル名を使用している (#46)\r\n\r\n???+ info \"要約\"\r\n\r\n    ファイル名の代わりに `io.Reader` 型を受け取るように関数を設計すると、関数の再利用性が向上し、テストが容易になります。\r\n\r\nファイル名をファイルから読み取るための関数入力として受け入れることは、ほとんどの場合、「コードの臭い」とみなされるべきです（ `os.Open` などの特定の関数を除く）。複数のファイルを作成することにになるかもしれず、単体テストがより複雑になる可能性があるからです。また、関数の再利用性も低下します （ただし、すべての関数が再利用されるわけではありません）。 `io.Reader` インタフェースを使用すると、データソースが抽象化されます。入力がファイル、文字列、HTTP リクエスト、gRPC リクエストのいずれであるかに関係なく、実装は再利用でき、簡単にテストできます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/46-function-input/)\r\n\r\n### `defer` 引数とレシーバーがどのように評価されるかを知らない（引数の評価、ポインター、および値レシーバー） (#47)\r\n\r\n???+ info \"要約\"\r\n\r\n    ポインタを `defer` 関数に渡すことと、呼び出しをクロージャ内にラップすることが、引数とレシーバーの即時評価を克服するために実現可能な解決策です。 \r\n\r\n`defer` 関数では、引数は、上位ブロックの関数が戻ってからではなく、すぐに評価されます。たとえば、このコードでは、常に同じステータス――空の文字列――で `notify` と `incrementCounter` を呼び出します。\r\n\r\n```go\r\nconst (\r\n    StatusSuccess  = \"success\"\r\n    StatusErrorFoo = \"error_foo\"\r\n    StatusErrorBar = \"error_bar\"\r\n)\r\n\r\nfunc f() error {\r\n    var status string\r\n    defer notify(status)\r\n    defer incrementCounter(status)\r\n\r\n    if err := foo(); err != nil {\r\n        status = StatusErrorFoo\r\n        return err\r\n    }\r\n\r\n    if err := bar(); err != nil {\r\n        status = StatusErrorBar\r\n        return err\r\n    }\r\n\r\n    status = StatusSuccess\r\n    return nil\r\n}\r\n```\r\n\r\nたしかに、`notify(status)` と `incrementCounter(status)` を `defer` 関数として呼び出しています。したがって、Go言語は、defer を使用した段階で `f` がステータスの現在の値を返すと、これらの呼び出しの実行を遅らせ、空の文字列を渡します。 \r\n\r\n`defer` を使い続けたい場合の主な方法は 2 つあります。 \r\n\r\n最初の解決策は文字列ポインタを渡すことです。\r\n\r\n```go hl_lines=\"3 4\"\r\nfunc f() error {\r\n    var status string\r\n    defer notify(&status) \r\n    defer incrementCounter(&status)\r\n\r\n    // 関数のそれ以外の部分は変更なし\r\n}\r\n```\r\n\r\n`defer` を使用すると、引数（ここではステータスのアドレス）がすぐに評価されます。ステータス自体は関数全体で変更されますが、そのアドレスは割り当てに関係なく一定のままです。よって、`notify` または `incrementCounter` が文字列ポインタによって参照される値を使用する場合、期待どおりに動作します。ただし、この解決策では 2 つの関数のシグネチャを変更する必要があり、それが常に可能であるとは限りません。 \r\n\r\n別の解決策があります――クロージャ（本体の外部から変数を参照する匿名関数値）を `defer` 文として呼び出すことです。\r\n\r\n```go hl_lines=\"3 4 5 6\"\r\nfunc f() error {\r\n    var status string\r\n    defer func() {\r\n        notify(status)\r\n        incrementCounter(status)\r\n    }()\r\n\r\n    // 関数のそれ以外の部分は変更なし\r\n}\r\n```\r\n\r\nここでは、`notify` と `incrementCounter` の両方の呼び出しをクロージャ内にラップします。このクロージャは、本体の外部からステータス変数を参照します。ゆえに、`status` は、`defer` を呼び出したときではなく、クロージャが実行されたときに評価されます。この解決策は正しく機能する上に、シグネチャを変更するために `notify` や `incrementCounter` を必要としません。 \r\n\r\nこの動作はメソッドレシーバーにも適用されることにも注意してください。レシーバーはすぐに評価されます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/47-defer-evaluation/)\r\n\r\n## エラー処理\r\n\r\n### パニック (#48)\r\n\r\n???+ info \"要約\"\r\n\r\n    `panic` の使用は、Go言語でエラーに対処するための手段です。ただし、これは回復不能な状況でのみ使用するようにしてください。たとえば、ヒューマンエラーを通知する場合や、必須の依存関係の読み込みに失敗した場合などです。\r\n\r\nGo言語では、panic は通常の流れを停止する組み込み関数です。\r\n\r\n```go\r\nfunc main() {\r\n    fmt.Println(\"a\")\r\n    panic(\"foo\")\r\n    fmt.Println(\"b\")\r\n}\r\n```\r\n\r\nこのコードは a を出力し、b を出力する前に停止します。\r\n\r\n```\r\na\r\npanic: foo\r\n\r\ngoroutine 1 [running]:\r\nmain.main()\r\n        main.go:7 +0xb3\r\n```\r\n\r\npanic の使用は慎重にすべきです。代表的なケースが 2 つあり、1 つはヒューマンエラーを通知する場合（例: [`sql.Register`](https://cs.opensource.google/go/go/+/refs/tags/go1.20.7:src/database/sql/sql.go;l=44)ドライバーが `nil` または既に登録されている場合に panic を起こします）、もう 1 つはアプリケーションが必須の依存関係の生成に失敗した場合です。結果として、例外的にアプリケーションを停止します。それ以外のほとんどの場合においては、エラー処理は、最後の戻り引数として適切なエラー型を返す関数を通じて行うべきです。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/48-panic/main.go)\r\n\r\n### エラーをラップすべきときを知らない (#49)\r\n\r\n???+ info \"要約\"\r\n\r\n    エラーをラップすると、エラーをマークしたり、追加のコンテキストを提供したりできます。ただし、エラーラッピングにより、呼び出し元がソースエラーを利用できるようになるため、潜在的な結合が発生します。それを避けたい場合は、エラーラッピングを使用しないでください。\r\n\r\nGo 1.13 以降、%w ディレクティブを使用すれば簡単にエラーをラップできるようになりました。エラーラッピングとは、ソースエラーも使用できるようにするラッパーコンテナ内でエラーをラップまたはパックすることです。一般に、エラーラッピングの主な使用例は次の 2 つです。 \r\n\r\n* エラーにさらにコンテキストを加える\r\n* エラーを特定のエラーとしてマークする \r\n\r\nエラーを処理するとき、エラーをラップするかどうかを決定できます。ラッピングとは、エラーにさらにコンテキストを追加したり、エラーを特定のタイプとしてマークしたりすることです。エラーをマークする必要がある場合は、独自のエラー型を作成する必要があります。ですが、新たにコンテキストを加えたいだけの場合は、新しいエラー型を作成する必要がないため、%w ディレクティブを指定して fmt.Errorf を使用しましょう。ただし、エラーラッピングにより、呼び出し元がソースエラーを利用できるようになるため、潜在的な結合が生じます。それを避けたい場合は、エラーのラッピングではなく、エラーの変換を使用する必要があります。たとえば、%v ディレクティブを指定した fmt.Errorf を使用します。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/49-error-wrapping/main.go)\r\n\r\n### エラー型の不正な比較 (#50)\r\n\r\n???+ info \"要約\"\r\n\r\n    Go 1.13 のエラーラッピングを `%w` ディレクティブと `fmt.Errorf` で使用する場合、型に対するエラーの比較は `errors.As` を通じて行う必要があります。そうでなければ、返されたエラーがラップされている場合、評価に失敗します。\r\n\r\n<!-- TODO -->\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/50-compare-error-type/main.go)\r\n\r\n### エラー値の不正な比較 (#51)\r\n\r\n???+ info \"要約\"\r\n\r\n    Go 1.13 のエラーラッピングを `%w` ディレクティブと `fmt.Errorf` で使用する場合、エラーと値の比較は `errors.As` を通じて行う必要があります。そうでなければ、返されたエラーがラップされている場合、評価に失敗します。 \r\n\r\nセンチネルエラーはグローバル変数として定義されたエラーのことです。\r\n\r\n```go\r\nimport \"errors\"\r\n\r\nvar ErrFoo = errors.New(\"foo\")\r\n```\r\n一般に、慣例として `Err` で始め、その後にエラー型を続けます。ここでは `ErrFoo` です。センチネルエラーは、_予期される_ エラー、つまりクライアントが確認することを期待するエラーを伝えます。一般的なガイドラインとして\r\n\r\n* 予期されるエラーはエラー値（センチネルエラー）として設計する必要があります： `var ErrFoo =errors.New(\"foo\")`。 \r\n* 予期しないエラーはエラー型として設計する必要があります： `BarError` は `error` インタフェースを実装した上で `type BarError struct { ... }`。 \r\n\r\nアプリケーションで `%w` ディレクティブと `fmt.Errorf` を使用してエラーラップを使用する場合、特定の値に対するエラーのチェックは `==` の代わりに `errors.Is` を使用して行いましょう。それによって、センチネルエラーがラップされている場合でも、`errors.Is` はそれを再帰的にアンラップし、チェーン内の各エラーを提供された値と比較できます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/51-comparing-error-value/main.go)\r\n\r\n### エラーの 2 回処理 (#52)\r\n\r\n???+ info \"要約\"\r\n\r\n    ほとんどの場合、エラーは 1 回で処理されるべきです。エラーをログに記録することは、エラーを処理することです。すなわち、ログに記録するかエラーを返すかを選択する必要があります。多くの場合、エラーラッピングは、エラーに追加のコンテキストを提供し、ソースエラーを返すことができるため、解決策になります。 \r\n\r\nエラーを複数回処理することは、特にGo言語に限らず、開発者が頻繁にやってしまうミスです。これにより、同じエラーが複数回ログに記録され、デバッグが困難になる状況が発生する可能性があります。 \r\n\r\nエラー処理は 1 度で済ますべきだということを覚えておきましょう。エラーをログに記録することは、エラーを処理することです。つまり、行うべきは、ログに記録するか、エラーを返すかのどちらかだということです。これにより、コードが簡素化され、エラーの状況についてより適切な洞察が得られます。エラーラッピングは、ソースエラーを伝え、エラーにコンテキストを追加できるため、最も使い勝手の良い手段になります。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/52-handling-error-twice/main.go)\r\n\r\n### エラー処理をしない (#53)\r\n\r\n???+ info \"要約\"\r\n\r\n    関数呼び出し中であっても、`defer` 関数内であっても、エラーを無視するときは、ブランク識別子を使用して明確に行うべきです。そうしないと、将来の読み手がそれが意図的だったのか、それともミスだったのか困惑する可能性があります。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/53-not-handling-error/main.go)\r\n\r\n### `defer` エラーを処理しない (#54)\r\n\r\n???+ info \"要約\"\r\n\r\n    多くの場合、`defer` 関数によって返されるエラーを無視すべきではありません。状況に応じて、直接処理するか、呼び出し元に伝えましょう。これを無視する場合は、ブランク識別子を使用してください。 \r\n\r\n次のコードを考えてみましょう。\r\n\r\n```go\r\nfunc f() {\r\n  // ...\r\n  notify() // エラー処理は省略されています\r\n}\r\n\r\nfunc notify() error {\r\n  // ...\r\n}\r\n```\r\n\r\n保守性の観点から、このコードはいくつかの問題を引き起こす可能性があります。ある人がこれを読むことを考えてみます。読み手は、notify がエラーを返すにもかかわらず、そのエラーが親関数によって処理されないことに気づきます。エラー処理が意図的であるかどうかを果たして推測できるでしょうか。以前の開発者がそれを処理するのを忘れたのか、それとも意図的に処理したのかを知ることができるでしょうか。\r\n\r\nこれらの理由により、エラーを無視したい場合、ブランク識別子（ `_` ）を使うほかありません。\r\n\r\n```go\r\n_ = notify\r\n```\r\n\r\nコンパイルと実行時間の点では、この方法は最初のコード部分と比べて何も変わりません。しかし、この新しいバージョンでは、私たちがエラーに関心がないことを明らかにしています。また、エラーが無視される理由を示すコメントを追加することもできます。\r\n\r\n```go\r\n// 最大でも 1 回の伝達 \r\n// それゆえ、エラーが発生した場合にそれらの一部が失われることは許容されます\r\n_ = notify()\r\n```\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/54-defer-errors/main.go)\r\n\r\n## 並行処理：基礎\r\n\r\n### 並行処理と並列処理の混同 (#55)\r\n\r\n???+ info \"要約\"\r\n\r\n    並行処理と並列処理の基本的な違いを理解することは、 Go 開発者にとって必須です。並行処理は構造に関するものですが、並列処理は実行に関するものです。 \r\n\r\n並行処理と並列処理は同じではありません。 \r\n\r\n* 並行処理は構造に関するものです。別々の並行ゴルーチンが取り組むことができるさまざまな段階を導入することで、逐次処理を並行処理に変更できます。 \r\n* 並列処理は実行に関するものです。並列ゴルーチンをさらに追加することで、段階レベルで並列処理を使用できます。 \r\n\r\nまとめると、並行処理は、並列化できる部分をもつ問題を解決するための構造を提供します。すなわち、_並行処理により並列処理が可能_ になります 。\r\n\r\n<!-- TODO Include Rob Pike's talk link-->\r\n\r\n### 並行処理のほうが常に早いと考えている (#56)\r\n\r\n???+ info \"要約\"\r\n\r\n    熟練した開発者になるには、並行処理が必ずしも高速であるとは限らないことを認識する必要があります。最小限のワークロードの並列処理を伴う解決策は、必ずしも逐次処理より高速であるとは限りません。逐次処理と並行処理のベンチマークは、仮定を検証する方法であるべきです。\r\n\r\nセクション全文は[こちら](56-concurrency-faster.md)。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/56-faster/)\r\n\r\n### チャネルまたはミューテックスをいつ使用するべきかについて戸惑っている (#57)\r\n\r\n???+ info \"要約\"\r\n\r\n    ゴルーチンの相互作用を認識していることは、チャネルとミューテックスのどちらを選択するかを決定するときにも役立ちます。一般に、並列ゴルーチンには同期が必要であり、したがってミューテックスが必要です。反対に、並行ゴルーチンは通常、調整とオーケストレーション、つまりチャネルを必要とします。 \r\n\r\n並行処理の問題を考慮すると、チャネルまたはミューテックスを使用した解決策を実装できるかどうかが必ずしも明確ではない可能性があります。Go言語は通信によるメモリの共有を促進するため、起こりうる間違いのうちの一つは、ユースケースにかかわらず、チャネルの使用を常に強制することです。しかしながら、2 つの方法は補完的なものであると見なすべきです。  \r\n\r\nチャネルまたはミューテックスはどのような場合に使用する必要があるのでしょうか。次の図の例をバックボーンとして使用します。この例には、特定の関係を持つ 3 つの異なるゴルーチンがあります。 \r\n\r\n* G1 と G2 は並列ゴルーチンです。チャネルからメッセージを受信し続ける同じ関数を実行する 2 つのゴルーチン、あるいは同じ HTTP ハンドラを同時に実行する 2 つのゴルーチンかもしれません。 \r\n* G1 と G3 は並行ゴルーチンであり、G2 と G3 も同様です。すべてのゴルーチンは全体の並行構造の一部ですが、G1 と G2 が最初のステップを実行し、G3 が次のステップを実行します。 \r\n\r\n<!-- TODO Include figure-->\r\n\r\n原則として、並列ゴルーチンは、スライスなどの共有リソースにアクセスしたり変更したりする必要がある場合などに、_同期_する必要があります。同期はミューテックスでは強制されますが、どのチャネル型でも強制されません（バッファありチャネルを除く）。したがって、一般に、並列ゴルーチン間の同期はミューテックスを介して達成される必要があります。 \r\n\r\n一方、一般に、並行ゴルーチンは _調整およびオーケストレーション_ をする必要があります。たとえば、G3 が G1 と G2 の両方からの結果を集約する必要がある場合、G1 と G2 は新しい中間結果が利用可能であることを G3 に通知する必要があります。この調整はコミュニケーションの範囲、つまりチャネルに該当します。 \r\n\r\n並行ゴルーチンに関しては、リソースの所有権をあるステップ（G1 および G2）から別のステップ（G3）に移管したい場合もあります。たとえば、G1 と G2 によって共有リソースが豊かになっている場合、ある時点でこのジョブは完了したと見なされます。ここでは、チャネルを使用して、特定のリソースの準備ができていることを通知し、所有権の移転を処理する必要があります。 \r\n\r\nミューテックスとチャネルには異なるセマンティクスがあります。ステートを共有したいとき、または共有リソースにアクセスしたいときは、ミューテックスによってこのリソースへの排他的アクセスが保証されます。反対に、チャネルはデータの有無（`chan struct{}` の有無）に関係なくシグナルを行う仕組みです。調整や所有権の移転はチャネルを通じて行う必要があります。ゴルーチンが並列か並行かを知ることが重要です。一般に、並列ゴルーチンにはミューテックスが必要で、並行ゴルーチンにはチャネルが必要です。\r\n\r\n### 競合問題を理解していない（データ競合と競合状態、そしてGo言語のメモリモデル） (#58)\r\n\r\n???+ info \"要約\"\r\n\r\n    並行処理に熟達するということは、データ競合と競合状態が異なる概念であることを理解することも意味します。データ競合は、複数のゴルーチンが同じメモリ位置に同時にアクセスし、そのうちの少なくとも 1 つが書き込みを行っている場合に発生します。一方、データ競合がないことが必ずしも決定的実行を意味するわけではありません。動作が制御できないイベントの順序やタイミングに依存している場合、これは競合状態です。\r\n\r\n競合問題は、プログラマーが直面する可能性のあるバグの中で最も困難かつ最も潜伏性の高いバグの 1 つとなります。Go 開発者として、私たちはデータ競合と競合状態、それらが及ぼしうる影響、およびそれらを回避する方法などの重要な側面を理解する必要があります。\r\n\r\n#### データ競合\r\n\r\nデータ競合は、2 つ以上のゴルーチンが同じメモリ位置に同時にアクセスし、少なくとも 1 つが書き込みを行っている場合に発生します。この場合、危険な結果が生じる可能性があります。さらに悪いことに、状況によっては、メモリ位置に無意味なビットの組み合わせを含む値が保持されてしまう可能性があります。 \r\n\r\nさまざまな手法を駆使して、データ競合の発生を防ぐことができます。たとえば \r\n\r\n* `sync/atomic` パッケージを使用する \r\n* 2 つのゴルーチンを同期する際にミューテックスのような特定の目的のためのデータ構造を利用する\r\n* チャネルを使用して 2 つのゴルーチンが通信し、変数が一度に 1 つのゴルーチンだけによって更新されるようにする\r\n\r\n#### 競合状態\r\n\r\n実行したい操作に応じて、データ競合のないアプリケーションが必ずしも決定的な結果を意味するでしょうか。そうとはいえません。\r\n\r\n競合状態は、動作が制御できないイベントのシーケンスまたはタイミングに依存する場合に発生します。ここでは、イベントのタイミングがゴルーチンの実行順序です。 \r\n\r\nまとめると、並行処理のアプリケーションで作業する場合、データ競合は競合状態とは異なることを理解することが不可欠です。データ競合は、複数のゴルーチンが同じメモリ位置に同時にアクセスし、そのうちの少なくとも 1 つが書き込みを行っている場合に発生します。データ競合とは、予想外の動作を意味します。ただし、データ競合のないアプリケーションが必ずしも決定的な結果を意味するわけではありません。データ競合がなくても、アプリケーションは制御されていないイベント（ゴルーチンの実行、チャネルへのメッセージの発信速度、データベースへの呼び出しの継続時間など）に依存する挙動を持つことがあります。その場合は競合状態です。並行処理のアプリケーションの設計に熟練するには、両方の概念を理解することが肝要です。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/58-races/)\r\n\r\n### ワークロードタイプごとの並行処理の影響を理解していない (#59)\r\n\r\n???+ info \"要約\"\r\n\r\n    一定数のゴルーチンを作成するときは、ワークロードのタイプを考慮してください。CPU バウンドのゴルーチンを作成するということは、この数を `GOMAXPROCS` 変数（デフォルトではホスト上の CPU コアの数に基づく）に近づけることを意味します。I/O バウンドのゴルーチンの作成は、外部システムなどの他の要因に依存します。 \r\n\r\n プログラミングでは、ワークロードの実行時間は次のいずれかによって制限されます。 \r\n\r\n * CPU の速度 - たとえば、マージソートアルゴリズムの実行がこれにあたります。このワークロードは CPU バウンドと呼ばれます。 \r\n * I/O の速度 - たとえば、REST 呼び出しやデータベースクエリの実行がこれにあたります。このワークロードは I/O バウンドと呼ばれます。 \r\n * 利用可能なメモリの量 - このワークロードはメモリバウンドと呼ばれます。\r\n\r\n???+ note \"補足\"\r\n\r\n    ここ数十年でメモリが非常に安価になったことを考慮すると、 3 つ目は現在では最もまれです。したがって、このセクションでは、最初の 2 つのワークロードタイプ、CPU バウンドと I/O バウンドに焦点を当てます。 \r\n\r\n ワーカーによって実行されるワークロードが I/O バウンドである場合、値は主に外部システムに依存します。逆に、ワークロードが CPU に依存している場合、ゴルーチンの最適な数は利用可能な CPU コアの数に近くなります（ベストプラクティスは `runtime.GOMAXPROCS` を使用することです）。並行処理のアプリケーションを設計する場合、ワークロードのタイプ（ I/O あるいは CPU ）を知ることが重要です。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/59-workload-type/main.go)\r\n\r\n### Go Context に対する誤解 (#60)\r\n\r\n???+ info \"要約\"\r\n\r\n    Go Context は、Go言語の並行処理の基礎の一部でもあります。 Context を使用すると、デッドライン、キーと値のリストを保持できます。\r\n\r\n!!! quote \"https://pkg.go.dev/context\"\r\n\r\n    Context は、デッドライン、キャンセルシグナル、その他の値を API の境界を越えて伝達します。\r\n \r\n#### デッドライン\r\n\r\nデッドラインとは、次のいずれかで決定される特定の時点を指します。 \r\n\r\n* 現在からの `time.Duration` （例：250 ms）\r\n* `time.Time` （例：2023-02-07 00:00:00 UTC） \r\n\r\nデッドラインのセマンティクスは、これを過ぎた場合は進行中のアクティビティを停止する必要があることを伝えます。アクティビティとは、たとえば、チャネルからのメッセージの受信を待機している I/O リクエストやゴルーチンです。 \r\n\r\n#### キャンセルシグナル \r\n\r\nGo Context のもう 1 つの使用例は、キャンセルシグナルを伝送することです。別のゴルーチン内で `CreateFileWatcher(ctx context.Context, filename string)` を呼び出すアプリケーションを作成することを想像してみましょう。この関数は、ファイルから読み取りを続けて更新をキャッチする特定のファイルウォッチャーを作成します。提供された Context が期限切れになるかキャンセルされると、この関数はそれを処理してファイル記述子を閉じます。 \r\n\r\n#### Context Value\r\n\r\nGo Context の最後の使用例は、キーと値のリストを運ぶことです。 Context にキーと値のリストを含める意味は何でしょうか。Go Context は汎用的であるため、使用例は無限にあります。 \r\n\r\nたとえば、トレースを使用する場合、異なるサブ関数の間で同じ相関 ID を共有したいことがあるかもしれません。一部の開発者は、この ID を関数シグネチャの一部にするにはあまりに侵略的だと考えるかもしれません。この点に関して、与えられた Context の一部としてそれを含めることを決定することもできます。 \r\n\r\n#### Context のキャンセルをキャッチする \r\n\r\n`context.Context` タイプは、受信専用の通知チャネル `<-chan struct{}` を返す `Done` メソッドをエクスポートします。このチャネルは、 Context に関連付けられた作業をキャンセルする必要がある場合に閉じられます。たとえば \r\n\r\n* `context.WithCancel`で作成された Context に関連する Done チャネルは、cancel関数が呼び出されると閉じられます。 \r\n* `context.WithDeadline`で作成した Context に関連する Done チャネルは、デッドラインを過ぎると閉じられます。 \r\n\r\n注意すべき点の 1 つは、内部チャネルは、特定の値を受け取ったときではなく、 Context がキャンセルされたとき、またはデッドラインに達したときに閉じる必要があるということです。チャネルのクローズは、すべての消費者ゴルーチンが受け取る唯一のチャネルアクションであるためです。このようにして、 Context がキャンセルされるか、デッドラインに達すると、すべての消費者に通知が届きます。 \r\n\r\nまとめると、熟練した Go 開発者になるには、 Context とその使用方法について理解する必要があります。原則として、ユーザーが待機させられる関数は Context を取得するべきです。これにより、上流の呼び出し元がこの関数をいつ呼び出すかを決定できるようになるからです。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/60-contexts/main.go)\r\n\r\n## 並行処理：実践\r\n\r\n### 不適切な Context を広めてしまう (#61)\r\n\r\n???+ info \"要約\"\r\n\r\n    Context を伝播する際には、Context をキャンセルできる条件を理解することが重要です。たとえば、レスポンスが送信された際に HTTP ハンドラが Context をキャンセルするときなどです。 \r\n\r\n多くの状況では、Go Context を伝播することが推奨されます。ただし、Context の伝播によって軽微なバグが発生し、サブ関数が正しく実行されなくなる場合があります。 \r\n\r\n次の例を考えてみましょう。いくつかのタスクを実行してレスポンスを返す HTTP ハンドラを公開します。ただし、レスポンスを返す直前に、それを Kafka トピックに送信したいと思っています。HTTP コンシューマにレイテンシの点でペナルティを課したくないので、publish アクションを新しいゴルーチン内で非同期に処理したいと考えています。たとえば、Context がキャンセルされた場合にメッセージの publish アクションを中断できるように、Context を受け入れる `publish` 関数を自由に使えるとします。可能な実装は次のとおりです。\r\n\r\n```go\r\nfunc handler(w http.ResponseWriter, r *http.Request) {\r\n    response, err := doSomeTask(r.Context(), r)\r\n    if err != nil {\r\n        http.Error(w, err.Error(), http.StatusInternalServerError)\r\n    return\r\n    }\r\n    go func() {\r\n        err := publish(r.Context(), response)\r\n        // err の処理をする\r\n    }()\r\n    writeResponse(response)\r\n}\r\n```\r\n\r\nこのコードの何が問題なのでしょうか。HTTP リクエストに付された Context は、さまざまな状況でキャンセルされる可能性があることを知っておく必要があります。 \r\n\r\n* クライアントの接続が終了したとき \r\n* HTTP/2リクエストの場合、リクエストがキャンセルされたとき\r\n* クライアントにレスポンスが書き戻されたとき \r\n\r\n最初の 2 つのケースでは、処理はおそらく正しく行われます。たとえば、doSomeTask からレスポンスを受け取ったものの、クライアントが接続を閉じた場合、メッセージが publish されないように、Context が既にキャンセルされた状態で publish を呼び出しても問題はおそらく起きません。しかし、最後のケースはどうでしょうか。\r\n\r\nレスポンスがクライアントに書き込まれると、要求に関連付けられた Context がキャンセルされます。したがって、競合状態に直面します。 \r\n\r\n* レスポンスが Kafka の publish 後に書かれた場合、レスポンスを返し、メッセージを正常に公開します。 \r\n* ただし、Kafka の publish 前または publish 中にレスポンスが書かれた場合、メッセージは publish されるべきではありません。 \r\n\r\n後者の場合、HTTP レスポンスをすぐに返すので、publish を呼び出すとエラーが返されます。\r\n\r\n???+ note \"補足\"\r\n\r\n    Go 1.21 からは、キャンセルせずに新しい Context を作成する方法が追加されました。 [`context.WithoutCancel`](https://pkg.go.dev/context#WithoutCancel) は、親がキャンセルされたときにキャンセルされていない親のコピーを返します。 \r\n\r\nまとめると、Context の伝播は慎重に行う必要があります。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/61-inappropriate-context/main.go)\r\n\r\n### 停止すべきときを知らずにゴルーチンを開始してしまう (#62)\r\n\r\n???+ info \"要約\"\r\n\r\n    リークを避けることは、ゴルーチンが開始されるたびに、最終的に停止する必要があることを意味します。\r\n\r\nゴルーチンは簡単に行うことができます。非常に簡単であるため、新しいゴルーチンをいつ停止するかについての計画を必ずしも立てていない可能性があり、リークにつながることがあります。ゴルーチンをいつ停止すればよいかわからないのは、Go言語でよくある設計上の問題であり、並行処理におけるミスです。 \r\n\r\n具体的な例について説明しましょう。外部設定（データベース接続などを使用したものなど）を監視する必要があるアプリケーションを設計します。まず、次のような実装をしてみます。\r\n\r\n```go\r\nfunc main() {\r\n    newWatcher()\r\n    // アプリケーションを実行する\r\n}\r\n\r\ntype watcher struct { /* いくつかのリソース */ }\r\n\r\nfunc newWatcher() {\r\n    w := watcher{}\r\n    go w.watch() // 外部設定を監視するゴルーチンを作成する\r\n}\r\n```\r\n\r\nこのコードの問題は、メインのゴルーチンが終了すると（おそらく OS シグナルまたは有限のワークロードのため）、アプリケーションが停止してしまうことです。したがって、ウォッチャーによって作成されたリソースは正常に閉じられません。これを防ぐにはどうすればよいでしょうか。\r\n\r\n1 つの方法としては、main が戻ったときにキャンセルされる Context を newWatcher に渡すことが挙げられます。\r\n\r\n```go\r\nfunc main() {\r\n    ctx, cancel := context.WithCancel(context.Background())\r\n    defer cancel()\r\n    newWatcher(ctx)\r\n    // アプリケーションを実行する\r\n}\r\n\r\nfunc newWatcher(ctx context.Context) {\r\n    w := watcher{}\r\n    go w.watch(ctx)\r\n}\r\n```\r\n\r\n作成した Context を watch メソッドに伝播します。Context がキャンセルされると、ウォッチャー構造体はそのリソースを閉じます。しかし、watch がそれを行う時間が確実にあるとはいえません。これは設計上の欠陥です。 \r\n\r\n問題は、ゴルーチンを停止する必要があることを伝えるためにシグナルを使用したことです。リソースが閉じられるまで、親のゴルーチンをブロックしませんでした。そうならないようにしましょう。\r\n\r\n```go\r\nfunc main() {\r\n    w := newWatcher()\r\n    defer w.close()\r\n    // アプリケーションを実行する\r\n}\r\n\r\nfunc newWatcher() watcher {\r\n    w := watcher{}\r\n    go w.watch()\r\n    return w\r\n}\r\n\r\nfunc (w watcher) close() {\r\n    // リソースを閉じる\r\n}\r\n```\r\n\r\nリソースを閉じる時間になったことを `watcher` に通知する代わりに、 `defer` を使用してこの　`close` メソッドを呼び出し、アプリケーションが終了する前にリソースが確実に閉じられるようにします。 \r\n\r\nまとめると、ゴルーチンは他のリソースと同様、メモリや他のリソースを解放するために最終的に閉じる必要があることに注意してください。ゴルーチンをいつ停止するかを知らずに開始するのは設計上の問題です。ゴルーチンが開始されるときは常に、いつ停止するかについて明確な計画を立てる必要があります。最後になりましたが、ゴルーチンがリソースを作成し、その有効期間がアプリケーションの存続期間にバインドされている場合は、アプリケーションを終了する前にそのゴルーチンが完了するのを待った方がおそらく確実です。そうすることで、リソースを間違いなく解放できます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/62-starting-goroutine/)\r\n\r\n### ゴルーチンとループ変数に注意しない (#63)\r\n\r\n???+ warning \"注意\"\r\n\r\n    このミスは Go　1.22 からは気にする必要がありません（[詳細](https://go.dev/blog/loopvar-preview)）。\r\n\r\n### `select` とチャネルを使用して決定的動作を期待する (#64)\r\n\r\n???+ info \"要約\"\r\n\r\n    複数のオプションが可能な場合、複数のチャネルで `select` するとケースがランダムに選択されることを理解すると、並行処理における軽微なバグにつながる可能性のある誤った仮定を立てることがなくなります。\r\n\r\nGo 開発者がチャネルを操作するときにありがちな間違いの 1 つは、select が複数のチャネルでどのように動作するかについて誤った理解をすることです。 \r\n\r\nたとえば、次の場合を考えてみましょう（ `disconnectCh` はバッファなしチャネルです）。\r\n\r\n```go\r\ngo func() {\r\n  for i := 0; i < 10; i++ {\r\n      messageCh <- i\r\n    }\r\n    disconnectCh <- struct{}{}\r\n}()\r\n\r\nfor {\r\n    select {\r\n    case v := <-messageCh:\r\n        fmt.Println(v)\r\n    case <-disconnectCh:\r\n        fmt.Println(\"disconnection, return\")\r\n        return\r\n    }\r\n}\r\n```\r\n\r\nこの例を複数回実行した場合、結果はランダムになります。\r\n\r\n```\r\n0\r\n1\r\n2\r\ndisconnection, return\r\n\r\n0\r\ndisconnection, return\r\n```\r\n\r\nどういうわけか 10 通のメッセージを消費するのではなく、そのうちの数通だけを受信しました。これは、複数のチャネルと併用した場合の select 文の仕様によるものです（https:// go.dev/ref/spec）。\r\n\r\n!!! quote \r\n\r\n    1 つ以上の通信を続行できる場合、均一の擬似ランダム選択によって、続行できる 1 つの通信が選択されます。 \r\n\r\n最初に一致したケースが優先される switch 文とは異なり、select 文は複数のオプションが可能な場合にランダムに選択します。 \r\n\r\nこの動作は最初は奇妙に思えるかもしれません。しかし、これはスタベーションを防ぐという理由があってのことです。最初に選択された通信がソースの順序に基づいているとします。その場合、送信速度が速いために、たとえば 1 つのチャネルからしか受信できないという状況に陥る可能性があります。これを防ぐために、Go言語の設計者はランダム選択を使用することにしました。 \r\n\r\n複数のチャネルで `select` を使用する場合、複数のオプションがあるなら、ソース順序の最初のケースが自動的に優先されるわけではないことに注意する必要があります。代わりに、Go言語はランダムに選択するため、どのオプションが選択されるかは保証されません。この動作を克服するには、単一の生産者ゴルーチンの場合、バッファなしのチャネルまたは単一のチャネルを使用することができます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/64-select-behavior/main.go)\r\n\r\n### 通知チャネルを使用していない (#65)\r\n\r\n???+ info \"要約\"\r\n\r\n    `chan struct{}` 型を使用して通知を送信しましょう。 \r\n\r\nチャネルは、シグナルを介してゴルーチン間で通信するためのメカニズムです。シグナルにはデータが含まれているかどうかは関係ありません。 \r\n\r\n具体的な例を見てみましょう。通信の切断が発生するたびにそれを通知するチャネルを作成します。 1 つの方法として、これを `chan bool` として扱うことが挙げられます。\r\n\r\n```go\r\ndisconnectCh := make(chan bool)\r\n```\r\n\r\nここで、そのようなチャネルを提供する API と対話するとします。これは真偽値のチャネルであるため、`true` または `false` のメッセージを受信できます。`true` が何を伝えているかはおそらく明らかでしょう。しかし、 `false` とは何を意味するのでしょうか。通信が切断されていないということでしょうか。その場合、どれくらいの頻度でそのようなシグナルを受信するのでしょうか。あるいは再接続したということでしょうか。そもそも `false` を受け取ることを期待すべきなのでしょうか。おそらく `true` メッセージを受け取ることだけを期待すべきでしょう。 \r\n\r\nその場合、情報を伝えるために特定の値は必要ないことを意味し、データの _ない_ チャネルが必要になります。これを処理する慣用的な方法は、空の構造体のチャネル―― `chan struct{} `――を使用することです。\r\n\r\n### nil チャネルを使用していない (#66)\r\n\r\n???+ info \"要約\"\r\n\r\n    nil チャネルを使用することによって、たとえば `select` 文からケースを _削除_ できるため、並行処理を行う際の道具の一つとして使えるようになるべきです。 \r\n\r\n次のコードによって何が行われるでしょうか。\r\n\r\n```go\r\nvar ch chan int\r\n<-ch\r\n```\r\n\r\n`ch` は `chan int` 型です。チャネルのゼロ値は nil であるので、 `ch` は `nil` です。ゴルーチンは panic を起こしません。ただし、永久にブロックします。 \r\n\r\nnil チャネルにメッセージを送信する場合も原理は同じです。以下のゴルーチンは永久にブロックします。\r\n\r\n```go\r\nvar ch chan int\r\nch <- 0\r\n```\r\n\r\nでは、Go言語が nil チャネルとの間でメッセージの送受信を許可する目的は何でしょうか。たとえば、2 つのチャネルをマージする慣用的な方法を実装するのに、 nil チャネルを使用することができます。\r\n\r\n```go hl_lines=\"5 9 15\"\r\nfunc merge(ch1, ch2 <-chan int) <-chan int {\r\n    ch := make(chan int, 1)\r\n\r\n    go func() {\r\n        for ch1 != nil || ch2 != nil { // 最低でも一つのチャネルが nil でなければ続行する\r\n            select {\r\n            case v, open := <-ch1:\r\n                if !open {\r\n                    ch1 = nil // 閉じたら ch1 を nil チャネルに割り当てる\r\n                    break\r\n                }\r\n                ch <- v\r\n            case v, open := <-ch2:\r\n                if !open {\r\n                    ch2 = nil // 閉じたら ch2 を nil チャネルに割り当てる\r\n                    break\r\n                }\r\n                ch <- v\r\n            }\r\n        }\r\n        close(ch)\r\n    }()\r\n\r\n    return ch\r\n}\r\n```\r\n\r\nこの洗練された解決策は、nil チャネルを利用して、何らかの方法で `select` 文から 1 つのケースを _削除_ します。 \r\n\r\nnil チャネルは状況によっては便利であり、Go 開発者は並行処理を扱う際に使いこなせるようになっておくべきです。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/66-nil-channels/main.go)\r\n\r\n### チャネルの容量について困惑している (#67)\r\n\r\n???+ info \"要約\"\r\n\r\n    問題が発生した場合は、使用するチャネルの型を慎重に決定してください。同期を強力に保証してくれるのはバッファなしチャネルのみです。 \r\n\r\nバッファありチャネル以外のチャネルの容量を指定するには正当な理由があるべきです。\r\n\r\n### 文字列フォーマットで起こり得る副作用を忘れてしまう（ etcd データ競合の例とデッドロック） (#68)\r\n\r\n???+ info \"要約\"\r\n\r\n    文字列の書式設定が既存の関数が呼び出す可能性があることを認識することは、デッドロックやその他のデータ競合の可能性に注意することを意味します。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/68-string-formatting/main.go)\r\n\r\n### `append` でデータ競合を起こしてしまう (#69)\r\n\r\n???+ info \"要約\"\r\n\r\n    `append` の呼び出しは必ずしもデータ競合がないわけではありません。ゆえに、共有スライス上で同時に使用してはいけません。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/69-data-race-append/main.go)\r\n\r\n### スライスとマップでミューテックスを正しく使用していない (#70)\r\n\r\n???+ info \"要約\"\r\n\r\n    スライスとマップはポインタであることを覚えておくと、典型的なデータ競合を防ぐことができます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/70-mutex-slices-maps/main.go)\r\n\r\n### `sync.WaitGroup` を正しく使用していない (#71)\r\n\r\n???+ info \"要約\"\r\n\r\n    `sync.WaitGroup` を正しく使用するには、ゴルーチンを起動する前に `Add` メソッドを呼び出しましょう。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/71-wait-group/main.go)\r\n\r\n### `sync.Cond` について忘れてしまう (#72)\r\n\r\n???+ info \"要約\"\r\n\r\n    `sync.Cond` を使用すると、複数のゴルーチンに繰り返し通知を送信できます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/72-cond/main.go)\r\n\r\n### `errgroup` を使用していない (#73)\r\n\r\n???+ info \"要約\"\r\n\r\n    `errgroup` パッケージを使用して、ゴルーチンのグループを同期し、エラーと Context を処理できます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/73-errgroup/main.go)\r\n\r\n\r\n### `sync` 型のコピー (#74)\r\n\r\n???+ info \"要約\"\r\n\r\n    `sync` 型はコピーされるべきではありません。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/74-copying-sync/main.go)\r\n\r\n## 標準ライブラリ\r\n\r\n### 間違った時間を指定する (#75)\r\n\r\n???+ info \"要約\"\r\n\r\n    `time.Duration` を受け入れる関数には注意を払ってください。整数を渡すことは許可されていますが、混乱を招かないように time API を使用するよう努めてください。\r\n\r\n標準ライブラリの多くの関数は、`int64` 型のエイリアスである `time.Duration` を受け入れます。ただし、1 単位の `time.Duration` は、他のプログラミング言語で一般的に見られる 1 ミリ秒ではなく、1 ナノ秒を表します。その結果、`time.Duration` API を使用する代わりに数値型を渡すと、予想外の動作が発生する可能性があります。 \r\n\r\n他言語を使用したことのある開発者の方は、次のコードによって 1 秒周期の新しい `time.Ticker` が生成されると考えるかもしれません。\r\n\r\n```go\r\nticker := time.NewTicker(1000)\r\nfor {\r\n\tselect {\r\n\tcase <-ticker.C:\r\n\t\t// 処理をする\r\n\t}\r\n}\r\n```\r\n\r\nしかしながら、1,000 `time.Duration` = 1,000 ナノ秒であるため、想定されている 1秒 ではなく、1,000 ナノ秒 = 1 マイクロ秒の周期になります。 \r\n\r\n混乱や予想外の動作を招かないよう、いつも `time.Duration` API を使用するべきです。\r\n\r\n```go\r\nticker = time.NewTicker(time.Microsecond)\r\n// もしくは\r\nticker = time.NewTicker(1000 * time.Nanosecond)\r\n```\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/75-wrong-time-duration/main.go)\r\n\r\n### `time.After` とメモリリーク (#76)\r\n\r\n???+ info \"要約\"\r\n\r\n    繰り返される関数（ループや HTTP ハンドラなど）で `time.After` の呼び出しを回避すると、ピーク時のメモリ消費を回避できます。`time.After` によって生成されたリソースは、 timer が終了したときにのみ解放されます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/76-time-after/main.go)\r\n\r\n### JSON 処理でありがちな間違い (#77)\r\n\r\n* 型の埋め込みによる予想外の動作 \r\n\r\n  Go 構造体で埋め込みフィールドを使用する場合は注意してください。 なぜなら `json.Marshaler` インタフェースを実装する time.Time 埋め込みフィールドのようなやっかいなバグが発生して、デフォルトのマーシャリング動作がオーバーライドされる可能性があるからです。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/type-embedding/main.go)\r\n\r\n* JSON と monotonic clock\r\n\r\n  2 つの `time.Time` 構造体を比較する場合、`time.Time` には wall clock と monotonic clock の両方が含まれており、== 演算子を使用した比較は両方の clock に対して行われることを思い出してください。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/monotonic-clock/main.go)\r\n\r\n* `any` のマップ\r\n\r\n  JSON データのアンマーシャリング中にマップを提供するときに間違いを避けるために、数値はデフォルトで `float64` に変換されることに注意してください。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/map-any/main.go)\r\n\r\n### SQL でありがちな間違い (#78)\r\n\r\n* `sql.Open` が必ずしもデータベースへの接続を確立するわけではないことを忘れている\r\n\r\n  設定を試し、データベースにアクセスできることを確認する必要がある場合は、 `Ping` または `PingContext` メソッドを呼び出しましょう。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/sql-open)\r\n\r\n* コネクションプーリングのことを忘れる \r\n\r\n  実運用水準のアプリケーションでは、データベース接続パラメータを設定しましょう。\r\n\r\n* プリペアドステートメントを使用していない\r\n\r\n  SQL のプリペアドステートメントを使用すると、クエリがより効率的かつ確実になります。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/prepared-statements)\r\n\r\n* null 値を誤った方法で処理している\r\n\r\n  テーブル内の null が許容されている列は、ポインタまたは `sql.NullXXX` 型を使用して処理しましょう。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/null-values/main.go)\r\n\r\n* 行の反復処理によるエラーを処理しない \r\n\r\n  行の反復処理の後に `sql.Rows` の `Err` メソッドを呼び出して、次の行の準備中にエラーを見逃していないことを確認しましょう。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/rows-iterations-errors)\r\n\r\n### 一時的なリソース（ HTTP body、`sql.Rows`、および `os.File` ）を閉じていない (#79)\r\n\r\n???+ info \"要約\"\r\n\r\n    リークを避けるために、 `io.Closer` を実装しているすべての構造体を最後には閉じましょう。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/79-closing-resources/)\r\n\r\n### HTTP リクエストに応答した後の return 文を忘れてしまう (#80)\r\n\r\n???+ info \"要約\"\r\n\r\n    HTTP ハンドラの実装での予想外の動作を避けるため、`http.Error` の後にハンドラを停止したい場合は、`return` 文を忘れないようにしてください。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/80-http-return/main.go)\r\n\r\n### 標準の HTTP クライアントとサーバーを使用している (#81)\r\n\r\n???+ info \"要約\"\r\n\r\n    実運用水準のアプリケーションを求めている場合は、標準の HTTP クライアントとサーバーの実装を使用しないでください。これらの実装には、タイムアウトや稼働環境で必須であるべき動作が欠落しています。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/81-default-http-client-server/)\r\n\r\n## テスト\r\n\r\n### テストを分類していない（ビルドタグ、環境変数、ショートモード） (#82)\r\n\r\n???+ info \"要約\"\r\n\r\n    ビルドフラグ、環境変数、またはショートモードを使用してテストを分類すると、テストプロセスがより効率的になります。ビルドフラグまたは環境変数を使用してテストカテゴリ（たとえば、単体テストと統合テスト）を作成し、短期間のテストと長時間のテストを区別することで、実行するテストの種類を決定できます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/82-categorizing-tests/)\r\n\r\n### `-race` フラグを有効にしていない (#83)\r\n\r\n???+ info \"要約\"\r\n\r\n    並行アプリケーションを作成する場合は、 `-race` フラグを有効にすることを強くお勧めします。そうすることで、ソフトウェアのバグにつながる可能性のある潜在的なデータ競合を発見できるようになります。\r\n\r\n### テスト実行モード（ `-parallel` および `-shuffle` ）を使用していない (#84)\r\n\r\n???+ info \"要約\"\r\n\r\n    `-parallel` フラグを使用するのは、特に長時間実行されるテストを高速化するのに効果的です。 `-shuffle` フラグを使用すると、テストスイートがバグを隠す可能性のある間違った仮定に依存しないようにすることができます。\r\n\r\n### テーブル駆動テストを使用しない (#85)\r\n\r\n???+ info \"要約\"\r\n\r\n    テーブル駆動テストは、コードの重複を防ぎ、将来の更新の処理を容易にするために、一連の類似したテストをグループ化する効率的な方法です。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/85-table-driven-tests/main_test.go)\r\n\r\n### 単体テストでのスリープ (#86)\r\n\r\n???+ info \"要約\"\r\n\r\n    テストの不安定さをなくし、より堅牢にするために、同期を使用してスリープを回避しましょう。同期が不可能な場合は、リトライ手法を検討してください。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/86-sleeping/main_test.go)\r\n\r\n### time API を効率的に処理できていない (#87)\r\n\r\n???+ info \"要約\"\r\n\r\n    time API を使用して関数を処理する方法を理解することで、テストの不安定さを軽減することができます。隠れた依存関係の一部として time を処理したり、クライアントに time を提供するように要求したりするなど、標準的な手段を利用できます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/87-time-api/)\r\n\r\n### テストに関するユーティリティパッケージ（ `httptest` および `iotest` ）を使用していない (#88)\r\n\r\n* `httptest` パッケージは、HTTP アプリケーションを扱うのに役立ちます。クライアントとサーバーの両方をテストするための一連のユーティリティを提供します。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/88-utility-package/httptest/main_test.go)\r\n\r\n* `iotest` パッケージは、io.Reader を作成し、アプリケーションのエラー耐性をテストするのに役立ちます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/88-utility-package/iotest/main_test.go)\r\n\r\n### 不正確なベンチマークの作成 (#89)\r\n\r\n???+ info \"要約\"\r\n\r\n    ベンチマークについて\r\n\r\n    * ベンチマークの精度を維持するには、time メソッドを使用しましょう。 \r\n    * ベンチタイムを増やすか、benchstat などのツールを使用することで、マイクロベンチマークが扱いやすくなります。 \r\n    * アプリケーションを最終的に実行するシステムがマイクロベンチマークを実行するシステムと異なる場合は、マイクロベンチマークの結果に注意してください。 \r\n    * コンパイラの最適化によってベンチマークの結果が誤魔化されないよう、テスト対象の関数が副作用を引き起こすようにしてください。 \r\n    * オブザーバー効果を防ぐには、CPU に依存する関数が使用するデータをベンチマークが再生成するよう強制してください。\r\n\r\nセクション全文は[こちら](89-benchmarks.md)。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/89-benchmark/)\r\n\r\n### Go言語のテスト機能をすべて試していない (#90)\r\n\r\n* コードカバレッジ \r\n\r\n   コードのどの部分に注意が必要かをすぐに確認するために、`-coverprofile` フラグを指定してコードカバレッジを使用しましょう。 \r\n\r\n * 別のパッケージからのテスト \r\n\r\n   内部ではなく公開された動作に焦点を当てたテストの作成を強制するために、単体テストは別々のパッケージに配置しましょう。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/different-package/main_test.go)\r\n\r\n* ユーティリティ関数 \r\n\r\n   従来の `if err != nil` の代わりに `*testing.T` 変数を使用してエラーを処理すると、コードが短く、読みやすくなります。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/utility-function/main_test.go)\r\n\r\n* setup と teardown\r\n\r\n   setup および teardown 機能を利用して、統合テストの場合など、複雑な環境を構成できます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/setup-teardown/main_test.go)\r\n\r\n### ファジングを使用していない（community mistake）\r\n\r\n???+ info \"要約\"\r\n\r\n    ファジングは、複雑な関数やメソッドへのランダムな、予想外の、または不正な入力を検出し、脆弱性、バグ、さらには潜在的なクラッシュを発見するのに効率的です。\r\n\r\n[@jeromedoucet](https://github.com/jeromedoucet) さんのご協力に感謝いたします。\r\n\r\n## 最適化\r\n\r\n### CPU キャッシュを理解していない (#91)\r\n\r\n* CPU アーキテクチャ \r\n\r\n  L1 キャッシュはメインメモリよりも約 50 ～ 100 倍高速であるため、CPU バウンドのアプリケーションを最適化するには、CPU キャッシュの使用方法を理解することが重要です。 \r\n\r\n* キャッシュライン \r\n\r\n  キャッシュラインの概念を意識することは、データ集約型アプリケーションでデータを整理する方法を理解するのに重要です。CPU はメモリをワードごとにフェッチしません。代わりに、通常はメモリブロックを 64 バイトのキャッシュラインにコピーします。個々のキャッシュラインを最大限に活用するには、空間的局所性を強制してください。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/cache-line/)\r\n\r\n* 構造体のスライスとスライスの構造体\r\n\r\n<!-- TODO -->\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/slice-structs/)\r\n\r\n* 予測可能性 \r\n\r\n  CPU にとって予測可能なコードにすることは、特定の関数を最適化する効率的な方法でもあります。たとえば、ユニットまたは定数ストライドは CPU にとって予測可能ですが、非ユニットストライド（連結リストなど）は予測できません。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/predictability/)\r\n\r\n* キャッシュ配置ポリシー \r\n\r\n  キャッシュがパーティション化されていることを認識することで、重大なストライドを回避し、キャッシュのごく一部のみを使用するようにすることができます。\r\n\r\n### 誤った共有を引き起こす並行処理(#92)\r\n\r\n???+ info \"要約\"\r\n\r\n    下位レベルの CPU キャッシュがすべてのコアで共有されるわけではないことを知っておくと、並行処理におけるの誤った共有などでパフォーマンスを低下させてしまうことを回避できます。メモリの共有はありえないのです。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/92-false-sharing/)\r\n\r\n### 命令レベルの並列性を考慮しない (#93)\r\n\r\n???+ info \"要約\"\r\n\r\n    命令レベルの並列性（ILP）を使用してコードの特定の部分を最適化し、CPU ができるだけ多くの命令を並列実行できるようにしましょう。主な手順の 1 つにデータハザードの特定があります。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/93-instruction-level-parallelism/)\r\n\r\n### データの配置を意識していない (#94)\r\n\r\n???+ info \"要約\"\r\n\r\n    Go言語では、基本型は各々のサイズに合わせて配置されることを覚えておくことで、ありがちな間違いを避けることができます。たとえば、構造体のフィールドをサイズで降順に再編成すると、構造体がよりコンパクトになる（メモリ割り当てが少なくなり、空間的局所性が向上する）可能性があることに留意してください。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/94-data-alignment/)\r\n\r\n### ヒープとスタックの違いを理解していない (#95)\r\n\r\n???+ info \"要約\"\r\n\r\n    ヒープとスタックの基本的な違いを理解することも、Go アプリケーションを最適化する際には大切です。スタック割り当ては容易なのに対して、ヒープ割り当ては遅く、メモリのクリーンアップに GC を利用します。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/95-stack-heap/)\r\n\r\n### 割り当てを減らす方法がわかっていない（ API の変更、コンパイラの最適化、および `sync.Pool`） (#96)\r\n\r\n???+ info \"要約\"\r\n\r\n    割り当てを減らすことも、Go アプリケーションを最適化する上で重要です。これは、共有を防ぐために API を慎重に設計する、一般的な Go コンパイラの最適化を理解する、`sync.Pool` を使用するなど、さまざまな方法で行うことができます。\r\n\r\n [ソースコード :simple-github:](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/96-reduce-allocations/)\r\n\r\n### インライン展開をしていない (#97)\r\n\r\n???+ info \"要約\"\r\n\r\n    ファストパスのインライン化手法を使用して、関数の呼び出しにかかる償却時間を効率的に削減しましょう。\r\n\r\n### Go言語の診断ツールを利用していない (#98)\r\n\r\n???+ info \"要約\"\r\n\r\n    プロファイリングと実行トレーサを利用して、アプリケーションのパフォーマンスと最適化すべき部分について理解しましょう。\r\n\r\nセクション全文は[こちら](98-profiling-execution-tracing.md)。\r\n\r\n### GC の仕組みを理解していない (#99)\r\n\r\n???+ info \"要約\"\r\n\r\n    GC の調整方法を理解すると、突然の負荷の増加をより効率的に処理できるなど、さまざまな恩恵が得られます。\r\n\r\n### Docker と Kubernetes 上でGo言語を実行することの影響を理解していない (#100)\r\n\r\n???+ info \"要約\"\r\n\r\n    Docker と Kubernetes にデプロイする際の CPU スロットリングを回避するには、Go言語が CFS 対応ではないことに留意してください。"
  },
  {
    "path": "docs/pt-br.md",
    "content": "---\ntitle: Brazilian Portuguese Version\ncomments: true\n---\n\n# Erros comuns de Go\n\n???+ tip \"The Coder Cafe\"\n\n    Se você gostou do meu livro, talvez se interesse pelo meu novo projeto: [The Coder Cafe](https://thecoder.cafe?rd=100go.co/pt-br), uma newsletter diária para programadores.\n\n    > Feeling overwhelmed by the endless stream of tech content? At The Coder Cafe, we serve one essential concept for coders. Written by a senior software engineer at Google, it's perfectly brewed for your morning coffee, helping you grow your skills deeply.\n\n    <center><a href=\"https://thecoder.cafe?rd=100go.co/pt-br\"><img src=\"../img/thecodercafe.png\" alt=\"\" style=\"width:480px;height:240px;\"></a></center>\n\nEsta página é um resumo dos erros do [100 Go Mistakes and How to Avoid Them book](book.md). Enquanto isso, também está aberto à comunidade. Se você acredita que um erro comum do Go deve ser adicionado, crie uma [issue](https://github.com/teivah/100-go-mistakes/issues/new?assignees=&labels=community+mistake&template=community_mistake.md&title=).\n\n![](img/inside-cover.png)\n\n???+ warning \"Beta\"\n\n    Você está visualizando uma versão beta enriquecida com muito mais conteúdo. No entanto, esta versão ainda não está completa e estou procurando voluntários para me ajudar a resumir os erros restantes ([GitHub issue #43](https://github.com/teivah/100-go-mistakes/issues/43)).\n\n    Progresso:\n    <progress value=\"81\" max=\"100\"/>\n\n## Código e Organização do Projeto\n\n### Sombreamento não intencional de variável (#1)\n\n???+ info \"TL;DR\"\n\n    Evitar variáveis ​​sombreadas pode ajudar a evitar erros, como fazer referência à variável errada ou confundir os desenvolvedores.\n\nO sombreamento de variável ocorre quando um nome de variável é redeclarado em um bloco interno, mas essa prática está sujeita a erros. A imposição de uma regra para proibir variáveis ​​obscuras depende do gosto pessoal. Por exemplo, às vezes pode ser conveniente reutilizar um nome de variável existente, como `err` no caso de erros. Porém, em geral, devemos ser cautelosos porque agora sabemos que podemos enfrentar um cenário onde o código compila, mas a variável que recebe o valor não é a esperada.\n\n[:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/1-variable-shadowing/main.go)\n\n### Código aninhado desnecessário (#2)\n\n???+ info \"TL;DR\"\n\n    Evitar níveis aninhados e manter o caminho feliz alinhado à esquerda facilita a construção de um modelo de código mental.\n\nEm geral, quanto mais níveis aninhados uma função exigir, mais complexa será sua leitura e compreensão. Vamos ver algumas aplicações diferentes desta regra para otimizar a legibilidade do nosso código:\n\n* Quando um bloco `if` retorna, devemos omitir o `else` em todos os casos. Por exemplo, não deveríamos escrever:\n\n```go\nif foo() {\n    // ...\n    return true\n} else {\n    // ...\n}\n```\n\nEm vez disso, omitimos o bloco `else` assim:\n\n```go\nif foo() {\n    // ...\n    return true\n}\n// ...\n```\n\n* Também podemos seguir esta lógica com um caminho não feliz:\n\n```go\nif s != \"\" {\n    // ...\n} else {\n    return errors.New(\"empty string\")\n}\n```\n\n  Aqui, um `s` vazio representa o caminho não feliz. Portanto, devemos inverter a condição assim:\n\n```go\nif s == \"\" {\n    return errors.New(\"empty string\")\n}\n// ...\n```\n\nEscrever código legível é um desafio importante para todo desenvolvedor. Esforçar-se para reduzir o número de blocos aninhados, alinhar o caminho feliz à esquerda e retornar o mais cedo possível são meios concretos para melhorar a legibilidade do nosso código.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/2-nested-code/main.go)\n\n### Uso indevido de funções init (#3)\n\n???+ info \"TL;DR\"\n\n    Ao inicializar variáveis, lembre-se de que as funções init têm tratamento de erros limitado e tornam o tratamento de estado e os testes mais complexos. Na maioria dos casos, as inicializações devem ser tratadas como funções específicas.\n\nUma função init é uma função usada para inicializar o estado de um aplicativo. Não aceita argumentos e não retorna nenhum resultado (uma função `func()`). Quando um pacote é inicializado, todas as declarações de constantes e variáveis ​​do pacote são avaliadas. Então, as funções init são executadas.\n\nAs funções de inicialização podem levar a alguns problemas:\n\n* Elas podem limitar o gerenciamento de erros.\n* Elas podem complicar a implementação de testes (por exemplo, uma dependência externa deve ser configurada, o que pode não ser necessário para o escopo dos testes unitários).\n* Se a inicialização exigir que definamos um estado, isso deverá ser feito por meio de variáveis ​​globais.\n\nDevemos ser cautelosos com as funções init. No entanto, elas podem ser úteis em algumas situações, como na definição de configuração estática. Caso contrário, e na maioria dos casos, devemos tratar as inicializações através de funções ad hoc.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/3-init-functions/)\n\n### Uso excessivo de getters e setters (#4)\n\n???+ info \"TL;DR\"\n\n    Forcing the use of getters and setters isn’t idiomatic in Go. Being pragmatic and finding the right balance between efficiency and blindly following certain idioms should be the way to go.\n\nO encapsulamento de dados refere-se a ocultar os valores ou o estado de um objeto. Getters e setters são meios de habilitar o encapsulamento, fornecendo métodos exportados sobre campos de objetos não exportados.\n\nNo Go, não há suporte automático para getters e setters como vemos em algumas linguagens. Também não é considerado obrigatório nem idiomático o uso de getters e setters para acessar campos struct. Não devemos sobrecarregar nosso código com getters e setters em structs se eles não trouxerem nenhum valor. Deveríamos ser pragmáticos e nos esforçar para encontrar o equilíbrio certo entre eficiência e seguir expressões que às vezes são consideradas indiscutíveis em outros paradigmas de programação.\n\nLembre-se de que Go é uma linguagem única projetada para muitas características, incluindo simplicidade. No entanto, se encontrarmos necessidade de getters e setters ou, como mencionado, prevermos uma necessidade futura e ao mesmo tempo garantirmos a compatibilidade futura, não há nada de errado em usá-los.\n\n### Interface poluidas (#5)\n\n???+ info \"TL;DR\"\n\n    Abstrações devem ser descobertas, não criadas. Para evitar complexidade desnecessária, crie uma interface quando precisar dela e não quando você prevêr que será necessária, ou se puder pelo menos provar que a abstração é válida.\n\nLeia a seção completa [aqui](5-interface-pollution.md).\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/5-interface-pollution/)\n\n### Interface do lado do producer (#6)\n\n???+ info \"TL;DR\"\n\n    Manter interfaces no lado do cliente evita abstrações desnecessárias.\n\nAs interfaces são satisfeitas implicitamente em Go, o que tende a ser um divisor de águas em comparação com linguagens com implementação explícita. Na maioria dos casos, a abordagem a seguir é semelhante à que descrevemos na seção anterior: _as abstrações devem ser descobertas, não criadas_. Isso significa que não cabe ao producer forçar uma determinada abstração para todos os clientes. Em vez disso, cabe ao cliente decidir se precisa de alguma forma de abstração e então determinar o melhor nível de abstração para suas necessidades.\n\nUma interface deve residir no lado do consumidor na maioria dos casos. Contudo, em contextos específicos (por exemplo, quando sabemos – e não prevemos – que uma abstração será útil para os consumidores), podemos querer tê-la do lado do procuder. Se o fizermos, devemos nos esforçar para mantê-lo o mínimo possível, aumentando o seu potencial de reutilização e tornando-o mais facilmente combinável.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/6-interface-producer/)\n\n### Interfaces de retorno (#7)\n\n???+ info \"TL;DR\"\n\n    Para evitar restrições em termos de flexibilidade, uma função não deve retornar interfaces, mas implementações concretas na maioria dos casos. Por outro lado, uma função deve aceitar interfaces sempre que possível.\n\nNa maioria dos casos, não devemos retornar interfaces, mas implementações concretas. Caso contrário, isso pode tornar nosso design mais complexo devido às dependências do pacote e pode restringir a flexibilidade porque todos os clientes teriam que contar com a mesma abstração. Novamente, a conclusão é semelhante às seções anteriores: se sabemos (não prevemos) que uma abstração será útil para os clientes, podemos considerar o retorno de uma interface. Caso contrário, não deveríamos forçar abstrações; eles devem ser descobertas pelos clientes. Se um cliente precisar abstrair uma implementação por qualquer motivo, ele ainda poderá fazer isso do lado do cliente.\n\n### `any` não diz nada (#8)\n\n???+ info \"TL;DR\"\n\n    Use apenas `any` se precisar aceitar ou retornar qualquer tipo possível, como `json.Marshal`. Caso contrário, `any` não fornece informações significativas e pode levar a problemas de tempo de compilação, permitindo que um chamador chame métodos com qualquer tipo de dados.\n\nO tipo `any` pode ser útil se houver uma necessidade genuína de aceitar ou retornar qualquer tipo possível (por exemplo, quando se trata de empacotamento ou formatação). Em geral, devemos evitar a todo custo generalizar demais o código que escrevemos. Talvez um pouco de código duplicado possa ocasionalmente ser melhor se melhorar outros aspectos, como a expressividade do código.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/8-any/main.go)\n\n### Ficar confuso sobre quando usar genéricos (#9)\n\n???+ info \"TL;DR\"\n\n    Depender de parâmetros genéricos e de tipo pode impedir a gravação de código clichê (boilerplate) para fatorar elementos ou comportamentos. No entanto, não use parâmetros de tipo prematuramente, mas somente quando você perceber uma necessidade concreta deles. Caso contrário, introduzem abstrações e complexidade desnecessárias.\n\nLeia a seção completa [aqui](9-generics.md).\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/9-generics/main.go)\n\n### Não estar ciente dos possíveis problemas com a incorporação de tipos (#10)\n\n???+ info \"TL;DR\"\n\n    Usar a incorporação de tipo (type embedding) também pode ajudar a evitar código clichê (boilerplate); no entanto, certifique-se de que isso não leve a problemas de visibilidade onde alguns campos deveriam ter permanecido ocultos.\n\nAo criar uma struct, Go oferece a opção de incorporar tipos. Mas isso às vezes pode levar a comportamentos inesperados se não compreendermos todas as implicações da incorporação de tipos. Ao longo desta seção, veremos como incorporar tipos, o que eles trazem e os possíveis problemas.\n\nNo Go, um campo struct é chamado de incorporado se for declarado sem nome. Por exemplo,\n\n```go\ntype Foo struct {\n    Bar // Embedded field\n}\n\ntype Bar struct {\n    Baz int\n}\n```\n\nNa estrutura `Foo`, o tipo `Bar` é declarado sem nome associado; portanto, é um campo incorporado.\n\nUsamos incorporação para promover os campos e métodos de um tipo incorporado. Como `Bar` contém um campo `Baz`, esse campo é promovido para `Foo`. Portanto, `Baz` fica disponível a partir de `Foo`.\n\nO que podemos dizer sobre a incorporação de tipos? Primeiro, observemos que raramente é uma necessidade e significa que, qualquer que seja o caso de uso, provavelmente também poderemos resolvê-lo sem incorporação de tipo. A incorporação de tipos é usada principalmente por conveniência: na maioria dos casos, para promover comportamentos.\n\nSe decidirmos usar incorporação de tipo, precisamos ter em mente duas restrições principais:\n\n* Não deve ser usado apenas como um açúcar sintático para simplificar o acesso a um campo (como `Foo.Baz()` em vez de `Foo.Bar.Baz()`). Se esta for a única justificativa, não vamos incorporar o tipo interno e usar um campo.\n* Não deve promover dados (campos) ou um comportamento (métodos) que queremos ocultar do exterior: por exemplo, se permitir que os clientes acessem um comportamento de bloqueio que deve permanecer privado da struct.\n\nUsar a incorporação de tipo de forma consciente, mantendo essas restrições em mente, pode ajudar a evitar código clichê (boilerplate) com métodos de encaminhamento adicionais. No entanto, vamos garantir que não o fazemos apenas por motivos cosméticos e não promovemos elementos que deveriam permanecer ocultos.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/10-type-embedding/main.go)\n\n### Não usar o padrão de opções funcionais (functional options pattern) (#11)\n\n???+ info \"TL;DR\"\n\n    Para lidar com opções de maneira conveniente e amigável à API, use o padrão de opções funcionais.\n\nEmbora existam diferentes implementações com pequenas variações, a ideia principal é a seguinte:\n\n* Uma estrutura não exportada contém a configuração: opções.\n* Cada opção é uma função que retorna o mesmo tipo: `type Option func(options *options) error`. Por exemplo, `WithPort` aceita um argumento `int`  que representa a porta e retorna um tipo `Option` que representa como atualizar a struct `options`.\n\n![](img/options.png)\n\n```go\ntype options struct {\n  port *int\n}\n\ntype Option func(options *options) error\n\nfunc WithPort(port int) Option {\n  return func(options *options) error {\n    if port < 0 {\n    return errors.New(\"port should be positive\")\n  }\n  options.port = &port\n  return nil\n  }\n}\n\nfunc NewServer(addr string, opts ...Option) ( *http.Server, error) {\n  var options options\n  for _, opt := range opts {\n    err := opt(&options)\n    if err != nil {\n      return nil, err\n    }\n  }\n\n  // At this stage, the options struct is built and contains the config\n  // Therefore, we can implement our logic related to port configuration\n  var port int\n  if options.port == nil {\n    port = defaultHTTPPort\n  } else {\n      if *options.port == 0 {\n      port = randomPort()\n    } else {\n      port = *options.port\n    }\n  }\n\n  // ...\n}\n```\n\nO padrão de opções funcionais fornece uma maneira prática e amigável à API de lidar com opções. Embora o padrão do construtor possa ser uma opção válida, ele tem algumas desvantagens menores (ter que passar uma estrutura de configuração que pode estar vazia ou uma maneira menos prática de lidar com o gerenciamento de erros) que tendem a tornar o padrão de opções funcionais a maneira idiomática de lidar com esse tipo de problema no Go.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/11-functional-options/)\n\n### Desorganização do projeto (estrutura do projeto e organização do pacote) (#12)\n\nNo que diz respeito à organização geral, existem diferentes escolas de pensamento. Por exemplo, devemos organizar a nossa aplicação por contexto ou por camada? Depende de nossas preferências. Podemos preferir agrupar o código por contexto (como o contexto do cliente, o contexto do contrato, etc.), ou podemos preferir seguir os princípios da arquitetura hexagonal e agrupar por camada técnica. Se a decisão que tomarmos se adequar ao nosso caso de uso, não pode ser uma decisão errada, desde que permaneçamos consistentes com ela.\n\nEm relação aos pacotes, existem várias práticas recomendadas que devemos seguir. Primeiro, devemos evitar pacotes prematuros porque podem complicar demais um projeto. Às vezes, é melhor usar uma organização simples e fazer nosso projeto evoluir quando entendemos o que ele contém, em vez de nos forçarmos a fazer a estrutura perfeita desde o início. A granularidade é outra coisa essencial a considerar. Devemos evitar dezenas de pacotes nano contendo apenas um ou dois arquivos. Se o fizermos, é porque provavelmente perdemos algumas conexões lógicas entre esses pacotes, tornando nosso projeto mais difícil de ser compreendido pelos leitores. Por outro lado, também devemos evitar pacotes grandes que diluem o significado do nome de um pacote.\n\nA nomenclatura dos pacotes também deve ser considerada com cuidado. Como todos sabemos (como desenvolvedores), nomear é difícil. Para ajudar os clientes a entender um projeto Go, devemos nomear nossos pacotes de acordo com o que eles fornecem, não com o que contêm. Além disso, a nomenclatura deve ser significativa. Portanto, o nome de um pacote deve ser curto, conciso, expressivo e, por convenção, uma única palavra minúscula.\n\nQuanto ao que exportar, a regra é bastante simples. Devemos minimizar o que deve ser exportado tanto quanto possível para reduzir o acoplamento entre pacotes e manter ocultos os elementos exportados desnecessários. Se não tivermos certeza se devemos ou não exportar um elemento, devemos optar por não exportá-lo. Mais tarde, se descobrirmos que precisamos exportá-lo, poderemos ajustar nosso código. Vamos também ter em mente algumas exceções, como fazer com que os campos sejam exportados para que uma estrutura possa ser desempacotada com encoding/json.\n\nOrganizar um projeto não é simples, mas seguir essas regras deve ajudar a facilitar sua manutenção. No entanto, lembre-se de que a consistência também é vital para facilitar a manutenção. Portanto, vamos nos certificar de manter as coisas o mais consistentes possível dentro de uma base de código.\n\n???+ note\n\n    Em 2023, a equipe Go publicou uma diretriz oficial para organizar/estruturar um projeto Go: [go.dev/doc/modules/layout](https://go.dev/doc/modules/layout)\n\n### Criando pacotes de utilitários (#13)\n\n???+ info \"TL;DR\"\n\n    A nomenclatura é uma parte crítica do design do aplicativo. Criar pacotes como `common`, `util` e `shared` não traz muito valor para o leitor. Refatore esses pacotes em nomes de pacotes significativos e específicos.\n\nAlém disso, tenha em mente que nomear um pacote com base no que ele fornece e não no que ele contém pode ser uma forma eficiente de aumentar sua expressividade.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/13-utility-packages/stringset.go)\n\n### Ignorando colisões de nomes de pacotes (#14)\n\n???+ info \"TL;DR\"\n\n    Para evitar colisões de nomes entre variáveis ​​e pacotes, levando a confusão ou talvez até bugs, use nomes exclusivos para cada um. Se isso não for viável, use um alias de importação para alterar o qualificador para diferenciar o nome do pacote do nome da variável ou pense em um nome melhor.\n\nAs colisões de pacotes ocorrem quando um nome de variável colide com um nome de pacote existente, impedindo que o pacote seja reutilizado. Devemos evitar colisões de nomes de variáveis ​​para evitar ambiguidade. Se enfrentarmos uma colisão, devemos encontrar outro nome significativo ou usar um alias de importação.\n\n### Documentação de código ausente (#15)\n\n???+ info \"TL;DR\"\n\n    Para ajudar clientes e mantenedores a entender a finalidade do seu código, documente os elementos exportados.\n\nA documentação é um aspecto importante da programação. Simplifica como os clientes podem consumir uma API, mas também pode ajudar na manutenção de um projeto. No Go, devemos seguir algumas regras para tornar nosso código idiomático:\n\nPrimeiro, cada elemento exportado deve ser documentado. Seja uma estrutura, uma interface, uma função ou qualquer outra coisa, se for exportado deve ser documentado. A convenção é adicionar comentários, começando com o nome do elemento exportado.\n\nPor convenção, cada comentário deve ser uma frase completa que termina com pontuação. Tenha também em mente que quando documentamos uma função (ou um método), devemos destacar o que a função pretende fazer, não como o faz; isso pertence ao núcleo de uma função e comentários, não à documentação. Além disso, o ideal é que a documentação forneça informações suficientes para que o consumidor não precise olhar nosso código para entender como usar um elemento exportado.\n\nQuando se trata de documentar uma variável ou constante, podemos estar interessados ​​em transmitir dois aspectos: sua finalidade e seu conteúdo. O primeiro deve funcionar como documentação de código para ser útil para clientes externos. Este último, porém, não deveria ser necessariamente público.\n\nPara ajudar clientes e mantenedores a entender o escopo de um pacote, devemos também documentar cada pacote. A convenção é iniciar o comentário com `// Package` seguido do nome do pacote. A primeira linha de um comentário de pacote deve ser concisa. Isso porque ele aparecerá no pacote. Então, podemos fornecer todas as informações que precisamos nas linhas seguintes.\n\nDocumentar nosso código não deve ser uma restrição. Devemos aproveitar a oportunidade para garantir que isso ajude os clientes e mantenedores a entender o propósito do nosso código.\n\n### Não usando linters (#16)\n\n???+ info \"TL;DR\"\n\n    Para melhorar a qualidade e consistência do código, use linters e formatadores.\n\nUm linter é uma ferramenta automática para analisar código e detectar erros. O escopo desta seção não é fornecer uma lista exaustiva dos linters existentes; caso contrário, ele ficará obsoleto rapidamente. Mas devemos entender e lembrar por que os linters são essenciais para a maioria dos projetos Go.\n\nNo entanto, se você não é um usuário regular de linters, aqui está uma lista que você pode usar diariamente:\n\n* [https://golang.org/cmd/vet](https://golang.org/cmd/vet)—A standard Go analyzer\n* [https://github.com/kisielk/errcheck](https://github.com/kisielk/errcheck)—An error checker\n* [https://github.com/fzipp/gocyclo](https://github.com/fzipp/gocyclo)—A cyclomatic complexity analyzer\n* [https://github.com/jgautheron/goconst](https://github.com/jgautheron/goconst)—A repeated string constants analyzer\n\n\nAlém dos linters, também devemos usar formatadores de código para corrigir o estilo do código. Aqui está uma lista de alguns formatadores de código para você experimentar:\n\n* [https://golang.org/cmd/gofmt](https://golang.org/cmd/gofmt)—A standard Go code formatter\n* [https://godoc.org/golang.org/x/tools/cmd/goimports](https://godoc.org/golang.org/x/tools/cmd/goimports)—A standard Go imports formatter\n\n\nEnquanto isso, devemos também dar uma olhada em golangci-lint ([https://github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint)).\nÉ uma ferramenta de linting que fornece uma fachada sobre muitos linters e formatadores úteis. Além disso, permite executar os linters em paralelo para melhorar a velocidade de análise, o que é bastante útil.\n\nLinters e formatadores são uma forma poderosa de melhorar a qualidade e consistência de nossa base de código. Vamos dedicar um tempo para entender qual deles devemos usar e garantir que automatizamos sua execução (como um precommit hook de CI ou Git).\n\n## Tipos de dados\n\n### Criando confusão com literais octais (#17)\n\n???+ info \"TL;DR\"\n\n    Ao ler o código existente, lembre-se de que literais inteiros começando com `0` são números octais. Além disso, para melhorar a legibilidade, torne os inteiros octais explícitos prefixando-os com `0o`.\n\nOs números octais começam com 0 (por exemplo, `010` é igual a 8 na base 10). Para melhorar a legibilidade e evitar possíveis erros para futuros leitores de código, devemos tornar os números octais explícitos usando o prefixo `0o` (por exemplo, `0o10`).\n\nDevemos também observar as outras representações literais inteiras:\n\n* _Binário_—Usa um prefixo `0b` ou `0B`(por exemplo, `0b100` é igual a 4 na base 10)\n* _Hexadecimal_—Usa um prefixo `0x` ou `0X` (por exemplo, `0xF` é igual a 15 na base 10)\n* _Imaginário_—Usa um `i` sufixo (por exemplo, `3i`)\n\nTambém podemos usar um caractere de sublinhado (_) como separador para facilitar a leitura. Por exemplo, podemos escrever 1 bilhão desta forma: `1_000_000_000`. Também podemos usar o caractere sublinhado com outras representações (por exemplo, `0b00_00_01`).\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/17-octal-literals/main.go)\n\n### Negligenciando estouros de número inteiro (#18)\n\n???+ info \"TL;DR\"\n\n    Como os overflows e underflows de números inteiros são tratados silenciosamente no Go, você pode implementar suas próprias funções para capturá-los.\n\nNo Go, um estouro de número inteiro que pode ser detectado em tempo de compilação gera um erro de compilação. Por exemplo,\n\n```go\nvar counter int32 = math.MaxInt32 + 1\n```\n\n```shell\nconstant 2147483648 overflows int32\n```\n\nNo entanto, em tempo de execução, um overflow ou underflow de inteiro é silencioso; isso não leva ao pânico do aplicativo. É essencial ter esse comportamento em mente, pois ele pode levar a bugs sorrateiros (por exemplo, um incremento de número inteiro ou adição de números inteiros positivos que leva a um resultado negativo).\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/18-integer-overflows)\n\n### Não entendendo os pontos flutuantes (#19)\n\n???+ info \"TL;DR\"\n\n    Fazer comparações de ponto flutuante dentro de um determinado delta pode garantir que seu código seja portátil. Ao realizar adição ou subtração, agrupe as operações com ordem de grandeza semelhante para favorecer a precisão. Além disso, execute multiplicação e divisão antes da adição e subtração.\n\nEm Go, existem dois tipos de ponto flutuante (se omitirmos os números imaginários): float32 e float64. O conceito de ponto flutuante foi inventado para resolver o principal problema dos números inteiros: sua incapacidade de representar valores fracionários. Para evitar surpresas desagradáveis, precisamos saber que a aritmética de ponto flutuante é uma aproximação da aritmética real.\n\nPara isso, veremos um exemplo de multiplicação:\n\n```go\nvar n float32 = 1.0001\nfmt.Println(n * n)\n```\n\nPodemos esperar que este código imprima o resultado de 1.0001 * 1.0001 = 1,00020001, certo? No entanto, executá-lo na maioria dos processadores x86 imprime 1.0002.\n\nComo os tipos `float32` e `float64` em Go são aproximações, temos que ter algumas regras em mente:\n\n* Ao comparar dois números de ponto flutuante, verifique se a diferença está dentro de um intervalo aceitável.\n* Ao realizar adições ou subtrações, agrupe operações com ordem de magnitude semelhante para melhor precisão.\n* Para favorecer a precisão, se uma sequência de operações exigir adição, subtração, multiplicação ou divisão, execute primeiro as operações de multiplicação e divisão.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/19-floating-points/main.go)\n\n### Não entendendo o comprimento e a capacidade de slice (#20)\n\n???+ info \"TL;DR\"\n\n    Compreender a diferença entre comprimento e capacidade da slice deve fazer parte do conhecimento básico de um desenvolvedor Go. O comprimento de slice é o número de elementos disponíveis na slice, enquanto a capacidade de slice é o número de elementos na matriz de apoio.\n\nLeia a seção completa [aqui](20-slice.md).\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/20-slice-length-cap/main.go)\n\n### Inicialização de slice ineficiente (#21)\n\n???+ info \"TL;DR\"\n\n    Ao criar uma fatia, inicialize-a com um determinado comprimento ou capacidade se o seu comprimento já for conhecido. Isso reduz o número de alocações e melhora o desempenho.\n\nAo inicializar uma fatia usando `make`, podemos fornecer um comprimento e uma capacidade opcional. Esquecer de passar um valor apropriado para ambos os parâmetros quando faz sentido é um erro generalizado. Na verdade, isso pode levar a múltiplas cópias e esforço adicional para o GC limpar as matrizes de apoio temporárias. Em termos de desempenho, não há uma boa razão para não ajudar o tempo de execução do Go.\n\nNossas opções são alocar uma fatia com determinada capacidade ou comprimento. Destas duas soluções, vimos que a segunda tende a ser um pouco mais rápida. Mas usar uma determinada capacidade e anexar pode ser mais fácil de implementar e ler em alguns contextos.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/21-slice-init/main.go)\n\n### Estar confuso sobre slice nula vs. slice vazia (#22)\n\n???+ info \"TL;DR\"\n\n    To prevent common confusions such as when using the `encoding/json` or the `reflect` package, you need to understand the difference between nil and empty slices. Both are zero-length, zero-capacity slices, but only a nil slice doesn’t require allocation.\n\nNo Go, há uma distinção entre slices nulas e vazias. Uma slice nula é igual a `nil`, enquanto uma slice vazia tem comprimento zero. Uma slice nula está vazia, mas uma slice vazia não é necessariamente `nil`. Enquanto isso, uma slice nula não requer nenhuma alocação. Vimos ao longo desta seção como inicializar uma slice dependendo do contexto usando\n\n* `var s []string` se não tivermos certeza sobre o comprimento final e a fatia pode estar vazia\n* `[]string(nil)` como açúcar sintático para criar uma fatia nula e vazia\n* `make([]string, length)` se o comprimento futuro for conhecido\n\nA última opção, `[]string{}` deve ser evitada se inicializarmos a fatia sem elementos. Finalmente, vamos verificar se as bibliotecas que usamos fazem distinções entre fatias nulas e vazias para evitar comportamentos inesperados.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/22-nil-empty-slice/)\n\n### Não verificar corretamente se um slice está vazio (#23)\n\n???+ info \"TL;DR\"\n\n    Para verificar se uma fatia não contém nenhum elemento, verifique seu comprimento. Esta verificação funciona independentemente de o slice estar `nil` ou vazio. O mesmo vale para maps. Para projetar APIs inequívocas, você não deve distinguir entre slice nulos e vazios.\n\nPara determinar se um slice possui elementos, podemos fazê-lo verificando se o slice é nulo ou se seu comprimento é igual a 0. Verificar o comprimento é a melhor opção a seguir, pois cobrirá ambos se o slice estiver vazio ou se o slice é nulo.\n\nEnquanto isso, ao projetar interfaces, devemos evitar distinguir slices nulos e vazios, o que leva a erros sutis de programação. Ao retornar slices, não deve haver diferença semântica nem técnica se retornarmos um slice nulo ou vazio. Ambos devem significar a mesma coisa para quem liga. Este princípio é o mesmo com maps. Para verificar se um map está vazio, verifique seu comprimento, não se é nulo.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/23-checking-slice-empty/main.go)\n\n### Não fazer cópias de slcies corretamente (#24)\n\n???+ info \"TL;DR\"\n\n    Para copiar um slice para outro usando a função `copy`, lembre-se que o número de elementos copiados corresponde ao mínimo entre os comprimentos dos dois slices.\n\nCopiar elementos de um slice para outro é uma operação razoavelmente frequente. Ao utilizar a cópia, devemos lembrar que o número de elementos copiados para o destino corresponde ao mínimo entre os comprimentos dos dois slices. Tenha também em mente que existem outras alternativas para copiar um slice, por isso não devemos nos surpreender se as encontrarmos em uma base de código.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/24-slice-copy/main.go)\n\n### Efeitos colaterais inesperados usando o slice append (#25)\n\n???+ info \"TL;DR\"\n\n    Usar `copy` ou a expressão de slice completa é uma forma de evitar que `append` crie conflitos se duas funções diferentes usarem slices apoiados pela mesmo array. No entanto, apenas uma cópia de slice evita vazamentos de memória se você quiser reduzir um slice grande.\n\nAo usar o slicing, devemos lembrar que podemos enfrentar uma situação que leva a efeitos colaterais não intencionais. Se o slice resultante tiver um comprimento menor que sua capacidade, o acréscimo poderá alterar o slice original. Se quisermos restringir a gama de possíveis efeitos colaterais, podemos usar uma cópia de slice ou a expressão de slice completa, o que nos impede de fazer uma cópia.\n\n???+ note\n\n    `s[low:high:max]`(expressão de slice completo): Esta instrução cria um slice semelhante àquele criado com `s[low:high]`, exceto que a capacidade de slice resultante é igual a `max - low`.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/25-slice-append/main.go)\n\n### Slices e vazamentos de memória (#26)\n\n???+ info \"TL;DR\"\n\n    Trabalhando com um slice de ponteiros ou estruturas com campos de ponteiro, você pode evitar vazamentos de memória marcando como nulos os elementos excluídos por uma operação de fatiamento.\n\n#### Vazamento de capacidade\n\nLembre-se de que fatiar um slice ou array grande pode levar a um potencial alto consumo de memória. O espaço restante não será recuperado pelo GC e podemos manter um grande array de apoio, apesar de usarmos apenas alguns elementos. Usar uma cópia em slice é a solução para evitar tal caso.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/26-slice-memory-leak/capacity-leak)\n\n#### Slice e ponteiros\n\nQuando usamos a operação de fatiamento com ponteiros ou estruturas com campos de ponteiro, precisamos saber que o GC não recuperará esses elementos. Nesse caso, as duas opções são realizar uma cópia ou marcar explicitamente os elementos restantes ou seus campos como `nil`.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/26-slice-memory-leak/slice-pointers)\n\n### Inicialização ineficiente do mapa (#27)\n\n???+ info \"TL;DR\"\n\n    Ao criar um mapa, inicialize-o com um determinado comprimento se o seu comprimento já for conhecido. Isso reduz o número de alocações e melhora o desempenho.\n\nUm mapa fornece uma coleção não ordenada de pares chave-valor em que todas as chaves são distintas. No Go, um mapa é baseado na estrutura de dados da tabela hash. Internamente, uma tabela hash é uma matriz de intervalos e cada intervalo é um ponteiro para uma matriz de pares de valores-chave.\n\nSe soubermos de antemão o número de elementos que um mapa conterá, devemos criá-lo fornecendo um tamanho inicial. Fazer isso evita o crescimento potencial do mapa, o que é bastante pesado em termos de computação porque requer a realocação de espaço suficiente e o reequilíbrio de todos os elementos.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/27-map-init/main_test.go)\n\n### Mapas e vazamentos de memória (#28)\n\n???+ info \"TL;DR\"\n\n    Um mapa sempre pode crescer na memória, mas nunca diminui. Portanto, se isso causar alguns problemas de memória, você pode tentar diferentes opções, como forçar Go a recriar o mapa ou usar ponteiros.\n\nLeia a seção completa [aqui](28-maps-memory-leaks.md).\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/28-map-memory-leak/main.go)\n\n### Comparando valores incorretamente (#29)\n\n???+ info \"TL;DR\"\n\n    Para comparar tipos em Go, você pode usar os operadores == e != se dois tipos forem comparáveis: booleanos, numerais, strings, ponteiros, canais e estruturas são compostos inteiramente de tipos comparáveis. Caso contrário, você pode usar `reflect.DeepEquale` pagar o preço da reflexão ou usar implementações e bibliotecas personalizadas.\n\nÉ essencial entender como usar `==` e `!=` para fazer comparações de forma eficaz. Podemos usar esses operadores em operandos comparáveis:\n\n* _Booleans_—Compara se dois booleanos são iguais.\n* _Numerics (int, float, and complex types)_—Compare se dois números são iguais.\n* _Strings_—Compare se duas strings são iguais.\n* _Channels_—Compare se dois canais foram criados pela mesma chamada a ser feita ou se ambos são nulos.\n* _Interfaces_—Compare se duas interfaces têm tipos dinâmicos idênticos e valores dinâmicos iguais ou se ambas são nulas.\n* _Pointers_—Compare se dois ponteiros apontam para o mesmo valor na memória ou se ambos são nulos.\n* _Structs and arrays_—Compare se são compostas de tipos semelhantes.\n\n???+ note\n\n    Também podemos usar os operadores `?`, `>=`, `<` e `>` com tipos numéricos para comparar valores e com strings para comparar sua ordem lexical.\n\nSe os operandos não forem comparáveis ​​(por exemplo, slices e mapas), teremos que usar outras opções, como reflexão. A reflexão é uma forma de metaprogramação e se refere à capacidade de um aplicativo de introspectar e modificar sua estrutura e comportamento. Por exemplo, em Go, podemos usar `reflect.DeepEqual`. Esta função informa se dois elementos são profundamente iguais percorrendo recursivamente dois valores. Os elementos que ele aceita são tipos básicos mais arrays, estruturas, slices, mapas, ponteiros, interfaces e funções. No entanto, o principal problema é a penalidade de desempenho.\n\nSe o desempenho for crucial em tempo de execução, implementar nosso método customizado pode ser a melhor solução. Uma observação adicional: devemos lembrar que a biblioteca padrão possui alguns métodos de comparação existentes. Por exemplo, podemos usar a função `bytes.Compare` otimizada para comparar duas slices de bytes. Antes de implementar um método customizado, precisamos ter certeza de não reinventar a roda.\n\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/29-comparing-values/main.go)\n\n## Estruturas de Controle\n\n### Ignorando que os elementos são copiados em loops de `range` (#30)\n\n???+ info \"TL;DR\"\n\n    O elemento de valor em um loop de `range` é uma cópia. Portanto, para modificar uma struct, por exemplo, acesse-a através de seu índice ou através de um loop `for` clássico (a menos que o elemento ou campo que você deseja modificar seja um ponteiro).\n\nUm range loop permite iterar em diferentes estruturas de dados:\n\n* String\n* Array\n* Pointer to an array\n* Slice\n* Map\n* Receiving channel\n\nComparado a um for `loop` clássico, um loop `range` é uma maneira conveniente de iterar todos os elementos de uma dessas estruturas de dados, graças à sua sintaxe concisa.\n\nAinda assim, devemos lembrar que o elemento de valor em um range loop é uma cópia. Portanto, se o valor for uma estrutura que precisamos sofrer mutação, atualizaremos apenas a cópia, não o elemento em si, a menos que o valor ou campo que modificamos seja um ponteiro. As opções preferidas são acessar o elemento através do índice usando um range loop ou um loop for clássico.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/30-range-loop-element-copied/)\n\n### Ignorando como os argumentos são avaliados em range loops (canais e arrays) (#31)\n\n???+ info \"TL;DR\"\n\n    Entender que a expressão passada ao operador `range` é avaliada apenas uma vez antes do início do loop pode ajudar a evitar erros comuns, como atribuição ineficiente em canal ou iteração de slice.\n\n\nO range loop avalia a expressão fornecida apenas uma vez, antes do início do loop, fazendo uma cópia (independentemente do tipo). Devemos lembrar deste comportamento para evitar erros comuns que podem, por exemplo, nos levar a acessar o elemento errado. Por exemplo:\n\n```go\na := [3]int{0, 1, 2}\nfor i, v := range a {\n    a[2] = 10\n    if i == 2 {\n        fmt.Println(v)\n    }\n}\n```\n\nEste código atualiza o último índice para 10. No entanto, se executarmos este código, ele não imprimirá 10; imprime 2.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/31-range-loop-arg-evaluation/)\n\n### :warning: Ignorando os impactos do uso de elementos ponteiros em `range` loops (#32)\n\n???+ warning\n\n    Este erro não é mais relevante no Go 1.22 ([detalhes](https://go.dev/blog/loopvar-preview)).\n\n### Fazendo suposições erradas durante as iterações de maps (ordenação e inserção do mapa durante a iteração) (#33)\n\n???+ info \"TL;DR\"\n\n    Para garantir resultados previsíveis ao usar maps, lembre-se de que uma estrutura de dados de mapa:\n\n* Não ordena os dados por chaves\n* Não preserva o pedido de inserção\n* Não tem uma ordem de iteração determinística\n* Não garante que um elemento adicionado durante uma iteração será produzido durante esta iteração\n\n<!-- TODO -->\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/33-map-iteration/main.go)\n\n### Ignorando como a declaração `break` funciona (#34)\n\n???+ info \"TL;DR\"\n\n    Usar `break` ou `continue` com um rótulo impõe a quebra de uma instrução específica. Isso pode ser útil com instruções `switch` ou `select` dentro de loops.\n\nUma instrução break é comumente usada para encerrar a execução de um loop. Quando loops são usados ​​em conjunto com switch ou select, os desenvolvedores frequentemente cometem o erro de quebrar a instrução errada. Por exemplo:\n\n```go\nfor i := 0; i < 5; i++ {\n    fmt.Printf(\"%d \", i)\n\n    switch i {\n    default:\n    case 2:\n        break\n    }\n}\n```\n\nA instrução break não encerra o loop `for`: em vez disso, ela encerra a instrução `switch`. Portanto, em vez de iterar de 0 a 2, este código itera de 0 a 4: `0 1 2 3 4`.\n\nUma regra essencial a ter em mente é que uma instrução `break` encerra a execução da instrução `for`, `switch`, ou mais interna `select`. No exemplo anterior, ele encerra a instrução `switch`.\n\nPara quebrar o loop em vez da instrução `switch`, a maneira mais idiomática é usar um rótulo:\n\n```go hl_lines=\"1 8\"\nloop:\n    for i := 0; i < 5; i++ {\n        fmt.Printf(\"%d \", i)\n\n        switch i {\n        default:\n        case 2:\n            break loop\n        }\n    }\n```\n\nAqui, associamos o `loop`rótulo ao `for` loop. Então, como fornecemos o `loop` rótulo para a instrução `break`, ela interrompe o loop, não a opção. Portanto, esta nova versão será impressa `0 1 2`, como esperávamos.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/34-break/main.go)\n\n### Usando `defer` dentro de um loop (#35)\n\n???+ info \"TL;DR\"\n\n    Extrair a lógica do loop dentro de uma função leva à execução de uma instrução `defer` no final de cada iteração.\n\nA instrução `defer` atrasa a execução de uma chamada até que a função circundante retorne. É usado principalmente para reduzir o código padrão. Por exemplo, se um recurso precisar ser fechado eventualmente, podemos usar `defer` para evitar a repetição das chamadas de fechamento antes de cada `return`.\n\nUm erro comum com `defer` é esquecer que ele agenda uma chamada de função quando a função _circundante_ retorna. Por exemplo:\n\n```go\nfunc readFiles(ch <-chan string) error {\n    for path := range ch {\n        file, err := os.Open(path)\n        if err != nil {\n            return err\n        }\n\n        defer file.Close()\n\n        // Do something with file\n    }\n    return nil\n}\n```\n\nAs chamadas `defer` não são executadas durante cada iteração do loop, mas quando a função `readFiles` retorna. Se `readFiles` não retornar, os descritores de arquivos ficarão abertos para sempre, causando vazamentos.\n\nUma opção comum para corrigir esse problema é criar uma função circundante após `defer`, chamada durante cada iteração:\n\n```go\nfunc readFiles(ch <-chan string) error {\n    for path := range ch {\n        if err := readFile(path); err != nil {\n            return err\n        }\n    }\n    return nil\n}\n\nfunc readFile(path string) error {\n    file, err := os.Open(path)\n    if err != nil {\n        return err\n    }\n\n    defer file.Close()\n\n    // Do something with file\n    return nil\n}\n```\n\nOutra solução é tornar a função `readFile` um encerramento, mas intrinsecamente, esta permanece a mesma solução: adicionar outra função circundante para executar as chamadas `defer` durante cada iteração.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/35-defer-loop/main.go)\n\n## Strings\n\n### Não entendendo o conceito de rune (#36)\n\n???+ info \"TL;DR\"\n\n    Entender que uma runa corresponde ao conceito de um ponto de código Unicode e que pode ser composta de múltiplos bytes deve fazer parte do conhecimento básico do desenvolvedor Go para trabalhar com precisão com strings.\n\nComo as runas estão por toda parte no Go, é importante entender o seguinte:\n\n* Um conjunto de caracteres é um conjunto de caracteres, enquanto uma codificação descreve como traduzir um conjunto de caracteres em binário.\n* No Go, uma string faz referência a uma fatia imutável de bytes arbitrários.\n* O código-fonte Go é codificado usando UTF-8. Portanto, todos os literais de string são strings UTF-8. Mas como uma string pode conter bytes arbitrários, se for obtida de outro lugar (não do código-fonte), não há garantia de que seja baseada na codificação UTF-8.\n* A `rune` corresponde ao conceito de ponto de código Unicode, significando um item representado por um único valor.\n* Usando UTF-8, um ponto de código Unicode pode ser codificado em 1 a 4 bytes.\n* Usar `len()` na string em Go retorna o número de bytes, não o número de runas.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/36-rune/main.go)\n\n### Iteração de string imprecisa (#37)\n\n???+ info \"TL;DR\"\n\n    Iterar em uma string com o operador `range` itera nas runas com o índice correspondente ao índice inicial da sequência de bytes da runa. Para acessar um índice de runa específico (como a terceira runa), converta a string em um arquivo `[]rune`.\n\nIterar em uma string é uma operação comum para desenvolvedores. Talvez queiramos realizar uma operação para cada runa na string ou implementar uma função personalizada para procurar uma substring específica. Em ambos os casos, temos que iterar nas diferentes runas de uma string. Mas é fácil ficar confuso sobre como funciona a iteração.\n\nFor example, consider the following example:\n\n```go\ns := \"hêllo\"\nfor i := range s {\n    fmt.Printf(\"position %d: %c\\n\", i, s[i])\n}\nfmt.Printf(\"len=%d\\n\", len(s))\n```\n\n```\nposition 0: h\nposition 1: Ã\nposition 3: l\nposition 4: l\nposition 5: o\nlen=6\n```\n\nVamos destacar três pontos que podem ser confusos:\n\n* A segunda runa é Ã na saída em vez de ê.\n* Saltamos da posição 1 para a posição 3: o que há na posição 2?\n* len retorna uma contagem de 6, enquanto s contém apenas 5 runas.\n\nVamos começar com a última observação. Já mencionamos que len retorna o número de bytes em uma string, não o número de runas. Como atribuímos uma string literal a `s`, `s` é uma string UTF-8. Enquanto isso, o caractere especial “ê” não é codificado em um único byte; requer 2 bytes. Portanto, chamar `len(s)` retorna 6.\n\nEnquanto isso, no exemplo anterior, temos que entender que não repetimos cada runa; em vez disso, iteramos sobre cada índice inicial de uma runa:\n\n![](img/rune.png)\n\nImprimir `s[i]` não imprime a i-ésima runa; imprime a representação UTF-8 do byte em index `i`. Portanto, imprimimos \"hÃllo\" em vez de \"hêllo\".\n\nSe quisermos imprimir todas as diferentes runas, podemos usar o elemento value do operador `range`:\n\n```go\ns := \"hêllo\"\nfor i, r := range s {\n    fmt.Printf(\"position %d: %c\\n\", i, r)\n}\n```\n\nOu podemos converter a string em uma fatia de runas e iterar sobre ela:\n\n\n```go hl_lines=\"2\"\ns := \"hêllo\"\nrunes := []rune(s)\nfor i, r := range runes {\n    fmt.Printf(\"position %d: %c\\n\", i, r)\n}\n```\n\nObserve que esta solução introduz uma sobrecarga de tempo de execução em comparação com a anterior. Na verdade, converter uma string em uma fatia de runas requer a alocação de uma fatia adicional e a conversão dos bytes em runas: uma complexidade de tempo O(n) com n o número de bytes na string. Portanto, se quisermos iterar todas as runas, devemos usar a primeira solução.\n\nPorém, se quisermos acessar a i-ésima runa de uma string com a primeira opção, não teremos acesso ao índice da runa; em vez disso, conhecemos o índice inicial de uma runa na sequência de bytes.\n\n```go\ns := \"hêllo\"\nr := []rune(s)[4]\nfmt.Printf(\"%c\\n\", r) // o\n```\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/37-string-iteration/main.go)\n\n### Uso indevido de funções de trim (#38)\n\n???+ info \"TL;DR\"\n\n    `strings.TrimRight`/`strings.TrimLeft` remove todas as runas finais/iniciais contidas em um determinado conjunto, enquanto `strings.TrimSuffix`/`strings.TrimPrefix` retorna uma string sem um sufixo/prefixo fornecido.\n\nPor exemplo:\n\n```go\nfmt.Println(strings.TrimRight(\"123oxo\", \"xo\"))\n```\n\nO exemplo imprime 123:\n\n![](img/trim.png)\n\nPor outro lado, `strings.TrimLeft` remove todas as runas principais contidas em um conjunto.\n\nPor outro lado, `strings.TrimSuffix`/`strings.TrimPrefix` retorna uma string sem o sufixo/prefixo final fornecido.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/38-trim/main.go)\n\n### Concatenação de strings subotimizada (#39)\n\n???+ info \"TL;DR\"\n\n    A concatenação de uma lista de strings deve ser feita com `strings.Builder` para evitar a alocação de uma nova string durante cada iteração.\n\nVamos considerar uma função `concat` que concatena todos os elementos string de uma fatia usando o operador `+=`:\n\n```go\nfunc concat(values []string) string {\n    s := \"\"\n    for _, value := range values {\n        s += value\n    }\n    return s\n}\n```\n\nDurante cada iteração, o operador `+=` concatena com `s` a sequência de valores. À primeira vista, esta função pode não parecer errada. Mas com esta implementação, esquecemos uma das principais características de uma string: a sua imutabilidade. Portanto, cada iteração não é atualizada `s`; ele realoca uma nova string na memória, o que impacta significativamente o desempenho desta função.\n\nFelizmente, existe uma solução para lidar com esse problema, usando `strings.Builder`:\n\n```go hl_lines=\"2 4\"\nfunc concat(values []string) string {\n    sb := strings.Builder{}\n    for _, value := range values {\n        _, _ = sb.WriteString(value)\n    }\n    return sb.String()\n}\n```\n\nDurante cada iteração, construímos a string resultante chamando o método `WriteString` que anexa o conteúdo do valor ao seu buffer interno, minimizando assim a cópia da memória.\n\n???+ note\n\n    `WriteString` retorna um erro como segunda saída, mas nós o ignoramos propositalmente. Na verdade, este método nunca retornará um erro diferente de zero. Então, qual é o propósito deste método retornar um erro como parte de sua assinatura? `strings.Builder` implementa a `io.StringWriter` interface, que contém um único método: `WriteString(s string) (n int, err error)`. Portanto, para estar em conformidade com esta interface, `WriteString` deve retornar um erro.\n\nInternamente, `strings.Builder` contém uma fatia de bytes. Cada chamada para `WriteString` resulta em uma chamada para anexar nesta fatia. Existem dois impactos. Primeiro, esta estrutura não deve ser usada simultaneamente, pois as chamadas `append` levariam a condições de corrida. O segundo impacto é algo que vimos no [mistake #21, \"Inicialização de slice ineficiente\"](#inefficient-slice-initialization-21): se o comprimento futuro de uma slice já for conhecido, devemos pré-alocá-la. Para isso, `strings.Builder` expõe um método `Grow(n int)` para garantir espaço para outros `n` bytes:\n\n```go\nfunc concat(values []string) string {\n    total := 0\n    for i := 0; i < len(values); i++ {\n        total += len(values[i])\n    }\n\n    sb := strings.Builder{}\n    sb.Grow(total) (2)\n    for _, value := range values {\n        _, _ = sb.WriteString(value)\n    }\n    return sb.String()\n}\n```\n\nVamos executar um benchmark para comparar as três versões (v1 usando `+=`; v2 usando `strings.Builder{}` sem pré-alocação; e v3 usando `strings.Builder{}` com pré-alocação). A slice de entrada contém 1.000 strings e cada string contém 1.000 bytes:\n\n```\nBenchmarkConcatV1-4             16      72291485 ns/op\nBenchmarkConcatV2-4           1188        878962 ns/op\nBenchmarkConcatV3-4           5922        190340 ns/op\n```\n\nComo podemos ver, a versão mais recente é de longe a mais eficiente: 99% mais rápida que a v1 e 78% mais rápida que a v2.\n\n`strings.Builder` é a solução recomendada para concatenar uma lista de strings. Normalmente, esta solução deve ser usada dentro de um loop. Na verdade, se precisarmos apenas concatenar algumas strings (como um nome e um sobrenome), o uso `strings.Builder` não é recomendado, pois isso tornará o código um pouco menos legível do que usar o operador `+=` or `fmt.Sprintf`.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/39-string-concat/)\n\n### Conversões de string inúteis (#40)\n\n???+ info \"TL;DR\"\n\n    Lembrar que o pacote `bytes` oferece as mesmas operações que o pacote `strings` pode ajudar a evitar conversões extras de bytes/string.\n\nAo optar por trabalhar com uma string ou um `[]byte`, a maioria dos programadores tende a preferir strings por conveniência. Mas a maior parte da E/S é realmente feita com `[]byte`. Por exemplo, `io.Reader`, `io.Writer` e `io.ReadAll` trabalham com `[]byte`, não com strings.\n\nQuando nos perguntamos se devemos trabalhar com strings ou `[]byte`, lembremos que trabalhar com `[]byte`não é necessariamente menos conveniente. Na verdade, todas as funções exportadas do pacote strings também possuem alternativas no pacote `bytes`: `Split`, `Count`, `Contains`, `Index` e assim por diante. Portanto, estejamos fazendo I/O ou não, devemos primeiro verificar se poderíamos implementar um fluxo de trabalho completo usando bytes em vez de strings e evitar o preço de conversões adicionais.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/40-string-conversion/main.go)\n\n### Vazamentos de substring e memória (#41)\n\n???+ info \"TL;DR\"\n\n    Usar cópias em vez de substrings pode evitar vazamentos de memória, pois a string retornada por uma operação de substring será apoiada pela mesma matriz de bytes.\n\nIn mistake [#26, “Slices and memory leaks,”](#slice-and-memory-leaks--26-) we saw how slicing a slice or array may lead to memory leak situations. This principle also applies to string and substring operations.\n\nWe need to keep two things in mind while using the substring operation in Go. First, the interval provided is based on the number of bytes, not the number of runes. Second, a substring operation may lead to a memory leak as the resulting substring will share the same backing array as the initial string. The solutions to prevent this case from happening are to perform a string copy manually or to use `strings.Clone` from Go 1.18.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/41-substring-memory-leak/main.go)\n\n## Functions and Methods\n\n### Não saber que tipo de receptor usar (#42)\n\n???+ info \"TL;DR\"\n\n    A decisão de usar um valor ou um receptor de ponteiro deve ser tomada com base em fatores como o tipo, se deve sofrer mutação, se contém um campo que não pode ser copiado e o tamanho do objeto. Em caso de dúvida, use um receptor de ponteiro.\n\nChoosing between value and pointer receivers isn’t always straightforward. Let’s discuss some of the conditions to help us choose.\n\nA receiver _must_ be a pointer\n\n* If the method needs to mutate the receiver. This rule is also valid if the receiver is a slice and a method needs to append elements:\n\n  ```go\n  type slice []int\n\n  func (s *slice) add(element int) {\n      *s = append(*s, element)\n  }\n  ```\n\n* If the method receiver contains a field that cannot be copied: for example, a type part of the sync package (see [#74, “Copying a sync type”](#copying-a-sync-type--74-)).\n\nA receiver _should_ be a pointer\n\n* If the receiver is a large object. Using a pointer can make the call more efficient, as doing so prevents making an extensive copy. When in doubt about how large is large, benchmarking can be the solution; it’s pretty much impossible to state a specific size, because it depends on many factors.\n\nA receiver _must_ be a value\n\n* If we have to enforce a receiver’s immutability.\n* If the receiver is a map, function, or channel. Otherwise, a compilation error\n  occurs.\n\nA receiver _should_ be a value\n\n* If the receiver is a slice that doesn’t have to be mutated.\n* If the receiver is a small array or struct that is naturally a value type without mutable fields, such as `time.Time`.\n* If the receiver is a basic type such as `int`, `float64`, or `string`.\n\nOf course, it’s impossible to be exhaustive, as there will always be edge cases, but this section’s goal was to provide guidance to cover most cases. By default, we can choose to go with a value receiver unless there’s a good reason not to do so. In doubt, we should use a pointer receiver.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/42-receiver/)\n\n### Nunca usando parâmetros de resultado nomeados (#43)\n\n???+ info \"TL;DR\"\n\n    Usar parâmetros de resultado nomeados pode ser uma maneira eficiente de melhorar a legibilidade de uma função/método, especialmente se vários parâmetros de resultado tiverem o mesmo tipo. Em alguns casos, esta abordagem também pode ser conveniente porque os parâmetros de resultado nomeados são inicializados com seu valor zero. Mas tenha cuidado com os possíveis efeitos colaterais.\n\nWhen we return parameters in a function or a method, we can attach names to these parameters and use them as regular variables. When a result parameter is named, it’s initialized to its zero value when the function/method begins. With named result parameters, we can also call a naked return statement (without arguments). In that case, the current values of the result parameters are used as the returned values.\n\nHere’s an example that uses a named result parameter `b`:\n\n```go\nfunc f(a int) (b int) {\n    b = a\n    return\n}\n```\n\nIn this example, we attach a name to the result parameter: `b`. When we call return without arguments, it returns the current value of `b`.\n\nIn some cases, named result parameters can also increase readability: for example, if two parameters have the same type. In other cases, they can also be used for convenience. Therefore, we should use named result parameters sparingly when there’s a clear benefit.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/43-named-result-parameters/main.go)\n\n### Efeitos colaterais não intencionais com parâmetros de resultado nomeados (#44)\n\n???+ info \"TL;DR\"\n\n    Consulte [#43](#never-using-named-result-parameters-43).\n\nWe mentioned why named result parameters can be useful in some situations. But as these result parameters are initialized to their zero value, using them can sometimes lead to subtle bugs if we’re not careful enough. For example, can you spot what’s wrong with this code?\n\n```go\nfunc (l loc) getCoordinates(ctx context.Context, address string) (\n    lat, lng float32, err error) {\n    isValid := l.validateAddress(address) (1)\n    if !isValid {\n        return 0, 0, errors.New(\"invalid address\")\n    }\n\n    if ctx.Err() != nil { (2)\n        return 0, 0, err\n    }\n\n    // Get and return coordinates\n}\n```\n\nThe error might not be obvious at first glance. Here, the error returned in the `if ctx.Err() != nil` scope is `err`. But we haven’t assigned any value to the `err` variable. It’s still assigned to the zero value of an `error` type: `nil`. Hence, this code will always return a nil error.\n\n\nWhen using named result parameters, we must recall that each parameter is initialized to its zero value. As we have seen in this section, this can lead to subtle bugs that aren’t always straightforward to spot while reading code. Therefore, let’s remain cautious when using named result parameters, to avoid potential side effects.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/44-side-effects-named-result-parameters/main.go)\n\n### Retornando um receptor nulo (#45)\n\n???+ info \"TL;DR\"\n\n    Ao retornar uma interface, tenha cuidado para não retornar um ponteiro nulo, mas um valor nulo explícito. Caso contrário, poderão ocorrer consequências não intencionais e o chamador receberá um valor diferente de zero.\n\n<!-- TODO -->\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/45-nil-receiver/main.go)\n\n### Usando um nome de arquivo como entrada de função (#46)\n\n???+ info \"TL;DR\"\n\n    Projetar funções para receber tipos `io.Reader` em vez de nomes de arquivos melhora a capacidade de reutilização de uma função e facilita o teste.\n\nAccepting a filename as a function input to read from a file should, in most cases, be considered a code smell (except in specific functions such as `os.Open`). Indeed, it makes unit tests more complex because we may have to create multiple files. It also reduces the reusability of a function (although not all functions are meant to be reused). Using the `io.Reader` interface abstracts the data source. Regardless of whether the input is a file, a string, an HTTP request, or a gRPC request, the implementation can be reused and easily tested.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/46-function-input/)\n\n### Ignorando como argumentos `defer` e receptores são avaliados (avaliação de argumentos, ponteiros e receptores de valor) (#47)\n\n???+ info \"TL;DR\"\n\n    Passar um ponteiro para uma função `defer` e agrupar uma chamada dentro de um closure são duas soluções possíveis para superar a avaliação imediata de argumentos e receptores.\n\nIn a `defer` function the arguments are evaluated right away, not once the surrounding function returns. For example, in this code, we always call `notify` and `incrementCounter` with the same status: an empty string.\n\n```go\nconst (\n    StatusSuccess  = \"success\"\n    StatusErrorFoo = \"error_foo\"\n    StatusErrorBar = \"error_bar\"\n)\n\nfunc f() error {\n    var status string\n    defer notify(status)\n    defer incrementCounter(status)\n\n    if err := foo(); err != nil {\n        status = StatusErrorFoo\n        return err\n    }\n\n    if err := bar(); err != nil {\n        status = StatusErrorBar\n        return err\n    }\n\n    status = StatusSuccess <5>\n    return nil\n}\n```\n\nIndeed, we call `notify(status)` and `incrementCounter(status)` as `defer` functions. Therefore, Go will delay these calls to be executed once `f` returns with the current value of status at the stage we used defer, hence passing an empty string.\n\nTwo leading options if we want to keep using `defer`.\n\nThe first solution is to pass a string pointer:\n\n```go hl_lines=\"3 4\"\nfunc f() error {\n    var status string\n    defer notify(&status) \n    defer incrementCounter(&status)\n\n    // The rest of the function unchanged\n}\n```\n\nUsing `defer` evaluates the arguments right away: here, the address of status. Yes, status itself is modified throughout the function, but its address remains constant, regardless of the assignments. Hence, if `notify` or `incrementCounter` uses the value referenced by the string pointer, it will work as expected. But this solution requires changing the signature of the two functions, which may not always be possible.\n\nThere’s another solution: calling a closure (an anonymous function value that references variables from outside its body) as a `defer` statement:\n\n```go hl_lines=\"3 4 5 6\"\nfunc f() error {\n    var status string\n    defer func() {\n        notify(status)\n        incrementCounter(status)\n    }()\n\n    // The rest of the function unchanged\n}\n```\n\nHere, we wrap the calls to both `notify` and `incrementCounter` within a closure. This closure references the status variable from outside its body. Therefore, `status` is evaluated once the closure is executed, not when we call `defer`. This solution also works and doesn’t require `notify` and `incrementCounter` to change their signature.\n\nLet's also note this behavior applies with method receiver: the receiver is evaluated immediately.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/47-defer-evaluation/)\n\n## Error Management\n\n### Pânico (#48)\n\n???+ info \"TL;DR\"\n\n    Usar `panic` é uma opção para lidar com erros no Go. No entanto, só deve ser usado com moderação em condições irrecuperáveis: por exemplo, para sinalizar um erro do programador ou quando você não consegue carregar uma dependência obrigatória.\n\nIn Go, panic is a built-in function that stops the ordinary flow:\n\n```go\nfunc main() {\n    fmt.Println(\"a\")\n    panic(\"foo\")\n    fmt.Println(\"b\")\n}\n```\n\nThis code prints a and then stops before printing b:\n\n```\na\npanic: foo\n\ngoroutine 1 [running]:\nmain.main()\n        main.go:7 +0xb3\n```\n\nPanicking in Go should be used sparingly. There are two prominent cases, one to signal a programmer error (e.g., [`sql.Register`](https://cs.opensource.google/go/go/+/refs/tags/go1.20.7:src/database/sql/sql.go;l=44) that panics if the driver is `nil` or has already been register) and another where our application fails to create a mandatory dependency. Hence, exceptional conditions that lead us to stop the application. In most other cases, error management should be done with a function that returns a proper error type as the last return argument.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/48-panic/main.go)\n\n### Ignorando quando embrulhar um erro (#49)\n\n???+ info \"TL;DR\"\n\n    Embrulhar um erro permite marcar um erro e/ou fornecer contexto adicional. No entanto, o agrupamento de erros cria um acoplamento potencial, pois disponibiliza o erro de origem para o chamador. Se você quiser evitar isso, não use a agrupamento automático de erros.\n\nSince Go 1.13, the %w directive allows us to wrap errors conveniently. Error wrapping is about wrapping or packing an error inside a wrapper container that also makes the source error available. In general, the two main use cases for error wrapping are the following:\n\n* Adding additional context to an error\n* Marking an error as a specific error\n\nWhen handling an error, we can decide to wrap it. Wrapping is about adding additional context to an error and/or marking an error as a specific type. If we need to mark an error, we should create a custom error type. However, if we just want to add extra context, we should use fmt.Errorf with the %w directive as it doesn’t require creating a new error type. Yet, error wrapping creates potential coupling as it makes the source error available for the caller. If we want to prevent it, we shouldn’t use error wrapping but error transformation, for example, using fmt.Errorf with the %v directive.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/49-error-wrapping/main.go)\n\n### Comparando um tipo de erro de forma imprecisa (#50)\n\n???+ info \"TL;DR\"\n\n    Se você usar o agrupamento de erros do Go 1.13 com a diretiva `%w` e `fmt.Errorf`, a comparação de um erro com um tipo deverá ser feita usando `errors.As`. Caso contrário, se o erro retornado que você deseja verificar for embrulhado, as verificações falharão.\n\n<!-- TODO -->\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/50-compare-error-type/main.go)\n\n### Comparando um valor de erro incorretamente (#51)\n\n???+ info \"TL;DR\"\n\n    Se você usar o agrupamento de erros do Go 1.13 com a diretiva `%w` e `fmt.Errorf`, a comparação de um erro ou de um valor deverá ser feita usando `errors.As`. Caso contrário, se o erro retornado que você deseja verificar for embrulhado, as verificações falharão.\n\nA sentinel error is an error defined as a global variable:\n\n```go\nimport \"errors\"\n\nvar ErrFoo = errors.New(\"foo\")\n```\n\nIn general, the convention is to start with `Err` followed by the error type: here, `ErrFoo`. A sentinel error conveys an _expected_ error, an error that clients will expect to check. As general guidelines:\n\n* Expected errors should be designed as error values (sentinel errors): `var ErrFoo = errors.New(\"foo\")`.\n* Unexpected errors should be designed as error types: `type BarError struct { ... }`, with `BarError` implementing the `error` interface.\n\nIf we use error wrapping in our application with the `%w` directive and `fmt.Errorf`, checking an error against a specific value should be done using `errors.Is` instead of `==`. Thus, even if the sentinel error is wrapped, `errors.Is` can recursively unwrap it and compare each error in the chain against the provided value.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/51-comparing-error-value/main.go)\n\n### Lidando com um erro duas vezes (#52)\n\n???+ info \"TL;DR\"\n\n    Na maioria das situações, um erro deve ser tratado apenas uma vez. Registrar um erro é tratar um erro. Portanto, você deve escolher entre registrar ou retornar um erro. Em muitos casos, o embrulho automático de erros é a solução, pois permite fornecer contexto adicional a um erro e retornar o erro de origem.\n\nHandling an error multiple times is a mistake made frequently by developers, not specifically in Go. This can cause situations where the same error is logged multiple times make debugging harder.\n\nLet's remind us that handling an error should be done only once. Logging an error is handling an error. Hence, we should either log or return an error. By doing this, we simplify our code and gain better insights into the error situation. Using error wrapping is the most convenient approach as it allows us to propagate the source error and add context to an error.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/52-handling-error-twice/main.go)\n\n### Não tratando de um erro (#53)\n\n???+ info \"TL;DR\"\n\n    Ignorar um erro, seja durante uma chamada de função ou em uma função `defer`, deve ser feito explicitamente usando o identificador em branco. Caso contrário, os futuros leitores poderão ficar confusos sobre se foi intencional ou um erro.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/53-not-handling-error/main.go)\n\n### Não tratando erros de `defer` (#54)\n\n???+ info \"TL;DR\"\n\n    Em muitos casos, você não deve ignorar um erro retornado por uma função `defer`. Manipule-o diretamente ou propague-o para o chamador, dependendo do contexto. Se você quiser ignorá-lo, use o identificador em branco.\n\nConsider the following code:\n\n```go\nfunc f() {\n  // ...\n  notify() // Error handling is omitted\n}\n\nfunc notify() error {\n  // ...\n}\n```\n\nFrom a maintainability perspective, the code can lead to some issues. Let’s consider a new reader looking at it. This reader notices that notify returns an error but that the error isn’t handled by the parent function. How can they guess whether or not handling the error was intentional? How can they know whether the previous developer forgot to handle it or did it purposely?\n\nFor these reasons, when we want to ignore an error, there's only one way to do it, using the blank identifier (`_`):\n\n```go\n_ = notify\n```\n\nIn terms of compilation and run time, this approach doesn’t change anything compared to the first piece of code. But this new version makes explicit that we aren’t interested in the error. Also, we can add a comment that indicates the rationale for why an error is ignored:\n\n```go\n// At-most once delivery.\n// Hence, it's accepted to miss some of them in case of errors.\n_ = notify()\n```\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/54-defer-errors/main.go)\n\n## Concurrency: Foundations\n\n### Misturando simultaneidade e paralelismo (#55)\n\n???+ info \"TL;DR\"\n\n    Compreender as diferenças fundamentais entre simultaneidade e paralelismo é a base do conhecimento do desenvolvedor Go. A simultaneidade tem a ver com estrutura, enquanto o paralelismo tem a ver com execução.\n\nConcurrency and parallelism are not the same:\n\n* Concurrency is about structure. We can change a sequential implementation into a concurrent one by introducing different steps that separate concurrent goroutines can tackle.\n* Meanwhile, parallelism is about execution. We can use parallism at the steps level by adding more parallel goroutines.\n\nIn summary, concurrency provides a structure to solve a problem with parts that may be parallelized. Therefore, _concurrency enables parallelism_.\n\n<!-- TODO Include Rob Pike's talk link-->\n\n### Pensar que a simultaneidade é sempre mais rápida (#56)\n\n???+ info \"TL;DR\"\n\n    Para ser um desenvolvedor proficiente, você deve reconhecer que a simultaneidade nem sempre é mais rápida. As soluções que envolvem a paralelização de cargas de trabalho mínimas podem não ser necessariamente mais rápidas do que uma implementação sequencial. A avaliação comparativa de soluções sequenciais versus soluções simultâneas deve ser a forma de validar suposições.\n\nRead the full section [here](56-concurrency-faster.md).\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/56-faster/)\n\n### Ficar confuso sobre quando usar canais ou mutexes (#57)\n\n???+ info \"TL;DR\"\n\n    Estar ciente das interações goroutine também pode ser útil ao decidir entre canais e mutexes. Em geral, goroutines paralelas requerem sincronização e, portanto, mutexes. Por outro lado, goroutines simultâneas geralmente requerem coordenação e orquestração e, portanto, canais.\n\nGiven a concurrency problem, it may not always be clear whether we can implement a\nsolution using channels or mutexes. Because Go promotes sharing memory by communication, one mistake could be to always force the use of channels, regardless of\nthe use case. However, we should see the two options as complementary. \n\nWhen should we use channels or mutexes? We will use the example in the next figure as a backbone. Our example has three different goroutines with specific relationships:\n\n* G1 and G2 are parallel goroutines. They may be two goroutines executing the same function that keeps receiving messages from a channel, or perhaps two goroutines executing the same HTTP handler at the same time.\n* On the other hand, G1 and G3 are concurrent goroutines, as are G2 and G3. All the goroutines are part of an overall concurrent structure, but G1 and G2 perform the first step, whereas G3 does the next step.\n\n<!-- TODO Include figure-->\n\nIn general, parallel goroutines have to _synchronize_: for example, when they need to access or mutate a shared resource such as a slice. Synchronization is enforced with mutexes but not with any channel types (not with buffered channels). Hence, in general, synchronization between parallel goroutines should be achieved via mutexes.\n\nConversely, in general, concurrent goroutines have to _coordinate and orchestrate_. For example, if G3 needs to aggregate results from both G1 and G2, G1 and G2 need to signal to G3 that a new intermediate result is available. This coordination falls under the scope of communication—therefore, channels.\n\nRegarding concurrent goroutines, there’s also the case where we want to transfer the ownership of a resource from one step (G1 and G2) to another (G3); for example, if G1 and G2 are enriching a shared resource and at some point, we consider this job as complete. Here, we should use channels to signal that a specific resource is ready and handle the ownership transfer.\n\nMutexes and channels have different semantics. Whenever we want to share a state or access a shared resource, mutexes ensure exclusive access to this resource. Conversely, channels are a mechanic for signaling with or without data (`chan struct{}` or not). Coordination or ownership transfer should be achieved via channels. It’s important to know whether goroutines are parallel or concurrent because, in general, we need mutexes for parallel goroutines and channels for concurrent ones.\n\n### Não entender os problemas de corrida (corridas de dados vs. condições de corrida e o modelo de memória Go) (#58)\n\n???+ info \"TL;DR\"\n\n    Ser proficiente em simultaneidade também significa compreender que corridas de dados e condições de corrida são conceitos diferentes. As corridas de dados ocorrem quando várias goroutines acessam simultaneamente o mesmo local de memória e pelo menos uma delas está gravando. Enquanto isso, estar livre de disputa de dados não significa necessariamente execução determinística. Quando um comportamento depende da sequência ou do tempo de eventos que não podem ser controlados, esta é uma condição de corrida.\n\nRace problems can be among the hardest and most insidious bugs a programmer can face. As Go developers, we must understand crucial aspects such as data races and race conditions, their possible impacts, and how to avoid them.\n\n#### Data Race\n\nA data race occurs when two or more goroutines simultaneously access the same memory location and at least one is writing. In this case, the result can be hazardous. Even worse, in some situations, the memory location may end up holding a value containing a meaningless combination of bits.\n\nWe can prevent a data race from happening using different techniques. For example: \n\n* Using the `sync/atomic` package\n* In synchronizing the two goroutines with an ad hoc data structure like a mutex\n* Using channels to make the two goroutines communicating to ensure that a variable is updated by only one goroutine at a time\n\n#### Race Condition\n\nDepending on the operation we want to perform, does a data-race-free application necessarily mean a deterministic result? Not necessarily.\n\nA race condition occurs when the behavior depends on the sequence or the timing of events that can’t be controlled. Here, the timing of events is the goroutines’ execution order.\n\nIn summary, when we work in concurrent applications, it’s essential to understand that a data race is different from a race condition. A data race occurs when multiple goroutines simultaneously access the same memory location and at least one of them is writing. A data race means unexpected behavior. However, a data-race-free application doesn’t necessarily mean deterministic results. An application can be free of data races but still have behavior that depends on uncontrolled events (such as goroutine execution, how fast a message is published to a channel, or how long a call to a database lasts); this is a race condition. Understanding both concepts is crucial to becoming proficient in designing concurrent applications.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/58-races/)\n\n### Não compreender os impactos de simultaneidade de um tipo de carga de trabalho (#59)\n\n???+ info \"TL;DR\"\n\n    Ao criar um determinado número de goroutines, considere o tipo de carga de trabalho. Criar goroutines vinculadas à CPU significa limitar esse número próximo à variável GOMAXPROCS (baseado por padrão no número de núcleos de CPU no host). A criação de goroutines vinculadas a E/S depende de outros fatores, como o sistema externo.\n\nIn programming, the execution time of a workload is limited by one of the following:\n\n* The speed of the CPU—For example, running a merge sort algorithm. The workload is called CPU-bound.\n* The speed of I/O—For example, making a REST call or a database query. The workload is called I/O-bound.\n* The amount of available memory—The workload is called memory-bound.\n\n???+ note\n\n    The last is the rarest nowadays, given that memory has become very cheap in recent decades. Hence, this section focuses on the two first workload types: CPU- and I/O-bound.\n\nIf the workload executed by the workers is I/O-bound, the value mainly depends on the external system. Conversely, if the workload is CPU-bound, the optimal number of goroutines is close to the number of available CPU cores (a best practice can be to use `runtime.GOMAXPROCS`). Knowing the workload type (I/O or CPU) is crucial when designing concurrent applications.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/59-workload-type/main.go)\n\n### Incompreensão dos contextos Go (#60)\n\n???+ info \"TL;DR\"\n\n    Os contextos Go também são um dos pilares da simultaneidade em Go. Um contexto permite que você carregue um prazo, um sinal de cancelamento e/ou uma lista de valores-chave.\n\n!!! quote \"https://pkg.go.dev/context\"\n\n    A Context carries a deadline, a cancellation signal, and other values across API boundaries.\n\n#### Deadline\n\nA deadline refers to a specific point in time determined with one of the following:\n\n* A `time.Duration` from now (for example, in 250 ms)\n* A `time.Time` (for example, 2023-02-07 00:00:00 UTC)\n\nThe semantics of a deadline convey that an ongoing activity should be stopped if this deadline is met. An activity is, for example, an I/O request or a goroutine waiting to receive a message from a channel.\n\n#### Cancellation signals\n\nAnother use case for Go contexts is to carry a cancellation signal. Let’s imagine that we want to create an application that calls `CreateFileWatcher(ctx context.Context, filename string)` within another goroutine. This function creates a specific file watcher that keeps reading from a file and catches updates. When the provided context expires or is canceled, this function handles it to close the file descriptor.\n\n#### Context values\n\nThe last use case for Go contexts is to carry a key-value list. What’s the point of having a context carrying a key-value list? Because Go contexts are generic and mainstream, there are infinite use cases.\n\nFor example, if we use tracing, we may want different subfunctions to share the same correlation ID. Some developers may consider this ID too invasive to be part of the function signature. In this regard, we could also decide to include it as part of the provided context.\n\n#### Catching a context cancellation\n\nThe `context.Context` type exports a `Done` method that returns a receive-only notification channel: `<-chan struct{}`. This channel is closed when the work associated with the context should be canceled. For example,\n\n* The Done channel related to a context created with `context.WithCancel` is closed when the cancel function is called.\n* The Done channel related to a context created with `context.WithDeadline` is closed when the deadline has expired.\n\nOne thing to note is that the internal channel should be closed when a context is canceled or has met a deadline, instead of when it receives a specific value, because the closure of a channel is the only channel action that all the consumer goroutines will receive. This way, all the consumers will be notified once a context is canceled or a deadline is reached.\n\nIn summary, to be a proficient Go developer, we have to understand what a context is and how to use it. In general, a function that users wait for should take a context, as doing so allows upstream callers to decide when calling this function should be aborted. \n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/60-contexts/main.go)\n\n## Concurrency: Practice\n\n### Propagando um contexto impróprio (#61)\n\n???+ info \"TL;DR\"\n\n    Compreender as condições em que um contexto pode ser cancelado deve ser importante ao propagá-lo: por exemplo, um manipulador HTTP cancelando o contexto quando a resposta for enviada.\n\nIn many situations, it is recommended to propagate Go contexts. However, context propagation can sometimes lead to subtle bugs, preventing subfunctions from being correctly executed.\n\nLet’s consider the following example. We expose an HTTP handler that performs some tasks and returns a response. But just before returning the response, we also want to send it to a Kafka topic. We don’t want to penalize the HTTP consumer latency-wise, so we want the publish action to be handled asynchronously within a new goroutine. We assume that we have at our disposal a `publish` function that accepts a context so the action of publishing a message can be interrupted if the context is canceled, for example. Here is a possible implementation:\n\n```go\nfunc handler(w http.ResponseWriter, r *http.Request) {\n    response, err := doSomeTask(r.Context(), r)\n    if err != nil {\n        http.Error(w, err.Error(), http.StatusInternalServerError)\n    return\n    }\n    go func() {\n        err := publish(r.Context(), response)\n        // Do something with err\n    }()\n    writeResponse(response)\n}\n```\n\nWhat’s wrong with this piece of code? We have to know that the context attached to an HTTP request can cancel in different conditions:\n\n* When the client’s connection closes\n* In the case of an HTTP/2 request, when the request is canceled\n* When the response has been written back to the client\n\nIn the first two cases, we probably handle things correctly. For example, if we get a response from doSomeTask but the client has closed the connection, it’s probably OK to call publish with a context already canceled so the message isn’t published. But what about the last case?\n\nWhen the response has been written to the client, the context associated with the request will be canceled. Therefore, we are facing a race condition:\n\n* If the response is written after the Kafka publication, we both return a response and publish a message successfully\n* However, if the response is written before or during the Kafka publication, the message shouldn’t be published.\n\nIn the latter case, calling publish will return an error because we returned the HTTP response quickly.\n\n???+ note\n\n    From Go 1.21, there is a way to create a new context without cancel. [`context.WithoutCancel`](https://pkg.go.dev/context#WithoutCancel) returns a copy of parent that is not canceled when parent is canceled.\n\nIn summary, propagating a context should be done cautiously.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/61-inappropriate-context/main.go)\n\n### Iniciando uma goroutine sem saber quando interrompê-la (#62)\n\n???+ info \"TL;DR\"\n\n    Evitar vazamentos significa estar ciente de que sempre que uma goroutine for iniciada, você deve ter um plano para interrompê-la eventualmente.\n\nGoroutines are easy and cheap to start—so easy and cheap that we may not necessarily have a plan for when to stop a new goroutine, which can lead to leaks. Not knowing when to stop a goroutine is a design issue and a common concurrency mistake in Go.\n\nLet’s discuss a concrete example. We will design an application that needs to watch some external configuration (for example, using a database connection). Here’s a first implementation:\n\n```go\nfunc main() {\n    newWatcher()\n    // Run the application\n}\n\ntype watcher struct { /* Some resources */ }\n\nfunc newWatcher() {\n    w := watcher{}\n    go w.watch() // Creates a goroutine that watches some external configuration\n}\n```\n\nThe problem with this code is that when the main goroutine exits (perhaps because of an OS signal or because it has a finite workload), the application is stopped. Hence, the resources created by watcher aren’t closed gracefully. How can we prevent this from happening?\n\nOne option could be to pass to newWatcher a context that will be canceled when main returns:\n\n```go\nfunc main() {\n    ctx, cancel := context.WithCancel(context.Background())\n    defer cancel()\n    newWatcher(ctx)\n    // Run the application\n}\n\nfunc newWatcher(ctx context.Context) {\n    w := watcher{}\n    go w.watch(ctx)\n}\n```\n\nWe propagate the context created to the watch method. When the context is canceled, the watcher struct should close its resources. However, can we guarantee that watch will have time to do so? Absolutely not—and that’s a design flaw.\n\n The problem is that we used signaling to convey that a goroutine had to be stopped. We didn’t block the parent goroutine until the resources had been closed.  Let’s make sure we do:\n\n```go\nfunc main() {\n    w := newWatcher()\n    defer w.close()\n    // Run the application\n}\n\nfunc newWatcher() watcher {\n    w := watcher{}\n    go w.watch()\n    return w\n}\n\nfunc (w watcher) close() {\n    // Close the resources\n}\n```\n\nInstead of signaling `watcher` that it’s time to close its resources, we now call this `close` method, using `defer` to guarantee that the resources are closed before the application exits.\n\nIn summary, let’s be mindful that a goroutine is a resource like any other that must eventually be closed to free memory or other resources. Starting a goroutine without knowing when to stop it is a design issue. Whenever a goroutine is started, we should have a clear plan about when it will stop. Last but not least, if a goroutine creates resources and its lifetime is bound to the lifetime of the application, it’s probably safer to wait for this goroutine to complete before exiting the application. This way, we can ensure that the resources can be freed.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/62-starting-goroutine/)\n\n### :warning: Não ter cuidado com goroutines e variáveis ​​de loop (#63)\n\n???+ warning\n\n    Este erro não é mais relevante no Go 1.22 ([detalhes](https://go.dev/blog/loopvar-preview)).\n\n### Esperando um comportamento determinístico usando seleção e canais (#64)\n\n???+ info \"TL;DR\"\n\n    Compreender que com `select` vários canais escolhe o caso aleatoriamente se múltiplas opções forem possíveis evita fazer suposições erradas que podem levar a erros sutis de simultaneidade.\n\nOne common mistake made by Go developers while working with channels is to make wrong assumptions about how select behaves with multiple channels.\n\nFor example, let's consider the following case (`disconnectCh` is a unbuffered channel):\n\n```go\ngo func() {\n  for i := 0; i < 10; i++ {\n      messageCh <- i\n    }\n    disconnectCh <- struct{}{}\n}()\n\nfor {\n    select {\n    case v := <-messageCh:\n        fmt.Println(v)\n    case <-disconnectCh:\n        fmt.Println(\"disconnection, return\")\n        return\n    }\n}\n```\n\nIf we run this example multiple times, the result will be random:\n\n```\n0\n1\n2\ndisconnection, return\n\n0\ndisconnection, return\n```\n\nInstead of consuming the 10 messages, we only received a few of them. What’s the reason? It lies in the specification of the select statement with multiple channels (https:// go.dev/ref/spec):\n\n!!! quote \n\n    If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection.\n\nUnlike a switch statement, where the first case with a match wins, the select statement selects randomly if multiple options are possible.\n\nThis behavior might look odd at first, but there’s a good reason for it: to prevent possible starvation. Suppose the first possible communication chosen is based on the source order. In that case, we may fall into a situation where, for example, we only receive from one channel because of a fast sender. To prevent this, the language designers decided to use a random selection.\n\nWhen using `select` with multiple channels, we must remember that if multiple options are possible, the first case in the source order does not automatically win. Instead, Go selects randomly, so there’s no guarantee about which option will be chosen. To overcome this behavior, in the case of a single producer goroutine, we can use either unbuffered channels or a single channel.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/64-select-behavior/main.go)\n\n### Não usar canais de notificação (#65)\n\n???+ info \"TL;DR\"\n\n    Envie notificações usando um tipo `chan struct{}`.\n\nChannels are a mechanism for communicating across goroutines via signaling. A signal can be either with or without data.\n\nLet’s look at a concrete example. We will create a channel that will notify us whenever a certain disconnection occurs. One idea is to handle it as a `chan bool`:\n\n```go\ndisconnectCh := make(chan bool)\n```\n\nNow, let’s say we interact with an API that provides us with such a channel. Because it’s a channel of Booleans, we can receive either `true` or `false` messages. It’s probably clear what `true` conveys. But what does `false` mean? Does it mean we haven’t been disconnected? And in this case, how frequently will we receive such a signal? Does it mean we have reconnected? Should we even expect to receive `false`? Perhaps we should only expect to receive `true` messages.\n\nIf that’s the case, meaning we don’t need a specific value to convey some information, we need a channel _without_ data. The idiomatic way to handle it is a channel of empty structs: `chan struct{}`.\n\n### Não usar canais nulos (#66)\n\n???+ info \"TL;DR\"\n\n    O uso de canais nulos deve fazer parte do seu conjunto de ferramentas de simultaneidade porque permite remover casos de instruções `select`, por exemplo.\n\nWhat should this code do?\n\n```go\nvar ch chan int\n<-ch\n```\n\n`ch` is a `chan int` type. The zero value of a channel being nil, `ch` is `nil`. The goroutine won’t panic; however, it will block forever.\n\nThe principle is the same if we send a message to a nil channel. This goroutine blocks forever:\n\n```go\nvar ch chan int\nch <- 0\n```\n\nThen what’s the purpose of Go allowing messages to be received from or sent to a nil channel? For example, we can use nil channels to implement an idiomatic way to merge two channels:\n\n```go hl_lines=\"5 9 15\"\nfunc merge(ch1, ch2 <-chan int) <-chan int {\n    ch := make(chan int, 1)\n\n    go func() {\n        for ch1 != nil || ch2 != nil { // Continue if at least one channel isn’t nil\n            select {\n            case v, open := <-ch1:\n                if !open {\n                    ch1 = nil // Assign ch1 to a nil channel once closed\n                    break\n                }\n                ch <- v\n            case v, open := <-ch2:\n                if !open {\n                    ch2 = nil // Assigns ch2 to a nil channel once closed\n                    break\n                }\n                ch <- v\n            }\n        }\n        close(ch)\n    }()\n\n    return ch\n}\n```\n\nThis elegant solution relies on nil channels to somehow _remove_ one case from the `select` statement.\n\nLet’s keep this idea in mind: nil channels are useful in some conditions and should be part of the Go developer’s toolset when dealing with concurrent code.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/66-nil-channels/main.go)\n\n### Ficar intrigado com o tamanho do canal (#67)\n\n???+ info \"TL;DR\"\n\n    Decida cuidadosamente o tipo de canal correto a ser usado, considerando o problema. Somente canais sem buffer oferecem fortes garantias de sincronização. Para canais em buffer, você deve ter um bom motivo para especificar um tamanho de canal diferente de um.\n\nAn unbuffered channel is a channel without any capacity. It can be created by either omitting the size or providing a 0 size:\n\n```go\nch1 := make(chan int)\nch2 := make(chan int, 0)\n```\n\nWith an unbuffered channel (sometimes called a synchronous channel), the sender will block until the receiver receives data from the channel.\n\nConversely, a buffered channel has a capacity, and it must be created with a size greater than or equal to 1:\n\n```go\nch3 := make(chan int, 1)\n```\n\nWith a buffered channel, a sender can send messages while the channel isn’t full. Once the channel is full, it will block until a receiver goroutine receives a message:\n\n```go\nch3 := make(chan int, 1)\nch3 <-1 // Non-blocking\nch3 <-2 // Blocking\n```\n\nThe first send isn’t blocking, whereas the second one is, as the channel is full at this stage.\n\nWhat's the main difference between unbuffered and buffered channels:\n\n* An unbuffered channel enables synchronization. We have the guarantee that two goroutines will be in a known state: one receiving and another sending a message.\n* A buffered channel doesn’t provide any strong synchronization. Indeed, a producer goroutine can send a message and then continue its execution if the channel isn’t full. The only guarantee is that a goroutine won’t receive a message before it is sent. But this is only a guarantee because of causality (you don’t drink your coffee before you prepare it).\n\nIf we need a buffered channel, what size should we provide?\n\nThe default value we should use for buffered channels is its minimum: 1. So, we may approach the problem from this standpoint: is there any good reason not to use a value of 1? Here’s a list of possible cases where we should use another size:\n\n* While using a worker pooling-like pattern, meaning spinning a fixed number of goroutines that need to send data to a shared channel. In that case, we can tie the channel size to the number of goroutines created.\n* When using channels for rate-limiting problems. For example, if we need to enforce resource utilization by bounding the number of requests, we should set up the channel size according to the limit.\n\nIf we are outside of these cases, using a different channel size should be done cautiously. Let’s bear in mind that deciding about an accurate queue size isn’t an easy problem:\n\n!!! quote \"Martin Thompson\"\n\n    Queues are typically always close to full or close to empty due to the differences in pace between consumers and producers. They very rarely operate in a balanced middle ground where the rate of production and consumption is evenly matched.\n\n### Esquecendo os possíveis efeitos colaterais da formatação de strings (#68)\n\n???+ info \"TL;DR\"\n\n    Estar ciente de que a formatação de strings pode levar à chamada de funções existentes significa estar atento a possíveis impasses e outras disputas de dados.\n\nIt’s pretty easy to forget the potential side effects of string formatting while working in a concurrent application.\n\n#### [etcd](https://github.com/etcd-io/etcd) data race\n\n[github.com/etcd-io/etcd/pull/7816](https://github.com/etcd-io/etcd/pull/7816) shows an example of an issue where a map's key was formatted based on a mutable values from a context.\n\n#### Deadlock\n\nCan you see what the problem is in this code with a `Customer` struct exposing an `UpdateAge` method and implementing the `fmt.Stringer` interface?\n\n```go\ntype Customer struct {\n    mutex sync.RWMutex // Uses a sync.RWMutex to protect concurrent accesses\n    id    string\n    age   int\n}\n\nfunc (c *Customer) UpdateAge(age int) error {\n    c.mutex.Lock() // Locks and defers unlock as we update Customer\n    defer c.mutex.Unlock()\n\n    if age < 0 { // Returns an error if age is negative\n        return fmt.Errorf(\"age should be positive for customer %v\", c)\n    }\n\n    c.age = age\n    return nil\n}\n\nfunc (c *Customer) String() string {\n    c.mutex.RLock() // Locks and defers unlock as we read Customer\n    defer c.mutex.RUnlock()\n    return fmt.Sprintf(\"id %s, age %d\", c.id, c.age)\n}\n```\n\nThe problem here may not be straightforward. If the provided age is negative, we return an error. Because the error is formatted, using the `%s` directive on the receiver, it will call the `String` method to format `Customer`. But because `UpdateAge` already acquires the mutex lock, the `String` method won’t be able to acquire it. Hence, this leads to a deadlock situation. If all goroutines are also asleep, it leads to a panic.\n\nOne possible solution is to restrict the scope of the mutex lock:\n\n```go hl_lines=\"2 3 4\"\nfunc (c *Customer) UpdateAge(age int) error {\n    if age < 0 {\n        return fmt.Errorf(\"age should be positive for customer %v\", c)\n    }\n\n    c.mutex.Lock() <1>\n    defer c.mutex.Unlock()\n\n    c.age = age\n    return nil\n}\n```\n\nYet, such an approach isn't always possible. In these conditions, we have to be extremely careful with string formatting.\n\nAnother approach is to access the `id` field directly:\n\n```go hl_lines=\"6\"\nfunc (c *Customer) UpdateAge(age int) error {\n    c.mutex.Lock()\n    defer c.mutex.Unlock()\n\n    if age < 0 {\n        return fmt.Errorf(\"age should be positive for customer id %s\", c.id)\n    }\n\n    c.age = age\n    return nil\n}\n```\n\nIn concurrent applications, we should remain cautious about the possible side effects of string formatting.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/68-string-formatting/main.go)\n\n### Criando corridas de dados com acréscimo (#69)\n\n???+ info \"TL;DR\"\n\n    As chamadas `append` nem sempre são isentas de disputa de dados; portanto, não deve ser usado simultaneamente em uma slice compartilhada.\n\nShould adding an element to a slice using `append` is data-race-free? Spoiler: it depends.\n\nDo you believe this example has a data race? \n\n```go\ns := make([]int, 1)\n\ngo func() { // In a new goroutine, appends a new element on s\n    s1 := append(s, 1)\n    fmt.Println(s1)\n}()\n\ngo func() { // Same\n    s2 := append(s, 1)\n    fmt.Println(s2)\n}()\n```\n\nThe answer is no.\n\nIn this example, we create a slice with `make([]int, 1)`. The code creates a one-length, one-capacity slice. Thus, because the slice is full, using append in each goroutine returns a slice backed by a new array. It doesn’t mutate the existing array; hence, it doesn’t lead to a data race.\n\nNow, let’s run the same example with a slight change in how we initialize `s`. Instead of creating a slice with a length of 1, we create it with a length of 0 but a capacity of 1. How about this new example? Does it contain a data race?\n\n```go hl_lines=\"1\"\ns := make([]int, 0, 1)\n\ngo func() { \n    s1 := append(s, 1)\n    fmt.Println(s1)\n}()\n\ngo func() {\n    s2 := append(s, 1)\n    fmt.Println(s2)\n}()\n```\n\nThe answer is yes. We create a slice with `make([]int, 0, 1)`. Therefore, the array isn’t full. Both goroutines attempt to update the same index of the backing array (index 1), which is a data race.\n\nHow can we prevent the data race if we want both goroutines to work on a slice containing the initial elements of `s` plus an extra element? One solution is to create a copy of `s`.\n\nWe should remember that using append on a shared slice in concurrent applications can lead to a data race. Hence, it should be avoided.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/69-data-race-append/main.go)\n\n### Usando mutexes imprecisamente com slices e maps (#70)\n\n???+ info \"TL;DR\"\n\n    Lembrar que slices e maps são ponteiros pode evitar corridas comuns de dados.\n\nLet's implement a `Cache` struct used to handle caching for customer balances. This struct will contain a map of balances per customer ID and a mutex to protect concurrent accesses:\n\n```go\ntype Cache struct {\n    mu       sync.RWMutex\n    balances map[string]float64\n}\n```\n\nNext, we add an `AddBalance` method that mutates the `balances` map. The mutation is done in a critical section (within a mutex lock and a mutex unlock):\n\n```go\nfunc (c *Cache) AddBalance(id string, balance float64) {\n    c.mu.Lock()\n    c.balances[id] = balance\n    c.mu.Unlock()\n}\n```\n\nMeanwhile, we have to implement a method to calculate the average balance for all the customers. One idea is to handle a minimal critical section this way:\n\n```go\nfunc (c *Cache) AverageBalance() float64 {\n    c.mu.RLock()\n    balances := c.balances // Creates a copy of the balances map\n    c.mu.RUnlock()\n\n    sum := 0.\n    for _, balance := range balances { // Iterates over the copy, outside of the critical section\n        sum += balance\n    }\n    return sum / float64(len(balances))\n}\n```\n\nWhat's the problem with this code?\n\nIf we run a test using the `-race` flag with two concurrent goroutines, one calling `AddBalance` (hence mutating balances) and another calling `AverageBalance`, a data race occurs. What’s the problem here?\n\nInternally, a map is a `runtime.hmap` struct containing mostly metadata (for example, a counter) and a pointer referencing data buckets. So, `balances := c.balances` doesn’t copy the actual data. Therefore, the two goroutines perform operations on the same data set, and one mutates it. Hence, it's a data race.\n\nOne possible solution is to protect the whole `AverageBalance` function:\n\n```go hl_lines=\"2 3\"\nfunc (c *Cache) AverageBalance() float64 {\n    c.mu.RLock()\n    defer c.mu.RUnlock() // Unlocks when the function returns\n\n    sum := 0.\n    for _, balance := range c.balances {\n        sum += balance\n    }\n    return sum / float64(len(c.balances))\n}\n```\n\nAnother option, if the iteration operation isn’t lightweight, is to work on an actual copy of the data and protect only the copy:\n\n```go hl_lines=\"2 3 4 5 6 7\"\nfunc (c *Cache) AverageBalance() float64 {\n    c.mu.RLock()\n    m := make(map[string]float64, len(c.balances)) // Copies the map\n    for k, v := range c.balances {\n        m[k] = v\n    }\n    c.mu.RUnlock()\n\n    sum := 0.\n    for _, balance := range m {\n        sum += balance\n    }\n    return sum / float64(len(m))\n}\n```\n\nOnce we have made a deep copy, we release the mutex. The iterations are done on the copy outside of the critical section.\n\nIn summary, we have to be careful with the boundaries of a mutex lock. In this section, we have seen why assigning an existing map (or an existing slice) to a map isn’t enough to protect against data races. The new variable, whether a map or a slice, is backed by the same data set. There are two leading solutions to prevent this: protect the whole function, or work on a copy of the actual data. In all cases, let’s be cautious when designing critical sections and make sure the boundaries are accurately defined.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/70-mutex-slices-maps/main.go)\n\n### Uso indevido `sync.WaitGroup` (#71)\n\n???+ info \"TL;DR\"\n\n    Para usar com precisão `sync.WaitGroup`, chame o método `Add` antes de ativar goroutines.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/71-wait-group/main.go)\n\n### Esquecendo `sync.Cond` (#72)\n\n???+ info \"TL;DR\"\n\n    Você pode enviar notificações repetidas para vários goroutines com `sync.Cond`.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/72-cond/main.go)\n\n### Não usando `errgroup` (#73)\n\n???+ info \"TL;DR\"\n\n    Você pode sincronizar um grupo de goroutines e lidar com erros e contextos com o pacote `errgroup`.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/73-errgroup/main.go)\n\n### Copiando um tipo `sync` (#74)\n\n???+ info \"TL;DR\"\n\n    Tipos `sync` não devem ser copiados.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/74-copying-sync/main.go)\n\n## Standard Library\n\n### Fornecendo uma duração de tempo errada (#75)\n\n???+ info \"TL;DR\"\n\n    Seja cauteloso com funções que aceitam um arquivo `time.Duration`. Mesmo que a passagem de um número inteiro seja permitida, tente usar a API time para evitar qualquer possível confusão.\n\nMany common functions in the standard library accept a `time.Duration`, which is an alias for the `int64` type. However, one `time.Duration` unit represents one nanosecond, instead of one millisecond, as commonly seen in other programming languages. As a result, passing numeric types instead of using the `time.Duration` API can lead to unexpected behavior.\n\nA developer with experience in other languages might assume that the following code creates a new `time.Ticker` that delivers ticks every second, given the value `1000`:\n\n```go\nticker := time.NewTicker(1000)\nfor {\n\tselect {\n\tcase <-ticker.C:\n\t\t// Do something\n\t}\n}\n```\n\nHowever, because 1,000 `time.Duration` units = 1,000 nanoseconds, ticks are delivered every 1,000 nanoseconds = 1 microsecond, not every second as assumed.\n\nWe should always use the `time.Duration` API to avoid confusion and unexpected behavior:\n```go\nticker = time.NewTicker(time.Microsecond)\n// Or\nticker = time.NewTicker(1000 * time.Nanosecond)\n```\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/75-wrong-time-duration/main.go)\n\n### `time.After` e vazamentos de memória (#76)\n\n???+ info \"TL;DR\"\n\n    Evitar chamadas para funções `time.After` repetidas (como loops ou manipuladores HTTP) pode evitar pico de consumo de memória. Os recursos criados por `time.After` são liberados somente quando o cronômetro expira.\n\nDevelopers often use `time.After` in loops or HTTP handlers repeatedly to implement the timing function. But it can lead to unintended peak memory consumption due to the delayed release of resources, just like the following code:\n\n```go\nfunc consumer(ch <-chan Event) {\n\tfor {\n\t\tselect {\n\t\tcase event := <-ch:\n\t\t\thandle(event)\n\t\tcase <-time.After(time.Hour):\n\t\t\tlog.Println(\"warning: no messages received\")\n\t\t}\n\t}\n}\n```\n\nThe source code of the function time.After is as follows:\n\n```go\nfunc After(d Duration) <-chan Time {\n\treturn NewTimer(d).C\n}\n```\n\nAs we see, it returns receive-only channel.\n\nWhen `time.After` is used in a loop or repeated context, a new channel is created in each iteration. If these channels are not properly closed or if their associated timers are not stopped, they can accumulate and consume memory. The resources associated with each timer and channel are only released when the timer expires or the channel is closed.\n\nTo avoid this happening, We can use context's timeout setting instead of `time.After`, like below:\n\n```go\nfunc consumer(ch <-chan Event) {\n\tfor {\n\t\tctx, cancel := context.WithTimeout(context.Background(), time.Hour)\n\t\tselect {\n\t\tcase event := <-ch:\n\t\t\tcancel()\n\t\t\thandle(event)\n\t\tcase <-ctx.Done():\n\t\t\tlog.Println(\"warning: no messages received\")\n\t\t}\n\t}\n}\n```\n\nWe can also use `time.NewTimer` like so:\n\n```go\nfunc consumer(ch <-chan Event) {\n\ttimerDuration := 1 * time.Hour\n\ttimer := time.NewTimer(timerDuration)\n\n\tfor {\n\t\ttimer.Reset(timerDuration)\n\t\tselect {\n\t\tcase event := <-ch:\n\t\t\thandle(event)\n\t\tcase <-timer.C:\n\t\t\tlog.Println(\"warning: no messages received\")\n\t\t}\n\t}\n}\n```\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/76-time-after/main.go)\n\n### Lidando com erros comuns JSON (#77)\n\n* Comportamento inesperado devido à incorporação de tipo\n\n  Tenha cuidado ao usar campos incorporados em estruturas Go. Fazer isso pode levar a bugs sorrateiros, como um campo time.Time incorporado que implementa a interface `json.Marshaler`, substituindo assim o comportamento de empacotamento padrão.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/type-embedding/main.go)\n\n* JSON e o relógio monotônico\n\n  Ao comparar duas estruturas `time.Time`, lembre-se de que `time.Time` contém um relógio de parede e um relógio monotônico, e a comparação usando o operador == é feita em ambos os relógios.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/monotonic-clock/main.go)\n\n* Map de `any`\n\n  Para evitar suposições erradas ao fornecer um map ao desempacotar (unmarshaling) dados JSON, lembre-se de que os valores numéricos são convertidos para `float64` por padrão.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/map-any/main.go)\n\n### Erros comuns de SQL (#78)\n\n* Esquecer `sql.Open` não necessariamente estabelece conexões com um banco de dados\n\n  Esquecer `sql.Open` não necessariamente estabelece conexões com um banco de dados\n  Chame o método `Ping` ou `PingContext` se precisar testar sua configuração e garantir que um banco de dados esteja acessível.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/sql-open)\n\n* Esquecendo o pool de conexões\n\n  Configure os parâmetros de conexão do banco de dados para aplicativos de nível de produção.\n\n* Não usar declarações preparadas\n\n  O uso de instruções preparadas em SQL torna as consultas mais eficientes e seguras.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/prepared-statements)\n\n* Tratamento incorreto de valores nulos\n\n  Lide com colunas anuláveis ​​em tabelas usando ponteiros ou tipos `sql.NullXXX`.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/null-values/main.go)\n\n* Não tratando de erros de iteração de linhas\n\n  Chame o método `Err` de `sql.Rows` iterações posteriores à linha para garantir que você não perdeu nenhum erro ao preparar a próxima linha.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/rows-iterations-errors)\n\n### Não fechando recursos transitórios (body HTTP, `sql.Rows` e `os.File`) (#79)\n\n???+ info \"TL;DR\"\n\n    Eventualmente feche todas as estruturas implementadas `io.Closer` para evitar possíveis vazamentos.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/79-closing-resources/)\n\n### Esquecendo a instrução return após responder a uma solicitação HTTP (#80)\n\n???+ info \"TL;DR\"\n\n    Para evitar comportamentos inesperados nas implementações do manipulador HTTP, certifique-se de não perder a instrução `return` se quiser que um manipulador pare após `http.Error`.\n\n\nConsider the following HTTP handler that handles an error from `foo` using `http.Error`:\n\n```go\nfunc handler(w http.ResponseWriter, req *http.Request) {\n\terr := foo(req)\n\tif err != nil {\n\t\thttp.Error(w, \"foo\", http.StatusInternalServerError)\n\t}\n\n\t_, _ = w.Write([]byte(\"all good\"))\n\tw.WriteHeader(http.StatusCreated)\n}\n```\n\nIf we run this code and `err != nil`, the HTTP response would be:\n\n```\nfoo\nall good\n```\n\nThe response contains both the error and success messages, and also the first HTTP status code, 500. There would also be a warning log indicating that we attempted to write the status code multiple times:\n\n```\n2023/10/10 16:45:33 http: superfluous response.WriteHeader call from main.handler (main.go:20)\n```\n\nThe mistake in this code is that `http.Error` does not stop the handler's execution, which means the success message and status code get written in addition to the error. Beyond an incorrect response, failing to return after writing an error can lead to the unwanted execution of code and unexpected side-effects. The following code adds the `return` statement following the `http.Error` and exhibits the desired behavior when ran:\n\n```go\nfunc handler(w http.ResponseWriter, req *http.Request) {\n\terr := foo(req)\n\tif err != nil {\n\t\thttp.Error(w, \"foo\", http.StatusInternalServerError)\n\t\treturn // Adds the return statement\n\t}\n\n\t_, _ = w.Write([]byte(\"all good\"))\n\tw.WriteHeader(http.StatusCreated)\n}\n```\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/80-http-return/main.go)\n\n### Usando o cliente e servidor HTTP padrão (#81)\n\n???+ info \"TL;DR\"\n\n    Para aplicativos de nível de produção, não use as implementações de cliente e servidor HTTP padrão. Essas implementações não possuem tempos limite e comportamentos que deveriam ser obrigatórios na produção.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/81-default-http-client-server/)\n\n## Teste\n\n### Não categorizar testes (tags de construção, variáveis ​​de ambiente e modo abreviado) (#82)\n\n???+ info \"TL;DR\"\n\n    Categorizar testes usando sinalizadores de construção, variáveis ​​de ambiente ou modo curto torna o processo de teste mais eficiente. Você pode criar categorias de teste usando sinalizadores de construção ou variáveis ​​de ambiente (por exemplo, testes de unidade versus testes de integração) e diferenciar testes curtos de testes de longa duração para decidir quais tipos de testes executar.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/82-categorizing-tests/)\n\n### Não habilitando a bandeira de corrida (#83)\n\n???+ info \"TL;DR\"\n\n    A ativação do sinalizador `-race` é altamente recomendada ao escrever aplicativos simultâneos. Isso permite que você detecte possíveis corridas de dados que podem levar a bugs de software.\n\nIn Go, the race detector isn’t a static analysis tool used during compilation; instead, it’s a tool to find data races that occur at runtime. To enable it, we have to enable the -race flag while compiling or running a test. For example:\n\n```bash\ngo test -race ./...\n```\n\nOnce the race detector is enabled, the compiler instruments the code to detect data races. Instrumentation refers to a compiler adding extra instructions: here, tracking all memory accesses and recording when and how they occur.\n\nEnabling the race detector adds an overhead in terms of memory and execution time; hence, it's generally recommended to enable it only during local testing or continuous integration, not production.\n\nIf a race is detected, Go raises a warning. For example:\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n)\n\nfunc main() {\n    i := 0\n    go func() { i++ }()\n    fmt.Println(i)\n}\n```\n\nRunnig this code with the `-race` logs the following warning:\n\n```bash hl_lines=\"3 7 11\"\n==================\nWARNING: DATA RACE\nWrite at 0x00c000026078 by goroutine 7: # (1)\n  main.main.func1()\n      /tmp/app/main.go:9 +0x4e\n\nPrevious read at 0x00c000026078 by main goroutine: # (2)\n  main.main()\n      /tmp/app/main.go:10 +0x88\n\nGoroutine 7 (running) created at: # (3)\n  main.main()\n      /tmp/app/main.go:9 +0x7a\n==================\n```\n\n1.  Indicates that goroutine 7 was writing\n2.  Indicates that the main goroutine was reading\n3.  Indicates when the goroutine 7 was created\n\nLet’s make sure we are comfortable reading these messages. Go always logs the following:\n\n* The concurrent goroutines that are incriminated: here, the main goroutine and goroutine 7.\n* Where accesses occur in the code: in this case, lines 9 and 10.\n* When these goroutines were created: goroutine 7 was created in main().\n\nIn addition, if a specific file contains tests that lead to data races, we can exclude it :material-information-outline:{ title=\"temporarily! 😉\" } from race detection using the `!race` build tag:\n\n```go\n//go:build !race\n\npackage main\n\nimport (\n    \"testing\"\n)\n\nfunc TestFoo(t *testing.T) {\n    // ...\n}\n```\n\n### Não usar modos de execução de teste (paralelo e aleatório) (#84)\n\n???+ info \"TL;DR\"\n\n    Usar o sinalizador `-parallel` é uma forma eficiente de acelerar testes, especialmente os de longa duração. Use o sinalizador `-shuffle` para ajudar a garantir que um conjunto de testes não se baseie em suposições erradas que possam ocultar bugs.\n\n### Não usar testes baseados em tabela (#85)\n\n???+ info \"TL;DR\"\n\n    Os testes baseados em tabelas são uma maneira eficiente de agrupar um conjunto de testes semelhantes para evitar a duplicação de código e facilitar o manuseio de atualizações futuras.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/85-table-driven-tests/main_test.go)\n\n### Dormindo em testes unitários (#86)\n\n???+ info \"TL;DR\"\n\n    Evite interrupções usando a sincronização para tornar o teste menos instável e mais robusto. Se a sincronização não for possível, considere uma abordagem de nova tentativa.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/86-sleeping/main_test.go)\n\n### Não lidar com a API de tempo de forma eficiente (#87)\n\n???+ info \"TL;DR\"\n\n    Entender como lidar com funções usando a API time é outra maneira de tornar um teste menos complicado. Você pode usar técnicas padrão, como lidar com o tempo como parte de uma dependência oculta ou solicitar que os clientes o forneçam.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/87-time-api/)\n\n### Não usar pacotes de utilitários de teste ( `httptest` e `iotest`) (#88)\n\n* O pacote `httptest` é útil para lidar com aplicativos HTTP. Ele fornece um conjunto de utilitários para testar clientes e servidores.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/88-utility-package/httptest/main_test.go)\n\n* O pacote `iotest` ajuda a escrever io.Reader e testar se um aplicativo é tolerante a erros.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/88-utility-package/iotest/main_test.go)\n\n### Escrevendo benchmarks imprecisos (#89)\n\n???+ info \"TL;DR\"\n\n    Regarding benchmarks:\n\n    * Use métodos de tempo para preservar a precisão de um benchmark.\n    * Aumentar o tempo de teste ou usar ferramentas como o benchstat pode ser útil ao lidar com micro-benchmarks.\n    * Tenha cuidado com os resultados de um micro-benchmark se o sistema que executa o aplicativo for diferente daquele que executa o micro-benchmark.\n    * Certifique-se de que a função em teste cause um efeito colateral, para evitar que as otimizações do compilador enganem você sobre os resultados do benchmark.\n    * Para evitar o efeito observador, force um benchmark a recriar os dados usados ​​por uma função vinculada à CPU.\n\nLeia a seção completa [aqui](89-benchmarks.md).\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/89-benchmark/)\n\n### Não explorando todos os recursos de teste do Go (#90)\n\n* Cobertura de código\n\n  Use a cobertura de código com o sinalizador `-coverprofile` para ver rapidamente qual parte do código precisa de mais atenção.\n\n* Testando de um pacote diferente\n\n  Coloque os testes unitários em um pacote diferente para impor testes de escrita que se concentrem em um comportamento exposto, não em internos.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/different-package/main_test.go)\n\n* Funções utilitárias\n\n  O tratamento de erros usando a variável `*testing.T` em vez do clássico `if err != nil` torna o código mais curto e fácil de ler.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/utility-function/main_test.go)\n\n* Configuração e desmontagem\n\n  Você pode usar funções de setup e teardown para configurar um ambiente complexo, como no caso de testes de integração.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/setup-teardown/main_test.go)\n\n### Não usar fuzzing (erro da comunidade)\n\n???+ info \"TL;DR\"\n\n    Fuzzing é uma estratégia eficiente para detectar entradas aleatórias, inesperadas ou malformadas em funções e métodos complexos, a fim de descobrir vulnerabilidades, bugs ou até mesmo travamentos potenciais.\n\nCredits: [@jeromedoucet](https://github.com/jeromedoucet)\n\n## Otimizações\n\n### Não entendendo os caches da CPU (#91)\n\n* Arquitetura da CPU\n\n  Compreender como usar caches de CPU é importante para otimizar aplicativos vinculados à CPU porque o cache L1 é cerca de 50 a 100 vezes mais rápido que a memória principal.\n\n* Linha de cache\n\n  Estar consciente do conceito de linha de cache é fundamental para entender como organizar dados em aplicativos com uso intensivo de dados. Uma CPU não busca memória palavra por palavra; em vez disso, geralmente copia um bloco de memória para uma linha de cache de 64 bytes. Para aproveitar ao máximo cada linha de cache individual, imponha a localidade espacial.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/cache-line/)\n\n* Slice de estruturas vs. estrutura de slices\n\n<!-- TODO -->\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/slice-structs/)\n\n* Previsibilidade\n\n  Tornar o código previsível para a CPU também pode ser uma forma eficiente de otimizar certas funções. Por exemplo, uma passada unitária ou constante é previsível para a CPU, mas uma passada não unitária (por exemplo, uma lista vinculada) não é previsível.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/predictability/)\n\n* Política de posicionamento de cache\n\n  Para evitar um avanço crítico e, portanto, utilizar apenas uma pequena parte do cache, esteja ciente de que os caches são particionados.\n\n### Escrevendo código simultâneo que leva a compartilhamento falso (#92)\n\n???+ info \"TL;DR\"\n\n    Saber que níveis mais baixos de caches de CPU não são compartilhados entre todos os núcleos ajuda a evitar padrões que degradam o desempenho, como compartilhamento falso ao escrever código de simultaneidade. Compartilhar memória é uma ilusão.\n\nLeia a seção completa [aqui](92-false-sharing.md).\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/92-false-sharing/)\n\n### Não levando em consideração o paralelismo no nível de instrução (#93)\n\n???+ info \"TL;DR\"\n\n    Use o ILP para otimizar partes específicas do seu código para permitir que uma CPU execute tantas instruções paralelas quanto possível. Identificar perigos nos dados é uma das etapas principais.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/93-instruction-level-parallelism/)\n\n### Não estar ciente do alinhamento dos dados (#94)\n\n???+ info \"TL;DR\"\n\n    Você pode evitar erros comuns lembrando que no Go os tipos básicos são alinhados com seu próprio tamanho. Por exemplo, tenha em mente que reorganizar os campos de uma estrutura por tamanho em ordem decrescente pode levar a estruturas mais compactas (menos alocação de memória e potencialmente uma melhor localidade espacial).\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/94-data-alignment/)\n\n### Não entendendo stack vs. heap (#95)\n\n???+ info \"TL;DR\"\n\n    Compreender as diferenças fundamentais entre heap e pilha também deve fazer parte do seu conhecimento básico ao otimizar um aplicativo Go. As alocações de pilha são quase gratuitas, enquanto as alocações de heap são mais lentas e dependem do GC para limpar a memória.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/95-stack-heap/)\n\n### Não saber como reduzir alocações (mudança de API, otimizações de compilador e `sync.Pool`) (#96)\n\n???+ info \"TL;DR\"\n\n    A redução das alocações também é um aspecto essencial da otimização de um aplicativo Go. Isso pode ser feito de diferentes maneiras, como projetar a API cuidadosamente para evitar compartilhamento, compreender as otimizações comuns do compilador Go e usar `sync.Pool`.\n\n [:simple-github: Código fonte](https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/96-reduce-allocations/)\n\n### Não dependendo do inlining (#97)\n\n???+ info \"TL;DR\"\n\n    Use a técnica de inlining de caminho rápido para reduzir com eficiência o tempo amortizado para chamar uma função.\n\n### Não usar ferramentas de diagnóstico Go (#98)\n\n???+ info \"TL;DR\"\n\n    Confie na criação de perfil e no rastreador de execução para entender o desempenho de um aplicativo e as partes a serem otimizadas.\n\nLeia a seção completa [aqui](98-profiling-execution-tracing.md).\n\n### Não entendendo como funciona o GC (#99)\n\n???+ info \"TL;DR\"\n\n    Compreender como ajustar o GC pode levar a vários benefícios, como lidar com aumentos repentinos de carga com mais eficiência.\n\n### Não entendendo os impactos da execução do Go no Docker e Kubernetes (#100)\n\n???+ info \"TL;DR\"\n\n    Para ajudar a evitar a limitação da CPU quando implantado no Docker e no Kubernetes, lembre-se de que Go não reconhece CFS.\n\nBy default, GOMAXPROCS is set to the number of OS-apparent logical CPU cores.\n\nWhen running some Go code inside Docker and Kubernetes, we must know that Go isn't CFS-aware ([github.com/golang/go/issues/33803](https://github.com/golang/go/issues/33803)). Therefore, GOMAXPROCS isn't automatically set to the value of `spec.containers.resources.limits.cpu` (see [Kubernetes Resource Management for Pods and Containers](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/)); instead, it's set to the number of logical cores on the host machine. The main implication is that it can lead to an increased tail latency in some specific situations.\n\nOne solution is to rely on [uber-go/automaxprocs](https://github.com/uber-go/automaxprocs) that automatically set `GOMAXPROCS` to match the Linux container CPU quota.\n\n## Community\n\nThanks to all the contributors:\n\n<a href=\"https://contrib.rocks/image?repo=teivah/100-go-mistakes\">\n    <img src=\"https://contrib.rocks/image?repo=teivah/100-go-mistakes\" alt=\"Description of the image\">\n</a>\n"
  },
  {
    "path": "docs/stylesheets/extra.css",
    "content": ".md-typeset figure img {\n  display: inline;\n}\n\n.md-typeset .admonition,\n.md-typeset details {\n  font-size: 15px\n}\n"
  },
  {
    "path": "docs/zh.md",
    "content": "---\ntitle: Chinese (Simplified) Version\ncomments: true\n---\n\n# 100 个 Go 常见错误及如何避免\n\n???+ tip \"The Coder Cafe\"\n\n    如果您喜欢我的书，您可能会对我的最新项目感兴趣：[The Coder Cafe](https://thecoder.cafe?rd=100go.co/zh)，这是一个为程序员提供的每日简报。\n\n    > Feeling overwhelmed by the endless stream of tech content? At The Coder Cafe, we serve one essential concept for coders. Written by a senior software engineer at Google, it's perfectly brewed for your morning coffee, helping you grow your skills deeply.\n\n    <center><a href=\"https://thecoder.cafe?rd=100go.co/zh\"><img src=\"../img/thecodercafe.png\" alt=\"\" style=\"width:480px;height:240px;\"></a></center>\n\n![](img/inside-cover.png)\n\n## 代码及工程组织\n\n### 意外的变量隐藏 (#1)\n\n避免变量隐藏（外部作用域变量被内部作用域同名变量隐藏），有助于避免变量引用错误，有助于他人阅读理解。\n\n### 不必要的代码嵌套 (#2)\n\n避免不必要的、过多的嵌套层次，并且让正常代码路径尽量左对齐（而不是放在分支路径中），有助于构建可读性更好的代码。\n\n### 误用 init 函数 (#3)\n\n初始化变量时，请记住 init 函数具有有限的错误处理能力，并且会使状态处理和测试变得更加复杂。在大多数情况下，初始化应该作为特定函数来处理。\n\n### 滥用 getters/setters (#4)\n\n在 Go 语言中，强制使用 getter 和 setter 方法并不符合 Go 惯例。在实践中，应该找到效率和盲目遵循某些惯用法之间的平衡点。\n\n### 接口污染 (#5)\n\n抽象应该被发现，而不是被创造。为了避免不必要的复杂性，需要时才创建接口，而不是预见到需要它，或者至少可以证明这种抽象是有价值的。\n\n### 将接口定义在实现方一侧 (#6)\n\n将接口保留在引用方一侧（而不是实现方一侧）可以避免不必要的抽象。\n\n### 将接口作为返回值 (#7)\n\n为了避免在灵活性方面受到限制，大多数情况下函数不应该返回接口，而应该返回具体的实现。相反，函数应该尽可能地使用接口作为参数。\n\n### `any` 没传递任何信息 (#8)\n\n只有在需要接受或返回任意类型时，才使用 `any`，例如 `json.Marshal`。其他情况下，因为 `any` 不提供有意义的信息，可能会导致编译时问题，如允许调用者调用方法处理任意类型数据。\n\n### [困惑何时该用范型](https://100go.co/9-generics/) (#9)\n\n使用泛型，可以通过类型参数分离具体的数据类型和行为，避免写很多重复度很高的代码。然而，不要过早地使用泛型、类型参数，只有在你看到真正需要时才使用。否则，它们会引入不必要的抽象和复杂性。\n\n### 未意识到类型嵌套的可能问题 (#10)\n\n使用类型嵌套也可以避免写一些重复代码，然而，在使用时需要确保不会导致不合理的可见性问题，比如有些字段应该对外隐藏不应该被暴露。\n\n### 不使用 function option 模式 (#11)\n\n为了设计并提供更友好的 API（可选参数），为了更好地处理选项，应该使用 function option 模式。\n\n### 工程组织不合理 (工程结构和包的组织) (#12)\n\n遵循像 project-layout 的建议来组织 Go 工程是一个不错的方法，尤其是你正在寻找一些类似的经验、惯例来组织一个新的 Go 工程的时候。\n\n### 创建工具包 (#13)\n\n命名是软件设计开发中非常重要的一个部分，创建一些名如 `common`、`util`、`shared` 之类的包名并不会给读者带来太大价值，应该将这些包名重构为更清晰、更具体的包名。\n\n### 忽略了包名冲突 (#14)\n\n为了避免变量名和包名之间的冲突，导致混淆或甚至错误，应为每个变量和包使用唯一的名称。如果这不可行，可以考虑使用导入别名 `import importAlias 'importPath'` 以区分包名和变量名，或者考虑一个更好的变量名。\n\n### 代码缺少文档 (#15)\n\n为了让使用方、维护人员能更清晰地了解你的代码的意图，导出的元素（函数、类型、字段）需要添加注释。\n\n### 不使用 linters 检查 (#16)\n\n为了改善代码质量、整体代码的一致性，应该使用 linters 和 formatters。\n\n## 数据类型\n\n### 八进制字面量引发的困惑 (#17)\n\n在阅读现有代码时，请记住以 0 开头的整数字面量是八进制数。此外，为了提高可读性，可以通过在前面加上 0o 来显式地表示八进制整数。\n\n### 未注意可能的整数溢出 (#18)\n\n在 Go 中整数上溢出和下溢是静默处理的，所以你可以实现自己的函数来捕获它们。\n\n### 没有透彻理解浮点数 (#19)\n\n比较浮点数时，通过比较二者的 delta 值是否介于一定的范围内，能让你写出可移植性更好的代码。\n\n在进行加法或减法时，将具有相似数量级的操作分成同一组以提高精度 (过早指数对齐丢失精度)。此外，在进行加法和减法之前，应先进行乘法和除法 (加减法误差会被乘除放大)。\n\n### [不理解 slice 的长度和容量](https://100go.co/20-slice/) (#20)\n\n理解 slice 的长度和容量的区别，是一个 Go 开发者的核心知识点之一。slice 的长度指的是 slice 已经存储的元素的数量，而容量指的是 slice 当前底层开辟的数组最多能容纳的元素的数量。\n\n### 不高效的 slice 初始化 (#21)\n\n当创建一个 slice 时，如果其长度可以预先确定，那么可以在定义时指定它的长度和容量。这可以改善后期 append 时一次或者多次的内存分配操作，从而改善性能。对于 map 的初始化也是如此。\n\n### 困惑于 nil 和空 slice (#22)\n\n为了避免常见的对 nil 和 empty slice 处理行为的混淆，例如在使用 encoding/json 或 reflect 包时，你需要理解 nil 和 empty slice 的区别。两者都是长度为零、容量为零的切片，但是 nil 切片不需要分配内存。\n\n### 没有适当检查 slice 是否为空 (#23)\n\n检查一个 slice 是否包含任何元素，可以检查其长度，不管 slice 是 nil 还是 empty，检查长度都是有效的。这个检查方法也适用于 map。\n\n为了设计更明确的 API，API 不应区分 nil 和空切片。\n\n### 没有正确拷贝 slice (#24)\n\n使用 `copy` 拷贝一个 slice 元素到另一个 slice 时，需要记得，实际拷贝的元素数量是二者 slice 长度中的较小值。\n\n### slice append 带来的预期之外的副作用 (#25)\n\n如果两个不同的函数操作的 slice 复用了相同的底层数组，它们对 slice 执行 append 操作时可能会产生冲突。使用 copy 来完整复制一个 slice 或者使用完整的 slice 表达式 `[low:high:max]` 限制最大容量，有助于避免产生冲突。当想对一个大 slice 进行 shrink 操作时，两种方式中，只有 copy 才可以避免内存泄漏。\n\n### slice 和内存泄漏 (#26)\n\n对于 slice 元素为指针，或者 slice 元素为 struct 但是该 struct 含有指针字段，当通过 `slice[low:high]` 操作取 subslice 时，对于那些不可访问的元素可以显式设置为 nil 来避免内存泄露。\n\n### 不高效的 map 初始化 (#27)\n\n见 [#21](#inefficient-slice-initialization-21).\n\n### [map 和内存泄漏](https://100go.co/28-maps-memory-leaks/) (#28)\n\n一个 map 的 buckets 占用的内存只会增长，不会缩减。因此，如果它导致了一些内存占用的问题，你需要尝试不同的方式来解决，比如重新创建一个 map 代替原来的（原来的 map 会被 GC 掉），或者 `map[keyType]valueType` 中的 valueType 使用指针代替长度固定的数组或者 sliceHeader 来缓解过多的内存占用。\n\n### 不正确的值比较 (#29)\n\nGo 中比较两个类型值时，如果是可比较类型，那么可以使用 `==` 或者 `!=` 运算符进行比较，比如：booleans、numerals、strings、pointers、channels，以及字段全部是可比较类型的 structs。其他情况下，你可以使用 `reflect.DeepEqual` 来比较，用反射的话会牺牲一点性能，也可以使用自定义的实现和其他库来完成。\n\n## 控制结构\n\n### 忽略了 `range` 循环变量是一个拷贝 (#30)\n\n`range` 循环中的循环变量是遍历容器中元素值的一个拷贝。因此，如果元素值是一个 struct 并且想在 `range` 中修改它，可以通过索引值来访问并修改它，或者使用经典的 for 循环+索引值的写法（除非遍历的元素是一个指针）。\n\n### 忽略了 `range` 循环中迭代目标值的计算方式 (channels 和 arrays) (#31)\n\n传递给 `range` 操作的迭代目标对应的表达式的值，只会在循环执行前被计算一次，理解这个有助于避免犯一些常见的错误，例如不高效的 channel 赋值操作和 slice 迭代操作。\n\n### 忽略了 `range` 循环中指针元素的影响 (#32)\n\n这里其实强调的是 `range` 迭代过程中，迭代变量实际上是一个拷贝。假设给另外一个容器元素（指针类型）赋值，且需要对迭代变量取地址转换成指针再赋值的话，这里潜藏着一个错误，就是 for 循环迭代变量是 per-variable-per-loop 而不是 per-variable-per-iteration。如果是通过局部变量（用迭代变量来初始化）或者使用索引值来直接引用迭代的元素，将有助于避免拷贝指针(迭代变量的地址)之类的 bug。\n\n### map 迭代过程中的错误假设（遍历顺序和迭代过程中插入）(#33)\n\n使用 map 时，为了能得到确定一致的结果，应该记住 Go 中的 map 数据结构：\n* 不会按照 key 对 data 进行排序，遍历时 key 不是有序的；\n* 遍历时的顺序，也不是按照插入时的顺序；\n* 没有一个确定性的遍历顺序，每次遍历顺序是不同的；\n* 不能保证迭代过程中新插入的元素，在当前迭代中能够被遍历到；\n\n### 忽略了 `break` 语句是如何工作的 (#34)\n\n配合 label 使用 `break` 和 `continue`，能够跳过一个特定的语句，在某些循环中存在 `switch` 和 `select` 语句的场景中就比较有帮助。\n\n### 在循环中使用 `defer`  (#35)\n\n在循环中使用 defer 不能在每轮迭代结束时执行 defer 语句，但是将循环逻辑提取到函数内部会在每次迭代结束时执行 defer 语句。\n\n## 字符串\n\n### 没有理解 rune (#36)\n\n理解 rune 类型对应的是一个 unicode 码点，每一个 unicode 码点其实是一个多字节的序列，不是一个 byte。这应该是 Go 开发者的核心知识点之一，理解了这个有助于更准确地处理字符串。\n\n### 不正确的字符串遍历 (#37)\n\n使用 `range` 操作符对一个 string 进行遍历实际上是对 string 对应的 `[]rune` 进行遍历，迭代变量中的索引值，表示的当前 rune 对应的 `[]rune` 在整个 `[]rune(string)` 中的起始索引。如果要访问 string 中的某一个 rune（比如第三个），首先要将字符串转换为 `[]rune` 然后再按索引值访问。\n\n### 误用 trim 函数 (#38)\n\n`strings.TrimRight`/`strings.TrimLeft` 移除在字符串尾部或者开头出现的一些 runes，函数会指定一个 rune 集合，出现在集合中的 rune 将被从字符串移除。而 `strings.TrimSuffix`/`strings.TrimPrefix` 是移除字符串的一个后缀/前缀。\n\n### 不经优化的字符串拼接操作 (#39)\n\n对一个字符串列表进行遍历拼接操作，应该通过 `strings.Builder` 来完成，以避免每次迭代拼接时都分配一个新的 string 对象出来。\n\n### 无用的字符串转换 (#40)\n\n`bytes` 包提供了一些和 `strings` 包相似的操作，可以帮助避免 []byte/string 之间的转换。\n\n### 子字符串和内存泄漏 (#41)\n\n使用一个子字符串的拷贝，有助于避免内存泄漏，因为对一个字符串的 `s[low:high]` 操作返回的子字符串，其使用了和原字符串 s 相同的底层数组。\n\n## 函数和方法\n\n### 不知道使用哪种接收器类型 (#42)\n\n对于接收器类型是采用 value 类型还是 pointer 类型，应该取决于下面这几种因素，比如：方法内是否会对它进行修改，它是否包含了一个不能被拷贝的字段，以及它表示的对象有多大。如果有疑问，接收器可以考虑使用 pointer 类型。\n\n### 从不使用命名的返回值 (#43)\n\n使用命名的返回值，是一种有效改善函数、方法可读性的方法，特别是返回值列表中有多个类型相同的参数。另外，因为返回值列表中的参数是经过零值初始化过的，某些场景下也会简化函数、方法的实现。但是需要注意它的一些潜在副作用。\n\n### 使用命名的返回值时预期外的副作用 (#44)\n\n见 [#43](#从不使用命名的返回值-43).\n\n使用命名的返回值，因为它已经被初始化了零值，需要注意在某些情况下异常返回时是否需要给它赋予一个不同的值，比如返回值列表定义了一个有名参数 `err error`，需要注意 `return err` 时是否正确地对 `err` 进行了赋值。\n\n### 返回一个 nil 接收器 (#45)\n\n当返回一个 interface 参数时，需要小心，不要返回一个 nil 指针，而是应该显式返回一个 nil 值。否则，可能会发生一些预期外的问题，因为调用方会收到一个非 nil 的值。\n\n### 使用文件名作为函数入参 (#46)\n\n设计函数时使用 `io.Reader` 类型作为入参，而不是文件名，将有助于改善函数的可复用性、易测试性。\n\n### 忽略 `defer` 语句中参数、接收器值的计算方式 (参数值计算, 指针, 和 value 类型接收器) (#47)\n\n为了避免 `defer` 语句执行时就立即对 defer 要执行的函数的参数进行计算，可以考虑将要执行的函数放到闭包里面，然后通过指针传递参数给闭包内函数（或者通过闭包捕获外部变量），来解决这个问题。\n\n## 错误管理\n\n### Panicking (#48)\n\n使用 `panic` 是 Go 中一种处理错误的方式，但是只能在遇到不可恢复的错误时使用，例如：通知开发人员一个强依赖的模块加载失败了。\n\n### 未考虑何时才应该包装 error (#49)\n\nWrapping（包装）错误允许您标记错误、提供额外的上下文信息。然而，包装错误会创建潜在的耦合，因为它使得原来的错误对调用者可见。如果您想要防止这种情况，请不要使用包装错误的方式。\n\n### 不正确的错误类型比较 (#50)\n\n如果你使用 Go 1.13 引入的特性 `fmt.Errorf` + `%w` 来包装一个错误，当进行错误比较时，如果想判断该包装后的错误是不是指定的错误类型，就需要使用 `errors.As`，如果想判断是不是指定的 error 对象就需要用 `errors.Is`。\n\n### 不正确的错误对象值比较 (#51)\n\n见 [#50](#不正确的错误类型比较-50).\n\n为了表达一个预期内的错误，请使用错误值的方式，并通过 `==` 或者 `errors.Is` 来比较。而对于意外错误，则应使用特定的错误类型（可以通过 `errors.As` 来比较）。\n\n### 两次处理同一个错误 (#52)\n\n大多数情况下，错误仅需要处理一次。打印错误日志也是一种错误处理。因此，当函数内发生错误时，应该在打印日志和返回错误中选择其中一种。包装错误也可以提供问题发生的额外上下文信息，也包括了原来的错误（可考虑交给调用方负责打日志）。\n\n### 不处理错误 (#53)\n\n不管是在函数调用时，还是在一个 `defer` 函数执行时，如果想要忽略一个错误，应该显式地通过 `_` 来忽略（可注明忽略的原因）。否则，将来的读者就会感觉到困惑，忽略这个错误是有意为之还是无意中漏掉了。\n\n### 不处理 `defer` 中的错误 (#54)\n\n大多数情况下，你不应该忽略 `defer` 函数执行时返回的错误，或者显式处理它，或者将它传递给调用方处理，可以根据情景进行选择。如果你确定要忽略这个错误，请显式使用 `_` 来忽略。\n\n## 并发编程: 基础\n\n### 混淆并发和并行 (#55)\n\n理解并发（concurrency）、并行（parallelism）之间的本质区别是 Go 开发人员必须要掌握的。并发是关于结构设计上的，并行是关于具体执行上的。\n\n### [认为并发总是更快](https://100go.co/56-concurrency-faster/) (#56)\n\n要成为一名熟练的开发人员，您必须意识到并非所有场景下都是并发的方案更快。对于任务中的最小工作负载部分，对它们进行并行化处理并不一定就有明显收益或者比串行化方案更快。对串行化、并发方案进行 benchmark 测试，是验证假设的好办法。\n\n### 不清楚何时使用 channels 或 mutexes (#57)\n\n了解 goroutine 之间的交互也可以在选择使用 channels 或 mutexes 时有所帮助。一般来说，并行的 goroutine 需要同步，因此需要使用 mutexes。相反，并发的 goroutine 通常需要协调和编排，因此需要使用 channels。\n\n### 不明白竞态问题 (数据竞态 vs. 竞态条件和 Go 内存模型) (#58)\n\n掌握并发意味着要认识到数据竞争（data races）和竞态条件（race conditions）是两个不同的概念。数据竞争，指的是有多个 goroutines 同时访问相同内存区域时，缺乏必要的同步控制，且其中至少有一个 goroutine 执行的是写操作。同时要认识到，没有发生数据竞争不代表程序的执行是确定性的、没问题的。当在某个特定的操作顺序或者特定的事件发生顺序下，如果最终的行为是不可控的，这就是竞态条件。\n\n> ps：数据竞争是竞态条件的子集，竞态条件不仅局限于访存未同步，它可以发生在更高的层面。`go test -race` 检测的是数据竞争，需要同步来解决，而开发者还需要关注面更广的竞态条件，它需要对多个 goroutines 的执行进行编排。\n\n理解 Go 的内存模型以及有关顺序和同步的底层保证是防止可能的数据竞争和竞态条件的关键。\n\n### 不理解不同工作负载类型对并发的影响 (#59)\n\n当创建一定数量的 goroutines 时，需要考虑工作负载的类型。如果工作负载是 CPU 密集型的，那么 goroutines 数量应该接近于 `GOMAXPROCS` 的值（该值取决于主机处理器核心数）。如果工作负载是 IO 密集型的，goroutines 数量就需要考虑多种因素，比如外部系统（考虑请求、响应速率）。\n\n### 误解了 Go contexts (#60)\n\nGo 的上下文（context）也是 Go 并发编程的基石之一。上下文允许您携带截止时间、取消信号和键值列表。\n\n## 并发编程: 实践\n\n### 传递不合适的 context (#61)\n\n当我们传递了一个 context，我们需要知道这个 context 什么时候可以被取消，这点很重要，例如：一个 HTTP 请求处理器在发送完响应后取消 context。\n\n> ps: 实际上 context 表达的是一个动作可以持续多久之后被停止。\n\n### 启动了一个 goroutine 但是不知道它何时会停止 (#62)\n\n避免 goroutine 泄漏，要有这种意识，当创建并启动一个 goroutine 的时候，应该有对应的设计让它能正常退出。\n\n### 不注意处理 goroutines 和循环中的迭代变量 (#63)\n\n为了避免 goroutines 和循环中的迭代变量问题，可以考虑创建局部变量并将迭代变量赋值给局部变量，或者 goroutines 调用带参数的函数，将迭代变量值作为参数值传入，来代替 goroutines 调用闭包。\n\n### 使用 select + channels 时误以为分支选择顺序是确定的 (#64)\n\n要明白，`select` 多个 channels 时，如果多个 channels 上的操作都就绪，那么会随机选择一个 `case` 分支来执行，因此要避免有分支选择顺序是从上到下的这种错误预设，这可能会导致设计上的 bug。\n\n### 不正确使用通知 channels (#65)\n\n发送通知时使用 `chan struct{}` 类型。\n\n> ps: 先明白什么是通知 channels，一个通知 channels 指的是只是用来做通知，而其中传递的数据没有意义，或者理解成不传递数据的 channels，这种称为通知 channels。其中传递的数据的类型为 struct{} 更合适。\n\n### 不使用 nil channels (#66)\n\n使用 nil channels 应该是并发处理方式中的一部分，例如，它能够帮助禁用 `select` 语句中的特定的分支。\n\n### 不清楚该如何确定 channel size (#67)\n\n根据指定的场景仔细评估应该使用哪一种 channel 类型（带缓冲的，不带缓冲的）。只有不带缓冲的 channels 可以提供强同步保证。\n\n使用带缓冲的 channels 时如果不确定 size 该如何设置，可以先设为 1，如果有合理的理由再去指定 channels size。\n\n> ps: 根据 disruptor 这个高性能内存消息队列的实践，在某种读写 pacing 下，队列要么满要么空，不大可能处于某种介于中间的稳态。\n\n### 忘记了字符串格式化可能带来的副作用（例如 etcd 数据竞争和死锁）(#68)\n\n意识到字符串格式化可能会导致调用现有函数，这意味着需要注意可能的死锁和其他数据竞争问题。\n\n> ps: 核心是要关注 `fmt.Sprintf` + `%v` 进行字符串格式化时 `%v` 具体到不同的类型值时，实际上执行的操作是什么。比如 `%v` 这个 placeholder 对应的值是一个 `context.Context`，那么会就遍历其通过 `context.WithValue` 附加在其中的 values，这个过程可能涉及到数据竞争问题。书中提及的另一个导致死锁的案例本质上也是一样的问题，只不过又额外牵扯到了 `sync.RWMutex` 不可重入的问题。\n\n### 使用 append 不当导致数据竞争 (#69)\n\n调用 `append` 不总是没有数据竞争的，因此不要在一个共享的 `slice` 上并发地执行 `append`。\n\n### 误用 mutexes 和 slices、maps (#70)\n\n请记住 slices 和 maps 是引用类型，有助于避免常见的数据竞争问题。\n\n> ps: 这里实际是因为错误理解了 slices 和 maps，导致写出了错误地拷贝 slices 和 maps 的代码，进而导致锁保护无效、出现数据竞争问题。\n\n### 误用 `sync.WaitGroup` (#71)\n\n正确地使用 `sync.WaitGroup` 需要在启动 goroutines 之前先调用 `Add` 方法。\n\n### 忘记使用 `sync.Cond` (#72)\n\n你可以使用 `sync.Cond` 向多个 goroutines 发送重复的通知。\n\n### 不使用 `errgroup` (#73)\n\n你可以使用 `errgroup` 包来同步一组 goroutines 并处理错误和上下文。\n\n### 拷贝一个 `sync` 下的类型 (#74)\n\n`sync` 包下的类型不应该被拷贝。\n\n## 标准库\n\n### 使用了错误的 time.Duration (#75)\n\n注意有些函数接收一个 `time.Duration` 类型的参数时，尽管直接传递一个整数是可以的，但最好还是使用 time API 中的方法来传递 duration，以避免可能造成的困惑和 bug。\n\n> ps: 重点是注意 time.Duration 定义的是 nanoseconds 数。\n\n### `time.After` 和内存泄漏 (#76)\n\n避免在重复执行很多次的函数（如循环中或 HTTP 处理函数）中调用 `time.After`，这可以避免内存峰值消耗。由 `time.After` 创建的资源仅在计时器超时才会被释放。\n\n### JSON 处理中的常见错误 (#77)\n\n* 类型嵌套导致的预料外的行为\n\n  要当心在 Go 结构体中嵌入字段，这样做可能会导致诸如嵌入的 `time.Time` 字段实现 `json.Marshaler` 接口，从而覆盖默认的 JSON 序列。\n\n* JSON 和单调时钟\n\n  当对两个 `time.Time` 类型值进行比较时，需要记住 `time.Time` 包含了一个墙上时钟（wall clock）和一个单调时钟 （monotonic clock），而使用 `==` 运算符进行比较时会同时比较这两个。\n\n* Map 键对应值为 `any`\n\n  当提供一个 map 用来 unmarshal JSON 数据时，为了避免不确定的 value 结构我们会使用 `any` 来作为 value 的类型而不是定义一个 struct，这种情况下需要记得数值默认会被转换为 `float64`。\n\n### 常见的 SQL 错误 (#78)\n\n* 忘记了 `sql.Open` 并没有与 db 服务器建立实际连接\n\n  需要调用 `Ping` 或者 `PingContext` 方法来测试配置并确保数据库是可达的。\n\n* 忘记了使用连接池\n\n  作为生产级别的应用，访问数据库时应该关注配置数据库连接池参数。\n\n* 没有使用 prepared 语句\n\n  使用 SQL prepared 语句能够让查询更加高效和安全。\n\n* 误处理 null 值\n\n  使用 `sql.NullXXX` 类型处理表中的可空列。\n\n* 不处理行迭代时的错误\n\n  调用 `sql.Rows` 的 `Err` 方法来确保在准备下一个行时没有遗漏错误。\n\n### 不关闭临时资源（HTTP 请求体、`sql.Rows` 和 `os.File`） (#79)\n\n最终要注意关闭所有实现 `io.Closer` 接口的结构体，以避免可能的泄漏。\n\n### 响应 HTTP 请求后没有返回语句 (#80)\n\n为了避免在 HTTP 处理函数中出现某些意外的问题，如果想在发生 `http.Error` 后让 HTTP 处理函数停止，那么就不要忘记使用 `return` 语句来阻止后续代码的执行。\n\n### 直接使用默认的 HTTP client 和 server (#81)\n\n对于生产级别的应用，不要使用默认的 HTTP client 和 server 实现。这些实现缺少超时和生产环境中应该强制使用的行为。\n\n## 测试\n\n### 不对测试进行分类 （build tags, 环境变量，短模式）(#82)\n\n对测试进行必要的分类，可以借助 build tags、环境变量以及短模式，来使得测试过程更加高效。你可以使用 build tags 或环境变量来创建测试类别（例如单元测试与集成测试），并区分短测试与长时间测试，来决定执行哪种类型的。\n\n> ps: 了解下 go build tags，以及 `go test -short`。\n\n### 不打开 race 开关 (#83)\n\n打开 `-race` 开关在编写并发应用时非常重要。这能帮助你捕获可能的数据竞争，从而避免软件 bug。\n\n### 不打开测试的执行模式开关 (parallel 和 shuffle) (#84)\n\n打开开关 `-parallel` 有助于加速测试的执行，特别是测试中包含一些需要长期运行的用例的时候。\n\n打开开关 `-shuffle` 能够打乱测试用例执行的顺序，避免一个测试依赖于某些不符合真实情况的预设，有助于及早暴露 bug。\n\n### 不使用表驱动的测试 (#85)\n\n表驱动的测试是一种有效的方式，可以将一组相似的测试分组在一起，以避免代码重复和使未来的更新更容易处理。\n\n### 在单元测试中执行 sleep 操作 (#86)\n\n使用同步的方式、避免 sleep，来尽量减少测试的不稳定性和提高鲁棒性。如果无法使用同步手段,可以考虑重试的方式。\n\n### 没有高效地处理 time API (#87)\n\n理解如何处理使用 time API 的函数，是使测试更加稳定的另一种方式。您可以使用标准技术，例如将时间作为隐藏依赖项的一部分来处理，或者要求客户端提供时间。\n\n### 不使用测试相关的工具包 (`httptest` 和 `iotest`) (#88)\n\n这个 `httptest` 包对处理 HTTP 应用程序很有帮助。它提供了一组实用程序来测试客户端和服务器。\n\n这个 `iotest` 包有助于编写 io.Reader 并测试应用程序是否能够容忍错误。\n\n### [不正确的基准测试](https://100go.co/89-benchmarks/) (#89)\n\n* 不要重置或者暂停 timer\n\n  使用 time 方法来保持基准测试的准确性。\n\n* 做出错误的微基准测试假设\n\n  增加 `benchtime` 或者使用 `benchstat` 等工具可以有助于微基准测试。\n\n  小心微基准测试的结果，如果最终运行应用程序的系统与运行微基准测试的系统不同。\n\n* 对编译期优化要足够小心\n\n  确保测试函数是否会产生一些副作用，防止编译器优化欺骗你得到的基准测试结果。\n\n* 被观察者效应所欺骗\n\n  为了避免被观察者效应欺骗，强制重新创建CPU密集型函数使用的数据。\n\n### 没有去探索 go test 所有的特性 (#90)\n\n* 代码覆盖率\n\n  使用 `-coverprofile` 参数可以快速查看代码的测试覆盖情况，方便快速查看哪个部分需要更多的关注。\n\n* 在不同的包中执行测试\n\n  单元测试组织到一个独立的包中，对于对外层暴露的接口，需要写一些测试用例。测试应该关注公开的行为，而非内部实现细节。\n\n* Utility 函数\n\n  处理错误时，使用 `*testing.T` 变量而不是经典的 `if err != nil` 可以让代码更加简洁易读。\n\n* 设置和销毁\n\n  你可以使用 setup 和 teardown 函数来配置一个复杂的环境，比如在集成测试的情况下。\n\n### 不使用模糊测试 (社区反馈错误)\n\n模糊测试是一种高效的策略，使用它能检测出随机、意料外的和一些恶意的数据输入，来完成一些复杂的操作。\n\n见: [@jeromedoucet](https://github.com/jeromedoucet)\n\n## 优化技术\n\n### 不理解 CPU cache (#91)\n\n* CPU 架构\n\n  理解 CPU 缓存的使用对于优化 CPU 密集型应用很重要，因为 L1 缓存比主存快 50 到 100 倍。\n\n* Cache line\n\n  意识到 cache line 概念对于理解如何在数据密集型应用中组织数据非常关键。CPU 并不是一个一个字来获取内存。相反，它通常复制一个 64 字节长度的 cache line。为了获得每个 cache line 的最大效用，需要实施空间局部性。\n\n* 一系列 struct 元素构成的 slice vs. 多个 slice 字段构成的 struct\n\n* 概率性的问题\n\n  提高 CPU 执行代码时的可预测性，也是优化某些函数的一个有效方法。比如，固定步长或连续访问对 CPU 来说是可预测的，但非连续访问（例如链表）就是不可预测的。\n\n* cache 放置策略\n\n  要注意现代缓存是分区的（set associative placement，组相连映射），要注意避免使用 `critical stride`，这种步长情况下只能利用 cache 的一小部分。\n\n  > critical stride，这种类型的步长，指的是内存访问的步长刚好等于 cache 大小。这种情况下，只有少部分 cacheline 被利用。\n\n### 写的并发处理逻辑会导致 false sharing (#92)\n\n了解 CPU 缓存的较低层的 L1、L2 cache 不会在所有核间共享，编写并发处理逻辑时能避免写出一些降低性能的问题，比如伪共享（false sharing）。内存共享只是一种假象。\n\n### 没有考虑指令级的并行 (#93)\n\n使用指令级并行（ILP）优化代码的特定部分，以允许 CPU 尽可能执行更多可以并行执行的指令。识别指令的数据依赖问题（data hazards）是主要步骤之一。\n\n### 不了解数据对齐 (#94)\n\n记住 Go 中基本类型与其自身大小对齐，例如，按大小降序重新组织结构体的字段可以形成更紧凑的结构体（减少内存分配，更好的空间局部性），这有助于避免一些常见的错误。\n\n### 不了解 stack vs. heap (#95)\n\n了解堆和栈之间的区别是开发人员的核心知识点，特别是要去优化一个 Go 程序时。栈分配的开销几乎为零，而堆分配则较慢，并且依赖 GC 来清理内存。\n\n### 不知道如何减少内存分配次数（API 调整，编译器优化和 `sync.Pool`） (#96)\n\n减少内存分配次数也是优化 Go 应用的一个重要方面。这可以通过不同的方式来实现，比如仔细设计 API 来避免不必要的拷贝，以及使用 `sync.Pool` 来对分配对象进行池化。\n\n### 不注意使用内联 (#97)\n\n使用快速路径的内联技术来更加有效地减少调用函数的摊销时间。\n\n### [不使用 Go 问题诊断工具](https://100go.co/98-profiling-execution-tracing/) (#98)\n\n了解 Go profiling 工具、执行时 tracer 来辅助判断一个应用程序是否正常，以及列出需要优化的部分。\n\n### 不理解 GC 是如何工作的 (#99)\n\n理解如何调优 GC 能够带来很多收益，例如有助于更高效地处理突增的负载。\n\n### 不了解 Docker 或者 K8S 对运行的 Go 应用的性能影响 (#100)\n\n为了避免 CPU throttling（CPU 限频）问题，当我们在 Docker 和 Kubernetes 部署应用时，要知道 Go 语言对 CFS（完全公平调度器）无感知。\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/teivah/100-go-mistakes\n\ngo 1.18\n\nrequire golang.org/x/sync v0.0.0-20210220032951-036812b2e83c\n"
  },
  {
    "path": "go.sum",
    "content": "golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\n"
  },
  {
    "path": "includes/abbreviations.md",
    "content": "*[GC]: Garbage Collector\n*[ILP]: Instruction-Level Parallelism\n*[CFS]: Completely Fair Scheduler\n*[GOMAXPROCS]: The variable defines the limit of OS threads in charge of executing user-level code simultaneously\n"
  },
  {
    "path": "justfile",
    "content": "build:\n  mkdocs build\nserve:\n  mkdocs serve\ntest:\n  mkdocs build && mkdocs serve\n"
  },
  {
    "path": "mkdocs.yml",
    "content": "site_name: 100 Go Mistakes and How to Avoid Them\nsite_url: https://100go.co\nrepo_name: teivah/100-go-mistakes\ntheme:\n  name: material\n  custom_dir: overrides\n  favicon: img/Go-Logo_LightBlue.svg\n  language: en\n  logo: img/Go-Logo_White.svg\n  icon:\n    repo: fontawesome/brands/github\n  features:\n    - navigation.tabs\n    - navigation.tabs.sticky\n    - search.highlight\n    - search.share\n    - search.suggest\n    - content.code.copy\n    - navigation.expand\n#    - navigation.instant -- Navigation is too slow\n    - navigation.sections\n    - announce.dismiss\n#    - navigation.tracking\n    - toc.follow\n    - content.code.annotate\n    - content.tooltips\n  palette:\n    # Palette toggle for light mode\n    - scheme: default\n      toggle:\n        icon: material/brightness-7 \n        name: Switch to dark mode\n      primary: cyan\n      accent: deep orange\n    # Palette toggle for dark mode\n    - scheme: slate\n      toggle:\n        icon: material/brightness-4\n        name: Switch to light mode\n      primary: blue grey\n      accent: teal\nrepo_url: https://github.com/teivah/100-go-mistakes\nplugins:\n  - search\n  - glightbox\n  - social:\n      cards_layout_options:\n        logo: img/cover.png\nextra:\n  analytics:\n    provider: google\n    property: G-HMY1HYDM93\n  alternate:\n    - name: 🇬🇧 English\n      link: /\n      lang: en\n    - name: 🇨🇳 简体中文\n      link: /zh/\n      lang: zh\n    - name: 🇯🇵 日本語\n      link: /ja/\n      lang: ja\n    - name: 🇧🇷 Português Brasileiro\n      link: /pt-br/\n      lang: pt-br\n  social:\n    - icon: fontawesome/brands/twitter\n      link: https://twitter.com/teivah\n  status:\n    new: New content\nextra_css:\n  - stylesheets/extra.css\nnav:\n    - Go Mistakes:\n      - index.md\n      - Full Sections:\n        - 5-interface-pollution.md\n        - 9-generics.md\n        - 20-slice.md\n        - 28-maps-memory-leaks.md\n        - 56-concurrency-faster.md\n        - 89-benchmarks.md\n        - 92-false-sharing.md\n        - 98-profiling-execution-tracing.md\n      - Translations:\n        - '🇨🇳 简体中文': zh.md\n        - '🇯🇵 日本語': ja.md\n        - '🇧🇷 Português Brasileiro': pt-br.md\n    - Book Details:\n      - book.md\n      - chapter-1.md\n      - external.md\n    - 'The Story Behind 100 Go Mistakes': https://www.thecoder.cafe/p/100-go-mistakes\n\nmarkdown_extensions:\n  - abbr\n  - admonition\n  - pymdownx.details\n  - pymdownx.highlight:\n      anchor_linenums: true\n      line_spans: __span\n      pygments_lang_class: true\n  - pymdownx.highlight\n  - pymdownx.inlinehilite\n  - pymdownx.snippets:\n      auto_append:\n        - includes/abbreviations.md\n  - pymdownx.superfences\n  - tables\n  - attr_list\n  - md_in_html\n  - footnotes\n  - pymdownx.emoji:\n      emoji_index: !!python/name:material.extensions.emoji.twemoji\n      emoji_generator: !!python/name:material.extensions.emoji.to_svg\ncopyright: Copyright &copy; 2022 - 2024 Teiva Harsanyi\n"
  },
  {
    "path": "overrides/main.html",
    "content": "{% extends \"base.html\" %}\n"
  },
  {
    "path": "overrides/partials/comments.html",
    "content": "{% if page.meta.comments %}\n<h2 id=\"__comments\">{{ lang.t(\"meta.comments\") }}</h2>\n<!-- Insert generated snippet here -->\n<script src=\"https://giscus.app/client.js\"\n        data-repo=\"teivah/100-go-mistakes\"\n        data-repo-id=\"MDEwOlJlcG9zaXRvcnkzMjA4MTg5NjI=\"\n        data-category=\"Discussions\"\n        data-category-id=\"DIC_kwDOEx9PEs4CZQUm\"\n        data-mapping=\"pathname\"\n        data-strict=\"0\"\n        data-reactions-enabled=\"1\"\n        data-emit-metadata=\"0\"\n        data-input-position=\"bottom\"\n        data-theme=\"preferred_color_scheme\"\n        data-lang=\"en\"\n        crossorigin=\"anonymous\"\n        async>\n</script>\n<!-- Synchronize Giscus theme with palette -->\n<script>\n  var giscus = document.querySelector(\"script[src*=giscus]\")\n\n  // Set palette on initial load\n  var palette = __md_get(\"__palette\")\n  if (palette && typeof palette.color === \"object\") {\n    var theme = palette.color.scheme === \"slate\"\n        ? \"transparent_dark\"\n        : \"light\"\n\n    // Instruct Giscus to set theme\n    giscus.setAttribute(\"data-theme\", theme)\n  }\n\n  // Register event handlers after documented loaded\n  document.addEventListener(\"DOMContentLoaded\", function() {\n    var ref = document.querySelector(\"[data-md-component=palette]\")\n    ref.addEventListener(\"change\", function() {\n      var palette = __md_get(\"__palette\")\n      if (palette && typeof palette.color === \"object\") {\n        var theme = palette.color.scheme === \"slate\"\n            ? \"transparent_dark\"\n            : \"light\"\n\n        // Instruct Giscus to change theme\n        var frame = document.querySelector(\".giscus-frame\")\n        frame.contentWindow.postMessage(\n            { giscus: { setConfig: { theme } } },\n            \"https://giscus.app\"\n        )\n      }\n    })\n  })\n</script>\n{% endif %}\n"
  },
  {
    "path": "site/20-slice/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\" class=\"no-js\"><head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n      \n      \n        <link rel=\"canonical\" href=\"https://100go.co/20-slice/\">\n      \n      \n        <link rel=\"prev\" href=\"../9-generics/\">\n      \n      \n        <link rel=\"next\" href=\"../28-maps-memory-leaks/\">\n      \n      \n      <link rel=\"icon\" href=\"../img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>Not understanding slice length and capacity (#20) - 100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"../assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\"..\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n      \n        <meta property=\"og:type\" content=\"website\">\n      \n        <meta property=\"og:title\" content=\"Not understanding slice length and capacity (#20) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta property=\"og:description\" content=\"None\">\n      \n        <meta property=\"og:image\" content=\"https://100go.co/assets/images/social/20-slice.png\">\n      \n        <meta property=\"og:image:type\" content=\"image/png\">\n      \n        <meta property=\"og:image:width\" content=\"1200\">\n      \n        <meta property=\"og:image:height\" content=\"630\">\n      \n        <meta property=\"og:url\" content=\"https://100go.co/20-slice/\">\n      \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n      \n        <meta name=\"twitter:title\" content=\"Not understanding slice length and capacity (#20) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta name=\"twitter:description\" content=\"None\">\n      \n        <meta name=\"twitter:image\" content=\"https://100go.co/assets/images/social/20-slice.png\">\n      \n    \n    \n  <link href=\"../assets/stylesheets/glightbox.min.css\" rel=\"stylesheet\"><script src=\"../assets/javascripts/glightbox.min.js\"></script><style id=\"glightbox-style\">\n            html.glightbox-open { overflow: initial; height: 100%; }\n            .gslide-title { margin-top: 0px; user-select: text; }\n            .gslide-desc { color: #666; user-select: text; }\n            .gslide-image img { background: white; }\n            .gscrollbar-fixer { padding-right: 15px; }\n            .gdesc-inner { font-size: 0.75rem; }\n            body[data-md-color-scheme=\"slate\"] .gdesc-inner { background: var(--md-default-bg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-title { color: var(--md-default-fg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-desc { color: var(--md-default-fg-color); }\n        </style></head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n        \n        <a href=\"#not-understanding-slice-length-and-capacity\" class=\"md-skip\">\n          Skip to content\n        </a>\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"></path></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              Not understanding slice length and capacity (#20)\n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"></path></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"></path></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"></path></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n    \n  \n  \n    \n    \n      <li class=\"md-tabs__item md-tabs__item--active\">\n        <a href=\"..\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"../book/\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n        \n        \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"..\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1_2\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../5-interface-pollution/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../9-generics/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    <li class=\"md-nav__item md-nav__item--active\">\n      \n      <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n      \n      \n        \n      \n      \n      <a href=\"./\" class=\"md-nav__link md-nav__link--active\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../28-maps-memory-leaks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../56-concurrency-faster/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../89-benchmarks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../92-false-sharing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../98-profiling-execution-tracing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_3\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../zh/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../ja/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../pt-br/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../book/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../chapter-1/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../external/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\" hidden>\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n                  \n  \n\n\n\n  \n  \n\n\n<h1 id=\"not-understanding-slice-length-and-capacity\">Not understanding slice length and capacity</h1>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/20-slice.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/20-slice.png\"></a></p>\n<p>It’s pretty common for Go developers to mix slice length and capacity or not understand them thoroughly. Assimilating these two concepts is essential for efficiently handling core operations such as slice initialization and adding elements with append, copying, or slicing. This misunderstanding can lead to using slices suboptimally or even to memory leaks.</p>\n<p>In Go, a slice is backed by an array. That means the slice’s data is stored contiguously in an array data structure. A slice also handles the logic of adding an element if the backing array is full or shrinking the backing array if it’s almost empty.</p>\n<p>Internally, a slice holds a pointer to the backing array plus a length and a capacity. The length is the number of elements the slice contains, whereas the capacity is the number of elements in the backing array, counting from the first element in the slice. Let’s go through a few examples to make things clearer. First, let’s initialize a slice with a given length and capacity:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-0-1\"><a id=\"__codelineno-0-1\" name=\"__codelineno-0-1\" href=\"#__codelineno-0-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">([]</span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">6</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// Three-length, six-capacity slice</span>\n</span></code></pre></div>\n<p>The first argument, representing the length, is mandatory. However, the second argument representing the capacity is optional. Figure 1 shows the result of this code in memory.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/slice-1.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/slice-1.png\"></a>\n  </p>\n<figcaption>Figure 1: A three-length, six-capacity slice.</figcaption>\n</figure>\n<p>In this case, <code>make</code> creates an array of six elements (the capacity). But because the length was set to 3, Go initializes only the first three elements. Also, because the slice is an <code>[]int</code> type, the first three elements are initialized to the zeroed value of an <code>int</code>: 0. The grayed elements are allocated but not yet used.</p>\n<p>If we print this slice, we get the elements within the range of the length, <code>[0 0 0]</code>. If we set <code>s[1]</code> to 1, the second element of the slice updates without impacting its length or capacity. Figure 2 illustrates this.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/slice-2.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/slice-2.png\"></a>\n  </p>\n<figcaption>Figure 2: Updating the slice’s second element: s[1] = 1.</figcaption>\n</figure>\n<p>However, accessing an element outside the length range is forbidden, even though it’s already allocated in memory. For example, <code>s[4]</code> = 0 would lead to the following panic:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-1-1\"><a id=\"__codelineno-1-1\" name=\"__codelineno-1-1\" href=\"#__codelineno-1-1\"></a>panic: runtime error: index out of range [4] with length 3\n</span></code></pre></div>\n<p>How can we use the remaining space of the slice? By using the <code>append</code> built-in function:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-2-1\"><a id=\"__codelineno-2-1\" name=\"__codelineno-2-1\" href=\"#__codelineno-2-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>This code appends to the existing <code>s</code> slice a new element. It uses the first grayed element (which was allocated but not yet used) to store element 2, as figure 3 shows.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/slice-3.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/slice-3.png\"></a>\n  </p>\n<figcaption>Figure 3: Appending an element to s.</figcaption>\n</figure>\n<p>The length of the slice is updated from 3 to 4 because the slice now contains four elements. Now, what happens if we add three more elements so that the backing array isn’t large enough?</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-3-1\"><a id=\"__codelineno-3-1\" name=\"__codelineno-3-1\" href=\"#__codelineno-3-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">4</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">5</span><span class=\"p\">)</span>\n</span><span id=\"__span-3-2\"><a id=\"__codelineno-3-2\" name=\"__codelineno-3-2\" href=\"#__codelineno-3-2\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>If we run this code, we see that the slice was able to cope with our request:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-4-1\"><a id=\"__codelineno-4-1\" name=\"__codelineno-4-1\" href=\"#__codelineno-4-1\"></a>[0 1 0 2 3 4 5]\n</span></code></pre></div>\n<p>Because an array is a fixed-size structure, it can store the new elements until element 4. When we want to insert element 5, the array is already full: Go internally creates another array by doubling the capacity, copying all the elements, and then inserting element 5. Figure 4 shows this process.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/slice-4.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/slice-4.png\"></a>\n  </p>\n<figcaption>Figure 4: Because the initial backing array is full, Go creates another array and copies all the elements.</figcaption>\n</figure>\n<p>The slice now references the new backing array. What will happen to the previous backing array? If it’s no longer referenced, it’s eventually freed by the garbage collector (<abbr title=\"Garbage Collector\">GC</abbr>) if allocated on the heap. (We discuss heap memory in mistake #95, “<a href=\"https://100go.co#not-understanding-stack-vs-heap-95\">Not understanding stack vs. heap</a>,” and we look at how the <abbr title=\"Garbage Collector\">GC</abbr> works in mistake #99, “<a href=\"https://100go.co#not-understanding-how-the-gc-works-99\">Not understanding how the <abbr title=\"Garbage Collector\">GC</abbr> works</a>.”)</p>\n<p>What happens with slicing? Slicing is an operation done on an array or a slice, providing a half-open range; the first index is included, whereas the second is excluded. The following example shows the impact, and figure 5 displays the result in memory:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-5-1\"><a id=\"__codelineno-5-1\" name=\"__codelineno-5-1\" href=\"#__codelineno-5-1\"></a><span class=\"nx\">s1</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">([]</span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">3</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">6</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// Three-length, six-capacity slice</span>\n</span><span id=\"__span-5-2\"><a id=\"__codelineno-5-2\" name=\"__codelineno-5-2\" href=\"#__codelineno-5-2\"></a><span class=\"nx\">s2</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">s1</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:</span><span class=\"mi\">3</span><span class=\"p\">]</span><span class=\"w\"> </span><span class=\"c1\">// Slicing from indices 1 to 3</span>\n</span></code></pre></div>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/slice-5.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/slice-5.png\"></a>\n  </p>\n<figcaption>Figure 5: The slices s1 and s2 reference the same backing array with different lengths and capacities.</figcaption>\n</figure>\n<p>First, <code>s1</code> is created as a three-length, six-capacity slice. When <code>s2</code> is created by slicing <code>s1</code>, both slices reference the same backing array. However, <code>s2</code> starts from a different index, 1. Therefore, its length and capacity (a two-length, five-capacity slice) differ from s1. If we update <code>s1[1]</code> or <code>s2[0]</code>, the change is made to the same array, hence, visible in both slices, as figure 6 shows.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/slice-6.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/slice-6.png\"></a>\n  </p>\n<figcaption>Figure 6: Because s1 and s2 are backed by the same array, updating a common element makes the change visible in both slices.</figcaption>\n</figure>\n<p>Now, what happens if we append an element to <code>s2</code>? Does the following code change <code>s1</code> as well?</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-6-1\"><a id=\"__codelineno-6-1\" name=\"__codelineno-6-1\" href=\"#__codelineno-6-1\"></a><span class=\"nx\">s2</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">s2</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>The shared backing array is modified, but only the length of <code>s2</code> changes. Figure 7 shows the result of appending an element to <code>s2</code>.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/slice-7.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/slice-7.png\"></a>\n  </p>\n<figcaption>Figure 7: Appending an element to s2.</figcaption>\n</figure>\n<p><code>s1</code> remains a three-length, six-capacity slice. Therefore, if we print <code>s1</code> and <code>s2</code>, the added element is only visible for <code>s2</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-7-1\"><a id=\"__codelineno-7-1\" name=\"__codelineno-7-1\" href=\"#__codelineno-7-1\"></a><span class=\"nx\">s1</span><span class=\"p\">=[</span><span class=\"mi\">0</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">],</span><span class=\"w\"> </span><span class=\"nx\">s2</span><span class=\"p\">=[</span><span class=\"mi\">1</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"p\">]</span>\n</span></code></pre></div>\n<p>It’s important to understand this behavior so that we don’t make wrong assumptions while using append.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>In these examples, the backing array is internal and not available directly to the Go developer. The only exception is when a slice is created from slicing an existing array.</p>\n</details>\n<p>One last thing to note: what if we keep appending elements to <code>s2</code> until the backing array is full? What will the state be, memory-wise? Let’s add three more elements so that the backing array will not have enough capacity:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-8-1\"><a id=\"__codelineno-8-1\" name=\"__codelineno-8-1\" href=\"#__codelineno-8-1\"></a><span class=\"nx\">s2</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">s2</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">3</span><span class=\"p\">)</span>\n</span><span id=\"__span-8-2\"><a id=\"__codelineno-8-2\" name=\"__codelineno-8-2\" href=\"#__codelineno-8-2\"></a><span class=\"nx\">s2</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">s2</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">4</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// At this stage, the backing is already full</span>\n</span><span id=\"__span-8-3\"><a id=\"__codelineno-8-3\" name=\"__codelineno-8-3\" href=\"#__codelineno-8-3\"></a><span class=\"nx\">s2</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">s2</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">5</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>This code leads to creating another backing array. Figure 8 displays the results in memory.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/slice-8.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/slice-8.png\"></a>\n  </p>\n<figcaption>Figure 8: Appending elements to s2 until the backing array is full.</figcaption>\n</figure>\n<p><code>s1</code> and <code>s2</code> now reference two different arrays. As <code>s1</code> is still a three-length, six-capacity slice, it still has some available buffer, so it keeps referencing the initial array. Also, the new backing array was made by copying the initial one from the first index of <code>s2</code>. That’s why the new array starts with element 1, not 0.</p>\n<p>To summarize, the slice length is the number of available elements in the slice, whereas the slice capacity is the number of elements in the backing array. Adding an element to a full slice (length == capacity) leads to creating a new backing array with a new capacity, copying all the elements from the previous array, and updating the slice pointer to the new array.</p>\n\n\n\n\n\n\n\n  \n  \n\n\n\n  \n\n\n  \n\n\n\n<h2 id=\"__comments\">Comments</h2>\n<!-- Insert generated snippet here -->\n<script src=\"https://giscus.app/client.js\" data-repo=\"teivah/100-go-mistakes\" data-repo-id=\"MDEwOlJlcG9zaXRvcnkzMjA4MTg5NjI=\" data-category=\"Discussions\" data-category-id=\"DIC_kwDOEx9PEs4CZQUm\" data-mapping=\"pathname\" data-strict=\"0\" data-reactions-enabled=\"1\" data-emit-metadata=\"0\" data-input-position=\"bottom\" data-theme=\"preferred_color_scheme\" data-lang=\"en\" crossorigin=\"anonymous\" async>\n</script>\n<!-- Synchronize Giscus theme with palette -->\n<script>\n  var giscus = document.querySelector(\"script[src*=giscus]\")\n\n  // Set palette on initial load\n  var palette = __md_get(\"__palette\")\n  if (palette && typeof palette.color === \"object\") {\n    var theme = palette.color.scheme === \"slate\"\n        ? \"transparent_dark\"\n        : \"light\"\n\n    // Instruct Giscus to set theme\n    giscus.setAttribute(\"data-theme\", theme)\n  }\n\n  // Register event handlers after documented loaded\n  document.addEventListener(\"DOMContentLoaded\", function() {\n    var ref = document.querySelector(\"[data-md-component=palette]\")\n    ref.addEventListener(\"change\", function() {\n      var palette = __md_get(\"__palette\")\n      if (palette && typeof palette.color === \"object\") {\n        var theme = palette.color.scheme === \"slate\"\n            ? \"transparent_dark\"\n            : \"light\"\n\n        // Instruct Giscus to change theme\n        var frame = document.querySelector(\".giscus-frame\")\n        frame.contentWindow.postMessage(\n            { giscus: { setConfig: { theme } } },\n            \"https://giscus.app\"\n        )\n      }\n    })\n  })\n</script>\n\n                \n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright © 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"></path></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \"..\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"../assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"../assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  \n<script id=\"init-glightbox\">const lightbox = GLightbox({\"touchNavigation\": true, \"loop\": false, \"zoomable\": true, \"draggable\": true, \"openEffect\": \"zoom\", \"closeEffect\": \"zoom\", \"slideEffect\": \"slide\"});\ndocument$.subscribe(()=>{ lightbox.reload(); });\n</script></body></html>"
  },
  {
    "path": "site/28-maps-memory-leaks/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\" class=\"no-js\"><head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n      \n      \n        <link rel=\"canonical\" href=\"https://100go.co/28-maps-memory-leaks/\">\n      \n      \n        <link rel=\"prev\" href=\"../20-slice/\">\n      \n      \n        <link rel=\"next\" href=\"../56-concurrency-faster/\">\n      \n      \n      <link rel=\"icon\" href=\"../img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>Maps and memory leaks (#28) - 100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"../assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\"..\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n      \n        <meta property=\"og:type\" content=\"website\">\n      \n        <meta property=\"og:title\" content=\"Maps and memory leaks (#28) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta property=\"og:description\" content=\"None\">\n      \n        <meta property=\"og:image\" content=\"https://100go.co/assets/images/social/28-maps-memory-leaks.png\">\n      \n        <meta property=\"og:image:type\" content=\"image/png\">\n      \n        <meta property=\"og:image:width\" content=\"1200\">\n      \n        <meta property=\"og:image:height\" content=\"630\">\n      \n        <meta property=\"og:url\" content=\"https://100go.co/28-maps-memory-leaks/\">\n      \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n      \n        <meta name=\"twitter:title\" content=\"Maps and memory leaks (#28) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta name=\"twitter:description\" content=\"None\">\n      \n        <meta name=\"twitter:image\" content=\"https://100go.co/assets/images/social/28-maps-memory-leaks.png\">\n      \n    \n    \n  <link href=\"../assets/stylesheets/glightbox.min.css\" rel=\"stylesheet\"><script src=\"../assets/javascripts/glightbox.min.js\"></script><style id=\"glightbox-style\">\n            html.glightbox-open { overflow: initial; height: 100%; }\n            .gslide-title { margin-top: 0px; user-select: text; }\n            .gslide-desc { color: #666; user-select: text; }\n            .gslide-image img { background: white; }\n            .gscrollbar-fixer { padding-right: 15px; }\n            .gdesc-inner { font-size: 0.75rem; }\n            body[data-md-color-scheme=\"slate\"] .gdesc-inner { background: var(--md-default-bg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-title { color: var(--md-default-fg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-desc { color: var(--md-default-fg-color); }\n        </style></head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n        \n        <a href=\"#maps-and-memory-leaks\" class=\"md-skip\">\n          Skip to content\n        </a>\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"></path></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              Maps and memory leaks (#28)\n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"></path></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"></path></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"></path></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n    \n  \n  \n    \n    \n      <li class=\"md-tabs__item md-tabs__item--active\">\n        <a href=\"..\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"../book/\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n        \n        \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"..\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1_2\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../5-interface-pollution/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../9-generics/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../20-slice/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    <li class=\"md-nav__item md-nav__item--active\">\n      \n      <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n      \n      \n        \n      \n      \n      <a href=\"./\" class=\"md-nav__link md-nav__link--active\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../56-concurrency-faster/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../89-benchmarks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../92-false-sharing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../98-profiling-execution-tracing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_3\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../zh/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../ja/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../pt-br/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../book/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../chapter-1/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../external/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\" hidden>\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n                  \n  \n\n\n\n  \n  \n\n\n<h1 id=\"maps-and-memory-leaks\">Maps and memory leaks</h1>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/28-maps-memory-leaks.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/28-maps-memory-leaks.png\"></a></p>\n<p>When working with maps in Go, we need to understand some important characteristics of how a map grows and shrinks. Let’s delve into this to prevent issues that can cause memory leaks.</p>\n<p>First, to view a concrete example of this problem, let’s design a scenario where we will work with the following map:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-0-1\"><a id=\"__codelineno-0-1\" name=\"__codelineno-0-1\" href=\"#__codelineno-0-1\"></a><span class=\"nx\">m</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">map</span><span class=\"p\">[</span><span class=\"kt\">int</span><span class=\"p\">][</span><span class=\"mi\">128</span><span class=\"p\">]</span><span class=\"kt\">byte</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>Each value of m is an array of 128 bytes. We will do the following:</p>\n<ol>\n<li>Allocate an empty map.</li>\n<li>Add 1 million elements.</li>\n<li>Remove all the elements, and run a Garbage Collection (<abbr title=\"Garbage Collector\">GC</abbr>).</li>\n</ol>\n<p>After each step, we want to print the size of the heap (using a <code>printAlloc</code> utility function). This shows us how this example behaves memory-wise:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-1-1\"><a id=\"__codelineno-1-1\" name=\"__codelineno-1-1\" href=\"#__codelineno-1-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-2\"><a id=\"__codelineno-1-2\" name=\"__codelineno-1-2\" href=\"#__codelineno-1-2\"></a><span class=\"w\">    </span><span class=\"nx\">n</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"nx\">_000_000</span>\n</span><span id=\"__span-1-3\"><a id=\"__codelineno-1-3\" name=\"__codelineno-1-3\" href=\"#__codelineno-1-3\"></a><span class=\"w\">    </span><span class=\"nx\">m</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">map</span><span class=\"p\">[</span><span class=\"kt\">int</span><span class=\"p\">][</span><span class=\"mi\">128</span><span class=\"p\">]</span><span class=\"kt\">byte</span><span class=\"p\">)</span>\n</span><span id=\"__span-1-4\"><a id=\"__codelineno-1-4\" name=\"__codelineno-1-4\" href=\"#__codelineno-1-4\"></a><span class=\"w\">    </span><span class=\"nx\">printAlloc</span><span class=\"p\">()</span>\n</span><span id=\"__span-1-5\"><a id=\"__codelineno-1-5\" name=\"__codelineno-1-5\" href=\"#__codelineno-1-5\"></a>\n</span><span id=\"__span-1-6\"><a id=\"__codelineno-1-6\" name=\"__codelineno-1-6\" href=\"#__codelineno-1-6\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">n</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Adds 1 million elements</span>\n</span><span id=\"__span-1-7\"><a id=\"__codelineno-1-7\" name=\"__codelineno-1-7\" href=\"#__codelineno-1-7\"></a><span class=\"w\">        </span><span class=\"nx\">m</span><span class=\"p\">[</span><span class=\"nx\">i</span><span class=\"p\">]</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"mi\">128</span><span class=\"p\">]</span><span class=\"kt\">byte</span><span class=\"p\">{}</span>\n</span><span id=\"__span-1-8\"><a id=\"__codelineno-1-8\" name=\"__codelineno-1-8\" href=\"#__codelineno-1-8\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-1-9\"><a id=\"__codelineno-1-9\" name=\"__codelineno-1-9\" href=\"#__codelineno-1-9\"></a><span class=\"w\">    </span><span class=\"nx\">printAlloc</span><span class=\"p\">()</span>\n</span><span id=\"__span-1-10\"><a id=\"__codelineno-1-10\" name=\"__codelineno-1-10\" href=\"#__codelineno-1-10\"></a>\n</span><span id=\"__span-1-11\"><a id=\"__codelineno-1-11\" name=\"__codelineno-1-11\" href=\"#__codelineno-1-11\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">n</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Deletes 1 million elements</span>\n</span><span id=\"__span-1-12\"><a id=\"__codelineno-1-12\" name=\"__codelineno-1-12\" href=\"#__codelineno-1-12\"></a><span class=\"w\">        </span><span class=\"nb\">delete</span><span class=\"p\">(</span><span class=\"nx\">m</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">)</span>\n</span><span id=\"__span-1-13\"><a id=\"__codelineno-1-13\" name=\"__codelineno-1-13\" href=\"#__codelineno-1-13\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-1-14\"><a id=\"__codelineno-1-14\" name=\"__codelineno-1-14\" href=\"#__codelineno-1-14\"></a>\n</span><span id=\"__span-1-15\"><a id=\"__codelineno-1-15\" name=\"__codelineno-1-15\" href=\"#__codelineno-1-15\"></a><span class=\"w\">    </span><span class=\"nx\">runtime</span><span class=\"p\">.</span><span class=\"nx\">GC</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// Triggers a manual GC</span>\n</span><span id=\"__span-1-16\"><a id=\"__codelineno-1-16\" name=\"__codelineno-1-16\" href=\"#__codelineno-1-16\"></a><span class=\"w\">    </span><span class=\"nx\">printAlloc</span><span class=\"p\">()</span>\n</span><span id=\"__span-1-17\"><a id=\"__codelineno-1-17\" name=\"__codelineno-1-17\" href=\"#__codelineno-1-17\"></a><span class=\"w\">    </span><span class=\"nx\">runtime</span><span class=\"p\">.</span><span class=\"nx\">KeepAlive</span><span class=\"p\">(</span><span class=\"nx\">m</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// Keeps a reference to m so that the map isn’t collected</span>\n</span><span id=\"__span-1-18\"><a id=\"__codelineno-1-18\" name=\"__codelineno-1-18\" href=\"#__codelineno-1-18\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-1-19\"><a id=\"__codelineno-1-19\" name=\"__codelineno-1-19\" href=\"#__codelineno-1-19\"></a>\n</span><span id=\"__span-1-20\"><a id=\"__codelineno-1-20\" name=\"__codelineno-1-20\" href=\"#__codelineno-1-20\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">printAlloc</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-21\"><a id=\"__codelineno-1-21\" name=\"__codelineno-1-21\" href=\"#__codelineno-1-21\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">m</span><span class=\"w\"> </span><span class=\"nx\">runtime</span><span class=\"p\">.</span><span class=\"nx\">MemStats</span>\n</span><span id=\"__span-1-22\"><a id=\"__codelineno-1-22\" name=\"__codelineno-1-22\" href=\"#__codelineno-1-22\"></a><span class=\"w\">    </span><span class=\"nx\">runtime</span><span class=\"p\">.</span><span class=\"nx\">ReadMemStats</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">m</span><span class=\"p\">)</span>\n</span><span id=\"__span-1-23\"><a id=\"__codelineno-1-23\" name=\"__codelineno-1-23\" href=\"#__codelineno-1-23\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"%d MB\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">m</span><span class=\"p\">.</span><span class=\"nx\">Alloc</span><span class=\"o\">/</span><span class=\"p\">(</span><span class=\"mi\">1024</span><span class=\"o\">*</span><span class=\"mi\">1024</span><span class=\"p\">))</span>\n</span><span id=\"__span-1-24\"><a id=\"__codelineno-1-24\" name=\"__codelineno-1-24\" href=\"#__codelineno-1-24\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>We allocate an empty map, add 1 million elements, remove 1 million elements, and then run a <abbr title=\"Garbage Collector\">GC</abbr>. We also make sure to keep a reference to the map using <a href=\"https://pkg.go.dev/runtime#KeepAlive\"><code>runtime.KeepAlive</code></a> so that the map isn’t collected as well. Let’s run this example:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-2-1\"><a id=\"__codelineno-2-1\" name=\"__codelineno-2-1\" href=\"#__codelineno-2-1\"></a>0 MB   &lt;-- After m is allocated\n</span><span id=\"__span-2-2\"><a id=\"__codelineno-2-2\" name=\"__codelineno-2-2\" href=\"#__codelineno-2-2\"></a>461 MB &lt;-- After we add 1 million elements\n</span><span id=\"__span-2-3\"><a id=\"__codelineno-2-3\" name=\"__codelineno-2-3\" href=\"#__codelineno-2-3\"></a>293 MB &lt;-- After we remove 1 million elements\n</span></code></pre></div>\n<p>What can we observe? At first, the heap size is minimal. Then it grows significantly after having added 1 million elements to the map. But if we expected the heap size to decrease after removing all the elements, this isn’t how maps work in Go. In the end, even though the <abbr title=\"Garbage Collector\">GC</abbr> has collected all the elements, the heap size is still 293 MB. So the memory shrunk, but not as we might have expected. What’s the rationale? We need to delve into how a map works in Go.</p>\n<p>A map provides an unordered collection of key-value pairs in which all the keys are distinct. In Go, a map is based on the hash table data structure: an array where each element is a pointer to a bucket of key-value pairs, as shown in figure 1.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/map-leak-1.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/map-leak-1.png\"></a>\n  </p>\n<figcaption>Figure 1: A hash table example with a focus on bucket 0.</figcaption>\n</figure>\n<p>Each bucket is a fixed-size array of eight elements. In the case of an insertion into a bucket that is already full (a bucket overflow), Go creates another bucket of eight elements and links the previous one to it. Figure 2 shows an example:</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/map-leak-2.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/map-leak-2.png\"></a>\n  </p>\n<figcaption>Figure 2: In case of a bucket overflow, Go allocates a new bucket and links the previous bucket to it.</figcaption>\n</figure>\n<p>Under the hood, a Go map is a pointer to a <a href=\"https://github.com/golang/go/blob/0262ea1ff9ac3b9fd268a48fcaaa6811c20cbea2/src/runtime/map.go#L117-L131\">runtime.hmap</a> struct. This struct contains multiple fields, including a B field, giving the number of buckets in the map:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-3-1\"><a id=\"__codelineno-3-1\" name=\"__codelineno-3-1\" href=\"#__codelineno-3-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">hmap</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-3-2\"><a id=\"__codelineno-3-2\" name=\"__codelineno-3-2\" href=\"#__codelineno-3-2\"></a><span class=\"w\">    </span><span class=\"nx\">B</span><span class=\"w\"> </span><span class=\"kt\">uint8</span><span class=\"w\"> </span><span class=\"c1\">// log_2 of # of buckets</span>\n</span><span id=\"__span-3-3\"><a id=\"__codelineno-3-3\" name=\"__codelineno-3-3\" href=\"#__codelineno-3-3\"></a><span class=\"w\">            </span><span class=\"c1\">// (can hold up to loadFactor * 2^B items)</span>\n</span><span id=\"__span-3-4\"><a id=\"__codelineno-3-4\" name=\"__codelineno-3-4\" href=\"#__codelineno-3-4\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-3-5\"><a id=\"__codelineno-3-5\" name=\"__codelineno-3-5\" href=\"#__codelineno-3-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>After adding 1 million elements, the value of B equals 18, which means 2¹⁸ = 262,144 buckets. When we remove 1 million elements, what’s the value of B? Still 18. Hence, the map still contains the same number of buckets.</p>\n<p>The reason is that the number of buckets in a map cannot shrink. Therefore, removing elements from a map doesn’t impact the number of existing buckets; it just zeroes the slots in the buckets. A map can only grow and have more buckets; it never shrinks.</p>\n<p>In the previous example, we went from 461 MB to 293 MB because the elements were collected, but running the <abbr title=\"Garbage Collector\">GC</abbr> didn’t impact the map itself. Even the number of extra buckets (the buckets created because of overflows) remains the same.</p>\n<p>Let’s take a step back and discuss when the fact that a map cannot shrink can be a problem. Imagine building a cache using a <code>map[int][128]byte</code>. This map holds per customer ID (the <code>int</code>), a sequence of 128 bytes. Now, suppose we want to save the last 1,000 customers. The map size will remain constant, so we shouldn’t worry about the fact that a map cannot shrink.</p>\n<p>However, let’s say we want to store one hour of data. Meanwhile, our company has decided to have a big promotion for Black Friday: in one hour, we may have millions of customers connected to our system. But a few days after Black Friday, our map will contain the same number of buckets as during the peak time. This explains why we can experience high memory consumption that doesn’t significantly decrease in such a scenario.</p>\n<p>What are the solutions if we don’t want to manually restart our service to clean the amount of memory consumed by the map? One solution could be to re-create a copy of the current map at a regular pace. For example, every hour, we can build a new map, copy all the elements, and release the previous one. The main drawback of this option is that following the copy and until the next garbage collection, we may consume twice the current memory for a short period.</p>\n<p>Another solution would be to change the map type to store an array pointer: <code>map[int]*[128]byte</code>. It doesn’t solve the fact that we will have a significant number of buckets; however, each bucket entry will reserve the size of a pointer for the value instead of 128 bytes (8 bytes on 64-bit systems and 4 bytes on 32-bit systems).</p>\n<p>Coming back to the original scenario, let’s compare the memory consumption for each map type following each step. The following table shows the comparison.</p>\n<table>\n<thead>\n<tr>\n<th>Step</th>\n<th><code>map[int][128]byte</code></th>\n<th><code>map[int]*[128]byte</code></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Allocate an empty map</td>\n<td>0 MB</td>\n<td>0 MB</td>\n</tr>\n<tr>\n<td>Add 1 million elements</td>\n<td>461 MB</td>\n<td>182 MB</td>\n</tr>\n<tr>\n<td>Remove all the elements and run a <abbr title=\"Garbage Collector\">GC</abbr></td>\n<td>293 MB</td>\n<td>38 MB</td>\n</tr>\n</tbody>\n</table>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>If a key or a value is over 128 bytes, Go won’t store it directly in the map bucket. Instead, Go stores a pointer to reference the key or the value.</p>\n</details>\n<p>As we have seen, adding n elements to a map and then deleting all the elements means keeping the same number of buckets in memory. So, we must remember that because a Go map can only grow in size, so does its memory consumption. There is no automated strategy to shrink it. If this leads to high memory consumption, we can try different options such as forcing Go to re-create the map or using pointers to check if it can be optimized.</p>\n\n\n\n\n\n\n\n  \n  \n\n\n\n  \n\n\n  \n\n\n\n<h2 id=\"__comments\">Comments</h2>\n<!-- Insert generated snippet here -->\n<script src=\"https://giscus.app/client.js\" data-repo=\"teivah/100-go-mistakes\" data-repo-id=\"MDEwOlJlcG9zaXRvcnkzMjA4MTg5NjI=\" data-category=\"Discussions\" data-category-id=\"DIC_kwDOEx9PEs4CZQUm\" data-mapping=\"pathname\" data-strict=\"0\" data-reactions-enabled=\"1\" data-emit-metadata=\"0\" data-input-position=\"bottom\" data-theme=\"preferred_color_scheme\" data-lang=\"en\" crossorigin=\"anonymous\" async>\n</script>\n<!-- Synchronize Giscus theme with palette -->\n<script>\n  var giscus = document.querySelector(\"script[src*=giscus]\")\n\n  // Set palette on initial load\n  var palette = __md_get(\"__palette\")\n  if (palette && typeof palette.color === \"object\") {\n    var theme = palette.color.scheme === \"slate\"\n        ? \"transparent_dark\"\n        : \"light\"\n\n    // Instruct Giscus to set theme\n    giscus.setAttribute(\"data-theme\", theme)\n  }\n\n  // Register event handlers after documented loaded\n  document.addEventListener(\"DOMContentLoaded\", function() {\n    var ref = document.querySelector(\"[data-md-component=palette]\")\n    ref.addEventListener(\"change\", function() {\n      var palette = __md_get(\"__palette\")\n      if (palette && typeof palette.color === \"object\") {\n        var theme = palette.color.scheme === \"slate\"\n            ? \"transparent_dark\"\n            : \"light\"\n\n        // Instruct Giscus to change theme\n        var frame = document.querySelector(\".giscus-frame\")\n        frame.contentWindow.postMessage(\n            { giscus: { setConfig: { theme } } },\n            \"https://giscus.app\"\n        )\n      }\n    })\n  })\n</script>\n\n                \n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright © 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"></path></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \"..\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"../assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"../assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  \n<script id=\"init-glightbox\">const lightbox = GLightbox({\"touchNavigation\": true, \"loop\": false, \"zoomable\": true, \"draggable\": true, \"openEffect\": \"zoom\", \"closeEffect\": \"zoom\", \"slideEffect\": \"slide\"});\ndocument$.subscribe(()=>{ lightbox.reload(); });\n</script></body></html>"
  },
  {
    "path": "site/404.html",
    "content": "\n<!doctype html>\n<html lang=\"en\" class=\"no-js\">\n  <head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n      \n      \n      \n      \n      \n      <link rel=\"icon\" href=\"/img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"/assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"/assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"/stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\"/\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n    \n  </head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\"/.\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"/img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"/></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              \n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\"  aria-label=\"Switch to dark mode\"  type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"/></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\"  aria-label=\"Switch to light mode\"  type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"/></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"/></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"/></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"/></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"/></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"/></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"/></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"/.\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"/book/\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\" >\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\"/.\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"/img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"/></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1\" >\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"/.\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_2\" >\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"/5-interface-pollution/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"/9-generics/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"/20-slice/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"/28-maps-memory-leaks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"/56-concurrency-faster/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"/89-benchmarks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"/92-false-sharing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"/98-profiling-execution-tracing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_3\" >\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"/zh/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"/ja/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"/pt-br/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_2\" >\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"/book/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"/chapter-1/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"/external/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\" >\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n  <h1>404 - Not found</h1>\n\n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright &copy; 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"/></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \"/\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"/assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"/assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  </body>\n</html>"
  },
  {
    "path": "site/5-interface-pollution/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\" class=\"no-js\"><head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n      \n      \n        <link rel=\"canonical\" href=\"https://100go.co/5-interface-pollution/\">\n      \n      \n        <link rel=\"prev\" href=\"..\">\n      \n      \n        <link rel=\"next\" href=\"../9-generics/\">\n      \n      \n      <link rel=\"icon\" href=\"../img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>Interface pollution (#5) - 100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"../assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\"..\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n      \n        <meta property=\"og:type\" content=\"website\">\n      \n        <meta property=\"og:title\" content=\"Interface pollution (#5) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta property=\"og:description\" content=\"None\">\n      \n        <meta property=\"og:image\" content=\"https://100go.co/assets/images/social/5-interface-pollution.png\">\n      \n        <meta property=\"og:image:type\" content=\"image/png\">\n      \n        <meta property=\"og:image:width\" content=\"1200\">\n      \n        <meta property=\"og:image:height\" content=\"630\">\n      \n        <meta property=\"og:url\" content=\"https://100go.co/5-interface-pollution/\">\n      \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n      \n        <meta name=\"twitter:title\" content=\"Interface pollution (#5) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta name=\"twitter:description\" content=\"None\">\n      \n        <meta name=\"twitter:image\" content=\"https://100go.co/assets/images/social/5-interface-pollution.png\">\n      \n    \n    \n  <link href=\"../assets/stylesheets/glightbox.min.css\" rel=\"stylesheet\"><script src=\"../assets/javascripts/glightbox.min.js\"></script><style id=\"glightbox-style\">\n            html.glightbox-open { overflow: initial; height: 100%; }\n            .gslide-title { margin-top: 0px; user-select: text; }\n            .gslide-desc { color: #666; user-select: text; }\n            .gslide-image img { background: white; }\n            .gscrollbar-fixer { padding-right: 15px; }\n            .gdesc-inner { font-size: 0.75rem; }\n            body[data-md-color-scheme=\"slate\"] .gdesc-inner { background: var(--md-default-bg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-title { color: var(--md-default-fg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-desc { color: var(--md-default-fg-color); }\n        </style></head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n        \n        <a href=\"#interface-pollution\" class=\"md-skip\">\n          Skip to content\n        </a>\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"></path></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              Interface pollution (#5)\n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"></path></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"></path></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"></path></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n    \n  \n  \n    \n    \n      <li class=\"md-tabs__item md-tabs__item--active\">\n        <a href=\"..\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"../book/\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n        \n        \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"..\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1_2\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n    \n  \n  \n  \n    <li class=\"md-nav__item md-nav__item--active\">\n      \n      <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n      \n      \n        \n      \n      \n        <label class=\"md-nav__link md-nav__link--active\" for=\"__toc\">\n          \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n          <span class=\"md-nav__icon md-icon\"></span>\n        </label>\n      \n      <a href=\"./\" class=\"md-nav__link md-nav__link--active\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n      \n        \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#concepts\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Concepts\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#when-to-use-interfaces\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      When to use interfaces\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"When to use interfaces\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#common-behavior\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Common behavior\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#decoupling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Decoupling\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#restricting-behavior\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Restricting behavior\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#interface-pollution_1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Interface pollution\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../9-generics/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../20-slice/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../28-maps-memory-leaks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../56-concurrency-faster/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../89-benchmarks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../92-false-sharing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../98-profiling-execution-tracing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_3\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../zh/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../ja/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../pt-br/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../book/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../chapter-1/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../external/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\" hidden>\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#concepts\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Concepts\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#when-to-use-interfaces\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      When to use interfaces\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"When to use interfaces\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#common-behavior\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Common behavior\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#decoupling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Decoupling\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#restricting-behavior\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Restricting behavior\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#interface-pollution_1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Interface pollution\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n                  \n  \n\n\n\n  \n  \n\n\n<h1 id=\"interface-pollution\">Interface pollution</h1>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/interface-pollution.jpeg\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/interface-pollution.jpeg\"></a></p>\n<p>Interfaces are one of the cornerstones of the Go language when designing and structuring our code. However, like many tools or concepts, abusing them is generally not a good idea. Interface pollution is about overwhelming our code with unnecessary abstractions, making it harder to understand. It’s a common mistake made by developers coming from another language with different habits. Before delving into the topic, let’s refresh our minds about Go’s interfaces. Then, we will see when it’s appropriate to use interfaces and when it may be considered pollution.</p>\n<h2 id=\"concepts\">Concepts</h2>\n<p>An interface provides a way to specify the behavior of an object. We use interfaces to create common abstractions that multiple objects can implement. What makes Go interfaces so different is that they are satisfied implicitly. There is no explicit keyword like <code>implements</code> to mark that an object X implements interface Y.</p>\n<p>To understand what makes interfaces so powerful, we will dig into two popular ones from the standard library: <code>io.Reader</code> and <code>io.Writer</code>. The <code>io</code> package provides abstractions for I/O primitives. Among these abstractions, <code>io.Reader</code> relates to reading data from a data source and <code>io.Writer</code> to writing data to a target, as represented in the next figure:</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/ioreaderwriter.svg\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/ioreaderwriter.svg\"></a></p>\n</figure>\n<p>The <code>io.Reader</code> contains a single Read method:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-0-1\"><a id=\"__codelineno-0-1\" name=\"__codelineno-0-1\" href=\"#__codelineno-0-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Reader</span><span class=\"w\"> </span><span class=\"kd\">interface</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-0-2\"><a id=\"__codelineno-0-2\" name=\"__codelineno-0-2\" href=\"#__codelineno-0-2\"></a><span class=\"w\">    </span><span class=\"nx\">Read</span><span class=\"p\">(</span><span class=\"nx\">p</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">byte</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">n</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"p\">)</span>\n</span><span id=\"__span-0-3\"><a id=\"__codelineno-0-3\" name=\"__codelineno-0-3\" href=\"#__codelineno-0-3\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Custom implementations of the <code>io.Reader</code> interface should accept a slice of bytes, filling it with its data and returning either the number of bytes read or an error.</p>\n<p>On the other hand, <code>io.Writer</code> defines a single method, Write:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-1-1\"><a id=\"__codelineno-1-1\" name=\"__codelineno-1-1\" href=\"#__codelineno-1-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Writer</span><span class=\"w\"> </span><span class=\"kd\">interface</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-2\"><a id=\"__codelineno-1-2\" name=\"__codelineno-1-2\" href=\"#__codelineno-1-2\"></a><span class=\"w\">    </span><span class=\"nx\">Write</span><span class=\"p\">(</span><span class=\"nx\">p</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">byte</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">n</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"p\">)</span>\n</span><span id=\"__span-1-3\"><a id=\"__codelineno-1-3\" name=\"__codelineno-1-3\" href=\"#__codelineno-1-3\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Custom implementations of <code>io.Writer</code> should write the data coming from a slice to a target and return either the number of bytes written or an error. Therefore, both interfaces provide fundamental abstractions:</p>\n<ul>\n<li><code>io.Reader</code> reads data from a source</li>\n<li><code>io.Writer</code> writes data to a target</li>\n</ul>\n<p>What is the rationale for having these two interfaces in the language? What is the point of creating these abstractions?</p>\n<p>Let’s assume we need to implement a function that should copy the content of one file to another. We could create a specific function that would take as input two <code>*os.File</code>. Or, we can choose to create a more generic function using <code>io.Reader</code> and <code>io.Writer</code> abstractions:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-2-1\"><a id=\"__codelineno-2-1\" name=\"__codelineno-2-1\" href=\"#__codelineno-2-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">copySourceToDest</span><span class=\"p\">(</span><span class=\"nx\">source</span><span class=\"w\"> </span><span class=\"nx\">io</span><span class=\"p\">.</span><span class=\"nx\">Reader</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">dest</span><span class=\"w\"> </span><span class=\"nx\">io</span><span class=\"p\">.</span><span class=\"nx\">Writer</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-2-2\"><a id=\"__codelineno-2-2\" name=\"__codelineno-2-2\" href=\"#__codelineno-2-2\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-2-3\"><a id=\"__codelineno-2-3\" name=\"__codelineno-2-3\" href=\"#__codelineno-2-3\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>This function would work with <code>*os.File</code> parameters (as <code>*os.File</code> implements both <code>io.Reader</code> and <code>io.Writer</code>) and any other type that would implement these interfaces. For example, we could create our own <code>io.Writer</code> that writes to a database, and the code would remain the same. It increases the genericity of the function; hence, its reusability.</p>\n<p>Furthermore, writing a unit test for this function is easier because, instead of having to handle files, we can use the <code>strings</code> and <code>bytes</code> packages that provide helpful implementations:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-3-1\"><a id=\"__codelineno-3-1\" name=\"__codelineno-3-1\" href=\"#__codelineno-3-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">TestCopySourceToDest</span><span class=\"p\">(</span><span class=\"nx\">t</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">T</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-3-2\"><a id=\"__codelineno-3-2\" name=\"__codelineno-3-2\" href=\"#__codelineno-3-2\"></a><span class=\"w\">    </span><span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"nx\">input</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"s\">\"foo\"</span>\n</span><span id=\"__span-3-3\"><a id=\"__codelineno-3-3\" name=\"__codelineno-3-3\" href=\"#__codelineno-3-3\"></a><span class=\"w\">    </span><span class=\"nx\">source</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">strings</span><span class=\"p\">.</span><span class=\"nx\">NewReader</span><span class=\"p\">(</span><span class=\"nx\">input</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// Creates an io.Reader</span>\n</span><span id=\"__span-3-4\"><a id=\"__codelineno-3-4\" name=\"__codelineno-3-4\" href=\"#__codelineno-3-4\"></a><span class=\"w\">    </span><span class=\"nx\">dest</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">bytes</span><span class=\"p\">.</span><span class=\"nx\">NewBuffer</span><span class=\"p\">(</span><span class=\"nb\">make</span><span class=\"p\">([]</span><span class=\"kt\">byte</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">))</span><span class=\"w\"> </span><span class=\"c1\">// Creates an io.Writer</span>\n</span><span id=\"__span-3-5\"><a id=\"__codelineno-3-5\" name=\"__codelineno-3-5\" href=\"#__codelineno-3-5\"></a>\n</span><span id=\"__span-3-6\"><a id=\"__codelineno-3-6\" name=\"__codelineno-3-6\" href=\"#__codelineno-3-6\"></a><span class=\"w\">    </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">copySourceToDest</span><span class=\"p\">(</span><span class=\"nx\">source</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">dest</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// Calls copySourceToDest from a *strings.Reader and a *bytes.Buffer</span>\n</span><span id=\"__span-3-7\"><a id=\"__codelineno-3-7\" name=\"__codelineno-3-7\" href=\"#__codelineno-3-7\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-3-8\"><a id=\"__codelineno-3-8\" name=\"__codelineno-3-8\" href=\"#__codelineno-3-8\"></a><span class=\"w\">        </span><span class=\"nx\">t</span><span class=\"p\">.</span><span class=\"nx\">FailNow</span><span class=\"p\">()</span>\n</span><span id=\"__span-3-9\"><a id=\"__codelineno-3-9\" name=\"__codelineno-3-9\" href=\"#__codelineno-3-9\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-3-10\"><a id=\"__codelineno-3-10\" name=\"__codelineno-3-10\" href=\"#__codelineno-3-10\"></a>\n</span><span id=\"__span-3-11\"><a id=\"__codelineno-3-11\" name=\"__codelineno-3-11\" href=\"#__codelineno-3-11\"></a><span class=\"w\">    </span><span class=\"nx\">got</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">dest</span><span class=\"p\">.</span><span class=\"nx\">String</span><span class=\"p\">()</span>\n</span><span id=\"__span-3-12\"><a id=\"__codelineno-3-12\" name=\"__codelineno-3-12\" href=\"#__codelineno-3-12\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">got</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"nx\">input</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-3-13\"><a id=\"__codelineno-3-13\" name=\"__codelineno-3-13\" href=\"#__codelineno-3-13\"></a><span class=\"w\">        </span><span class=\"nx\">t</span><span class=\"p\">.</span><span class=\"nx\">Errorf</span><span class=\"p\">(</span><span class=\"s\">\"expected: %s, got: %s\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">input</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">got</span><span class=\"p\">)</span>\n</span><span id=\"__span-3-14\"><a id=\"__codelineno-3-14\" name=\"__codelineno-3-14\" href=\"#__codelineno-3-14\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-3-15\"><a id=\"__codelineno-3-15\" name=\"__codelineno-3-15\" href=\"#__codelineno-3-15\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>In the example, source is a <code>*strings.Reader</code>, whereas dest is a <code>*bytes.Buffer</code>. Here, we test the behavior of <code>copySourceToDest</code> without creating any files.</p>\n<p>While designing interfaces, the granularity (how many methods the interface contains) is also something to keep in mind. A <a href=\"https://www.youtube.com/watch?v=PAAkCSZUG1c&amp;t=318s\">known proverb</a> in Go relates to how big an interface should be:</p>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">Rob Pike</p>\n<p>The bigger the interface, the weaker the abstraction.</p>\n</div>\n<p>Indeed, adding methods to an interface can decrease its level of reusability. <code>io.Reader</code> and <code>io.Writer</code> are powerful abstractions because they cannot get any simpler. Furthermore, we can also combine fine-grained interfaces to create higher-level abstractions. This is the case with <code>io.ReadWriter</code>, which combines the reader and writer behaviors:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-4-1\"><a id=\"__codelineno-4-1\" name=\"__codelineno-4-1\" href=\"#__codelineno-4-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">ReadWriter</span><span class=\"w\"> </span><span class=\"kd\">interface</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-4-2\"><a id=\"__codelineno-4-2\" name=\"__codelineno-4-2\" href=\"#__codelineno-4-2\"></a><span class=\"w\">    </span><span class=\"nx\">Reader</span>\n</span><span id=\"__span-4-3\"><a id=\"__codelineno-4-3\" name=\"__codelineno-4-3\" href=\"#__codelineno-4-3\"></a><span class=\"w\">    </span><span class=\"nx\">Writer</span>\n</span><span id=\"__span-4-4\"><a id=\"__codelineno-4-4\" name=\"__codelineno-4-4\" href=\"#__codelineno-4-4\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>As Einstein said, “<em>Everything should be made as simple as possible, but no simpler.</em>” Applied to interfaces, this denotes that finding the perfect granularity for an interface isn’t necessarily a straightforward process.</p>\n</details>\n<p>Let’s now discuss common cases where interfaces are recommended.</p>\n<h2 id=\"when-to-use-interfaces\">When to use interfaces</h2>\n<p>When should we create interfaces in Go? Let’s look at three concrete use cases where interfaces are usually considered to bring value. Note that the goal isn’t to be exhaustive because the more cases we add, the more they would depend on the context. However, these three cases should give us a general idea:</p>\n<ul>\n<li>Common behavior </li>\n<li>Decoupling</li>\n<li>Restricting behavior</li>\n</ul>\n<h3 id=\"common-behavior\">Common behavior</h3>\n<p>The first option we will discuss is to use interfaces when multiple types implement a common behavior. In such a case, we can factor out the behavior inside an interface. If we look at the standard library, we can find many examples of such a use case. For example, sorting a collection can be factored out via three methods:</p>\n<ul>\n<li>Retrieving the number of elements in the collection</li>\n<li>Reporting whether one element must be sorted before another </li>\n<li>Swapping two elements</li>\n</ul>\n<p>Hence, the following interface was added to the <code>sort</code> package:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-5-1\"><a id=\"__codelineno-5-1\" name=\"__codelineno-5-1\" href=\"#__codelineno-5-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Interface</span><span class=\"w\"> </span><span class=\"kd\">interface</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-2\"><a id=\"__codelineno-5-2\" name=\"__codelineno-5-2\" href=\"#__codelineno-5-2\"></a><span class=\"w\">    </span><span class=\"nx\">Len</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"w\"> </span><span class=\"c1\">// Number of elements</span>\n</span><span id=\"__span-5-3\"><a id=\"__codelineno-5-3\" name=\"__codelineno-5-3\" href=\"#__codelineno-5-3\"></a><span class=\"w\">    </span><span class=\"nx\">Less</span><span class=\"p\">(</span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">j</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">bool</span><span class=\"w\"> </span><span class=\"c1\">// Checks two elements</span>\n</span><span id=\"__span-5-4\"><a id=\"__codelineno-5-4\" name=\"__codelineno-5-4\" href=\"#__codelineno-5-4\"></a><span class=\"w\">    </span><span class=\"nx\">Swap</span><span class=\"p\">(</span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">j</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// Swaps two elements</span>\n</span><span id=\"__span-5-5\"><a id=\"__codelineno-5-5\" name=\"__codelineno-5-5\" href=\"#__codelineno-5-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>This interface has a strong potential for reusability because it encompasses the common behavior to sort any collection that is index-based.</p>\n<p>Throughout the <code>sort</code> package, we can find dozens of implementations. If at some point we compute a collection of integers, for example, and we want to sort it, are we necessarily interested in the implementation type? Is it important whether the sorting algorithm is a merge sort or a quicksort? In many cases, we don’t care. Hence, the sorting behavior can be abstracted, and we can depend on the <code>sort.Interface</code>.</p>\n<p>Finding the right abstraction to factor out a behavior can also bring many benefits. For example, the <code>sort</code> package provides utility functions that also rely on <code>sort.Interface</code>, such as checking whether a collection is already sorted. For instance:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-6-1\"><a id=\"__codelineno-6-1\" name=\"__codelineno-6-1\" href=\"#__codelineno-6-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">IsSorted</span><span class=\"p\">(</span><span class=\"nx\">data</span><span class=\"w\"> </span><span class=\"nx\">Interface</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">bool</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-6-2\"><a id=\"__codelineno-6-2\" name=\"__codelineno-6-2\" href=\"#__codelineno-6-2\"></a><span class=\"w\">    </span><span class=\"nx\">n</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">Len</span><span class=\"p\">()</span>\n</span><span id=\"__span-6-3\"><a id=\"__codelineno-6-3\" name=\"__codelineno-6-3\" href=\"#__codelineno-6-3\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">n</span><span class=\"w\"> </span><span class=\"o\">-</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&gt;</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">--</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-6-4\"><a id=\"__codelineno-6-4\" name=\"__codelineno-6-4\" href=\"#__codelineno-6-4\"></a><span class=\"w\">        </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">Less</span><span class=\"p\">(</span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-6-5\"><a id=\"__codelineno-6-5\" name=\"__codelineno-6-5\" href=\"#__codelineno-6-5\"></a><span class=\"w\">            </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">false</span>\n</span><span id=\"__span-6-6\"><a id=\"__codelineno-6-6\" name=\"__codelineno-6-6\" href=\"#__codelineno-6-6\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-6-7\"><a id=\"__codelineno-6-7\" name=\"__codelineno-6-7\" href=\"#__codelineno-6-7\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-6-8\"><a id=\"__codelineno-6-8\" name=\"__codelineno-6-8\" href=\"#__codelineno-6-8\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">true</span>\n</span><span id=\"__span-6-9\"><a id=\"__codelineno-6-9\" name=\"__codelineno-6-9\" href=\"#__codelineno-6-9\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Because <code>sort.Interface</code> is the right level of abstraction, it makes it highly valuable.</p>\n<p>Let’s now see another main use case when using interfaces.</p>\n<h3 id=\"decoupling\">Decoupling</h3>\n<p>Another important use case is about decoupling our code from an implementation. If we rely on an abstraction instead of a concrete implementation, the implementation itself can be replaced with another without even having to change our code. This is the Liskov Substitution Principle (the L in Robert C. Martin’s <a href=\"https://en.wikipedia.org/wiki/SOLID\">SOLID</a> design principles).</p>\n<p>One benefit of decoupling can be related to unit testing. Let’s assume we want to implement a <code>CreateNewCustomer</code> method that creates a new customer and stores it. We decide to rely on the concrete implementation directly (let’s say a <code>mysql.Store</code> struct):</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-7-1\"><a id=\"__codelineno-7-1\" name=\"__codelineno-7-1\" href=\"#__codelineno-7-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">CustomerService</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-7-2\"><a id=\"__codelineno-7-2\" name=\"__codelineno-7-2\" href=\"#__codelineno-7-2\"></a><span class=\"w\">    </span><span class=\"nx\">store</span><span class=\"w\"> </span><span class=\"nx\">mysql</span><span class=\"p\">.</span><span class=\"nx\">Store</span><span class=\"w\"> </span><span class=\"c1\">// Depends on the concrete implementation</span>\n</span><span id=\"__span-7-3\"><a id=\"__codelineno-7-3\" name=\"__codelineno-7-3\" href=\"#__codelineno-7-3\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-7-4\"><a id=\"__codelineno-7-4\" name=\"__codelineno-7-4\" href=\"#__codelineno-7-4\"></a>\n</span><span id=\"__span-7-5\"><a id=\"__codelineno-7-5\" name=\"__codelineno-7-5\" href=\"#__codelineno-7-5\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">cs</span><span class=\"w\"> </span><span class=\"nx\">CustomerService</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">CreateNewCustomer</span><span class=\"p\">(</span><span class=\"nx\">id</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-7-6\"><a id=\"__codelineno-7-6\" name=\"__codelineno-7-6\" href=\"#__codelineno-7-6\"></a><span class=\"w\">    </span><span class=\"nx\">customer</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">Customer</span><span class=\"p\">{</span><span class=\"nx\">id</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"nx\">id</span><span class=\"p\">}</span>\n</span><span id=\"__span-7-7\"><a id=\"__codelineno-7-7\" name=\"__codelineno-7-7\" href=\"#__codelineno-7-7\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">cs</span><span class=\"p\">.</span><span class=\"nx\">store</span><span class=\"p\">.</span><span class=\"nx\">StoreCustomer</span><span class=\"p\">(</span><span class=\"nx\">customer</span><span class=\"p\">)</span>\n</span><span id=\"__span-7-8\"><a id=\"__codelineno-7-8\" name=\"__codelineno-7-8\" href=\"#__codelineno-7-8\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Now, what if we want to test this method? Because <code>customerService</code> relies on the actual implementation to store a <code>Customer</code>, we are obliged to test it through integration tests, which requires spinning up a MySQL instance (unless we use an alternative technique such as <a href=\"https://github.com/DATA-DOG/go-sqlmock\"><code>go-sqlmock</code></a>, but this isn’t the scope of this section). Although integration tests are helpful, that’s not always what we want to do. To give us more flexibility, we should decouple <code>CustomerService</code> from the actual implementation, which can be done via an interface like so:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-8-1\"><a id=\"__codelineno-8-1\" name=\"__codelineno-8-1\" href=\"#__codelineno-8-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">customerStorer</span><span class=\"w\"> </span><span class=\"kd\">interface</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Creates a storage abstraction</span>\n</span><span id=\"__span-8-2\"><a id=\"__codelineno-8-2\" name=\"__codelineno-8-2\" href=\"#__codelineno-8-2\"></a><span class=\"w\">    </span><span class=\"nx\">StoreCustomer</span><span class=\"p\">(</span><span class=\"nx\">Customer</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span>\n</span><span id=\"__span-8-3\"><a id=\"__codelineno-8-3\" name=\"__codelineno-8-3\" href=\"#__codelineno-8-3\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-8-4\"><a id=\"__codelineno-8-4\" name=\"__codelineno-8-4\" href=\"#__codelineno-8-4\"></a>\n</span><span id=\"__span-8-5\"><a id=\"__codelineno-8-5\" name=\"__codelineno-8-5\" href=\"#__codelineno-8-5\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">CustomerService</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-8-6\"><a id=\"__codelineno-8-6\" name=\"__codelineno-8-6\" href=\"#__codelineno-8-6\"></a><span class=\"w\">    </span><span class=\"nx\">storer</span><span class=\"w\"> </span><span class=\"nx\">customerStorer</span><span class=\"w\"> </span><span class=\"c1\">// Decouples CustomerService from the actual implementation</span>\n</span><span id=\"__span-8-7\"><a id=\"__codelineno-8-7\" name=\"__codelineno-8-7\" href=\"#__codelineno-8-7\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-8-8\"><a id=\"__codelineno-8-8\" name=\"__codelineno-8-8\" href=\"#__codelineno-8-8\"></a>\n</span><span id=\"__span-8-9\"><a id=\"__codelineno-8-9\" name=\"__codelineno-8-9\" href=\"#__codelineno-8-9\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">cs</span><span class=\"w\"> </span><span class=\"nx\">CustomerService</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">CreateNewCustomer</span><span class=\"p\">(</span><span class=\"nx\">id</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-8-10\"><a id=\"__codelineno-8-10\" name=\"__codelineno-8-10\" href=\"#__codelineno-8-10\"></a><span class=\"w\">    </span><span class=\"nx\">customer</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">Customer</span><span class=\"p\">{</span><span class=\"nx\">id</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"nx\">id</span><span class=\"p\">}</span>\n</span><span id=\"__span-8-11\"><a id=\"__codelineno-8-11\" name=\"__codelineno-8-11\" href=\"#__codelineno-8-11\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">cs</span><span class=\"p\">.</span><span class=\"nx\">storer</span><span class=\"p\">.</span><span class=\"nx\">StoreCustomer</span><span class=\"p\">(</span><span class=\"nx\">customer</span><span class=\"p\">)</span>\n</span><span id=\"__span-8-12\"><a id=\"__codelineno-8-12\" name=\"__codelineno-8-12\" href=\"#__codelineno-8-12\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Because storing a customer is now done via an interface, this gives us more flexibility in how we want to test the method. For instance, we can:</p>\n<ul>\n<li>Use the concrete implementation via integration tests </li>\n<li>Use a mock (or any kind of test double) via unit tests </li>\n<li>Or both</li>\n</ul>\n<p>Let’s now discuss another use case: to restrict a behavior.</p>\n<h3 id=\"restricting-behavior\">Restricting behavior</h3>\n<p>The last use case we will discuss can be pretty counterintuitive at first sight. It’s about restricting a type to a specific behavior. Let’s imagine we implement a custom configuration package to deal with dynamic configuration. We create a specific container for <code>int</code> configurations via an <code>IntConfig</code> struct that also exposes two methods: <code>Get</code> and <code>Set</code>. Here’s how that code would look:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-9-1\"><a id=\"__codelineno-9-1\" name=\"__codelineno-9-1\" href=\"#__codelineno-9-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">IntConfig</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-9-2\"><a id=\"__codelineno-9-2\" name=\"__codelineno-9-2\" href=\"#__codelineno-9-2\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-9-3\"><a id=\"__codelineno-9-3\" name=\"__codelineno-9-3\" href=\"#__codelineno-9-3\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-9-4\"><a id=\"__codelineno-9-4\" name=\"__codelineno-9-4\" href=\"#__codelineno-9-4\"></a>\n</span><span id=\"__span-9-5\"><a id=\"__codelineno-9-5\" name=\"__codelineno-9-5\" href=\"#__codelineno-9-5\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">IntConfig</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">Get</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-9-6\"><a id=\"__codelineno-9-6\" name=\"__codelineno-9-6\" href=\"#__codelineno-9-6\"></a><span class=\"w\">    </span><span class=\"c1\">// Retrieve configuration</span>\n</span><span id=\"__span-9-7\"><a id=\"__codelineno-9-7\" name=\"__codelineno-9-7\" href=\"#__codelineno-9-7\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-9-8\"><a id=\"__codelineno-9-8\" name=\"__codelineno-9-8\" href=\"#__codelineno-9-8\"></a>\n</span><span id=\"__span-9-9\"><a id=\"__codelineno-9-9\" name=\"__codelineno-9-9\" href=\"#__codelineno-9-9\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">IntConfig</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">Set</span><span class=\"p\">(</span><span class=\"nx\">value</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-9-10\"><a id=\"__codelineno-9-10\" name=\"__codelineno-9-10\" href=\"#__codelineno-9-10\"></a><span class=\"w\">    </span><span class=\"c1\">// Update configuration</span>\n</span><span id=\"__span-9-11\"><a id=\"__codelineno-9-11\" name=\"__codelineno-9-11\" href=\"#__codelineno-9-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Now, suppose we receive an <code>IntConfig</code> that holds some specific configuration, such as a threshold. Yet, in our code, we are only interested in retrieving the configuration value, and we want to prevent updating it. How can we enforce that, semantically, this configuration is read-only, if we don’t want to change our configuration package? By creating an abstraction that restricts the behavior to retrieving only a config value:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-10-1\"><a id=\"__codelineno-10-1\" name=\"__codelineno-10-1\" href=\"#__codelineno-10-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">intConfigGetter</span><span class=\"w\"> </span><span class=\"kd\">interface</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-10-2\"><a id=\"__codelineno-10-2\" name=\"__codelineno-10-2\" href=\"#__codelineno-10-2\"></a><span class=\"w\">    </span><span class=\"nx\">Get</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">int</span>\n</span><span id=\"__span-10-3\"><a id=\"__codelineno-10-3\" name=\"__codelineno-10-3\" href=\"#__codelineno-10-3\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Then, in our code, we can rely on <code>intConfigGetter</code> instead of the concrete implementation:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-11-1\"><a id=\"__codelineno-11-1\" name=\"__codelineno-11-1\" href=\"#__codelineno-11-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Foo</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-11-2\"><a id=\"__codelineno-11-2\" name=\"__codelineno-11-2\" href=\"#__codelineno-11-2\"></a><span class=\"w\">    </span><span class=\"nx\">threshold</span><span class=\"w\"> </span><span class=\"nx\">intConfigGetter</span>\n</span><span id=\"__span-11-3\"><a id=\"__codelineno-11-3\" name=\"__codelineno-11-3\" href=\"#__codelineno-11-3\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-11-4\"><a id=\"__codelineno-11-4\" name=\"__codelineno-11-4\" href=\"#__codelineno-11-4\"></a>\n</span><span id=\"__span-11-5\"><a id=\"__codelineno-11-5\" name=\"__codelineno-11-5\" href=\"#__codelineno-11-5\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">NewFoo</span><span class=\"p\">(</span><span class=\"nx\">threshold</span><span class=\"w\"> </span><span class=\"nx\">intConfigGetter</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">Foo</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Injects the configuration getter</span>\n</span><span id=\"__span-11-6\"><a id=\"__codelineno-11-6\" name=\"__codelineno-11-6\" href=\"#__codelineno-11-6\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">Foo</span><span class=\"p\">{</span><span class=\"nx\">threshold</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"nx\">threshold</span><span class=\"p\">}</span>\n</span><span id=\"__span-11-7\"><a id=\"__codelineno-11-7\" name=\"__codelineno-11-7\" href=\"#__codelineno-11-7\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-11-8\"><a id=\"__codelineno-11-8\" name=\"__codelineno-11-8\" href=\"#__codelineno-11-8\"></a>\n</span><span id=\"__span-11-9\"><a id=\"__codelineno-11-9\" name=\"__codelineno-11-9\" href=\"#__codelineno-11-9\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">f</span><span class=\"w\"> </span><span class=\"nx\">Foo</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">Bar</span><span class=\"p\">()</span><span class=\"w\">  </span><span class=\"p\">{</span>\n</span><span id=\"__span-11-10\"><a id=\"__codelineno-11-10\" name=\"__codelineno-11-10\" href=\"#__codelineno-11-10\"></a><span class=\"w\">    </span><span class=\"nx\">threshold</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">.</span><span class=\"nx\">threshold</span><span class=\"p\">.</span><span class=\"nx\">Get</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// Reads the configuration</span>\n</span><span id=\"__span-11-11\"><a id=\"__codelineno-11-11\" name=\"__codelineno-11-11\" href=\"#__codelineno-11-11\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-11-12\"><a id=\"__codelineno-11-12\" name=\"__codelineno-11-12\" href=\"#__codelineno-11-12\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>In this example, the configuration getter is injected into the <code>NewFoo</code> factory method. It doesn’t impact a client of this function because it can still pass an <code>IntConfig</code> struct as it implements <code>intConfigGetter</code>. Then, we can only read the configuration in the <code>Bar</code> method, not modify it. Therefore, we can also use interfaces to restrict a type to a specific behavior for various reasons, such as semantics enforcement.</p>\n<p>In this section, we saw three potential use cases where interfaces are generally considered as bringing value: factoring out a common behavior, creating some decoupling, and restricting a type to a certain behavior. Again, this list isn’t exhaustive, but it should give us a general understanding of when interfaces are helpful in Go.</p>\n<p>Now, let’s finish this section and discuss the problems with interface pollution.</p>\n<h2 id=\"interface-pollution_1\">Interface pollution</h2>\n<p>It’s fairly common to see interfaces being overused in Go projects. Perhaps the developer’s background was C# or Java, and they found it natural to create interfaces before concrete types. However, this isn’t how things should work in Go.</p>\n<p>As we discussed, interfaces are made to create abstractions. And the main caveat when programming meets abstractions is remembering that <strong>abstractions should be discovered, not created</strong>. What does this mean? It means we shouldn’t start creating abstractions in our code if there is no immediate reason to do so. We shouldn’t design with interfaces but wait for a concrete need. Said differently, we should create an interface when we need it, not when we foresee that we could need it.</p>\n<p>What’s the main problem if we overuse interfaces? The answer is that they make the code flow more complex. Adding a useless level of indirection doesn’t bring any value; it creates a worthless abstraction making the code more difficult to read, understand, and reason about. If we don’t have a strong reason for adding an interface and it’s unclear how an interface makes a code better, we should challenge this interface’s purpose. Why not call the implementation directly?</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>We may also experience performance overhead when calling a method through an interface. It requires a lookup in a hash table’s data structure to find the concrete type an interface points to. But this isn’t an issue in many contexts as the overhead is minimal.</p>\n</details>\n<p>In summary, we should be cautious when creating abstractions in our code—abstractions should be discovered, not created. It’s common for us, software developers, to overengineer our code by trying to guess what the perfect level of abstraction is, based on what we think we might need later. This process should be avoided because, in most cases, it pollutes our code with unnecessary abstractions, making it more complex to read.</p>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">Rob Pike</p>\n<p>Don’t design with interfaces, discover them.</p>\n</div>\n<p>Let’s not try to solve a problem abstractly but solve what has to be solved now. Last, but not least, if it’s unclear how an interface makes the code better, we should probably consider removing it to make our code simpler.</p>\n\n\n\n\n\n\n\n  \n  \n\n\n\n  \n\n\n  \n\n\n\n<h2 id=\"__comments\">Comments</h2>\n<!-- Insert generated snippet here -->\n<script src=\"https://giscus.app/client.js\" data-repo=\"teivah/100-go-mistakes\" data-repo-id=\"MDEwOlJlcG9zaXRvcnkzMjA4MTg5NjI=\" data-category=\"Discussions\" data-category-id=\"DIC_kwDOEx9PEs4CZQUm\" data-mapping=\"pathname\" data-strict=\"0\" data-reactions-enabled=\"1\" data-emit-metadata=\"0\" data-input-position=\"bottom\" data-theme=\"preferred_color_scheme\" data-lang=\"en\" crossorigin=\"anonymous\" async>\n</script>\n<!-- Synchronize Giscus theme with palette -->\n<script>\n  var giscus = document.querySelector(\"script[src*=giscus]\")\n\n  // Set palette on initial load\n  var palette = __md_get(\"__palette\")\n  if (palette && typeof palette.color === \"object\") {\n    var theme = palette.color.scheme === \"slate\"\n        ? \"transparent_dark\"\n        : \"light\"\n\n    // Instruct Giscus to set theme\n    giscus.setAttribute(\"data-theme\", theme)\n  }\n\n  // Register event handlers after documented loaded\n  document.addEventListener(\"DOMContentLoaded\", function() {\n    var ref = document.querySelector(\"[data-md-component=palette]\")\n    ref.addEventListener(\"change\", function() {\n      var palette = __md_get(\"__palette\")\n      if (palette && typeof palette.color === \"object\") {\n        var theme = palette.color.scheme === \"slate\"\n            ? \"transparent_dark\"\n            : \"light\"\n\n        // Instruct Giscus to change theme\n        var frame = document.querySelector(\".giscus-frame\")\n        frame.contentWindow.postMessage(\n            { giscus: { setConfig: { theme } } },\n            \"https://giscus.app\"\n        )\n      }\n    })\n  })\n</script>\n\n                \n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright © 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"></path></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \"..\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"../assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"../assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  \n<script id=\"init-glightbox\">const lightbox = GLightbox({\"touchNavigation\": true, \"loop\": false, \"zoomable\": true, \"draggable\": true, \"openEffect\": \"zoom\", \"closeEffect\": \"zoom\", \"slideEffect\": \"slide\"});\ndocument$.subscribe(()=>{ lightbox.reload(); });\n</script></body></html>"
  },
  {
    "path": "site/56-concurrency-faster/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\" class=\"no-js\"><head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n      \n      \n        <link rel=\"canonical\" href=\"https://100go.co/56-concurrency-faster/\">\n      \n      \n        <link rel=\"prev\" href=\"../28-maps-memory-leaks/\">\n      \n      \n        <link rel=\"next\" href=\"../89-benchmarks/\">\n      \n      \n      <link rel=\"icon\" href=\"../img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>Thinking concurrency is always faster (#56) - 100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"../assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\"..\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n      \n        <meta property=\"og:type\" content=\"website\">\n      \n        <meta property=\"og:title\" content=\"Thinking concurrency is always faster (#56) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta property=\"og:description\" content=\"None\">\n      \n        <meta property=\"og:image\" content=\"https://100go.co/assets/images/social/56-concurrency-faster.png\">\n      \n        <meta property=\"og:image:type\" content=\"image/png\">\n      \n        <meta property=\"og:image:width\" content=\"1200\">\n      \n        <meta property=\"og:image:height\" content=\"630\">\n      \n        <meta property=\"og:url\" content=\"https://100go.co/56-concurrency-faster/\">\n      \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n      \n        <meta name=\"twitter:title\" content=\"Thinking concurrency is always faster (#56) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta name=\"twitter:description\" content=\"None\">\n      \n        <meta name=\"twitter:image\" content=\"https://100go.co/assets/images/social/56-concurrency-faster.png\">\n      \n    \n    \n  <link href=\"../assets/stylesheets/glightbox.min.css\" rel=\"stylesheet\"><script src=\"../assets/javascripts/glightbox.min.js\"></script><style id=\"glightbox-style\">\n            html.glightbox-open { overflow: initial; height: 100%; }\n            .gslide-title { margin-top: 0px; user-select: text; }\n            .gslide-desc { color: #666; user-select: text; }\n            .gslide-image img { background: white; }\n            .gscrollbar-fixer { padding-right: 15px; }\n            .gdesc-inner { font-size: 0.75rem; }\n            body[data-md-color-scheme=\"slate\"] .gdesc-inner { background: var(--md-default-bg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-title { color: var(--md-default-fg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-desc { color: var(--md-default-fg-color); }\n        </style></head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n        \n        <a href=\"#thinking-concurrency-is-always-faster\" class=\"md-skip\">\n          Skip to content\n        </a>\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"></path></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              Thinking concurrency is always faster (#56)\n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"></path></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"></path></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"></path></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n    \n  \n  \n    \n    \n      <li class=\"md-tabs__item md-tabs__item--active\">\n        <a href=\"..\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"../book/\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n        \n        \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"..\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1_2\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../5-interface-pollution/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../9-generics/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../20-slice/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../28-maps-memory-leaks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    <li class=\"md-nav__item md-nav__item--active\">\n      \n      <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n      \n      \n        \n      \n      \n        <label class=\"md-nav__link md-nav__link--active\" for=\"__toc\">\n          \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n          <span class=\"md-nav__icon md-icon\"></span>\n        </label>\n      \n      <a href=\"./\" class=\"md-nav__link md-nav__link--active\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n      \n        \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#go-scheduling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Go Scheduling\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#parallel-merge-sort\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Parallel Merge Sort\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#conclusion\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Conclusion\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../89-benchmarks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../92-false-sharing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../98-profiling-execution-tracing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_3\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../zh/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../ja/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../pt-br/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../book/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../chapter-1/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../external/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\" hidden>\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#go-scheduling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Go Scheduling\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#parallel-merge-sort\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Parallel Merge Sort\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#conclusion\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Conclusion\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n                  \n  \n\n\n\n  \n  \n\n\n<h1 id=\"thinking-concurrency-is-always-faster\">Thinking concurrency is always faster</h1>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/56-concurrency-faster.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/56-concurrency-faster.png\"></a></p>\n<p>A misconception among many developers is believing that a concurrent solution is always faster than a sequential one. This couldn’t be more wrong. The overall performance of a solution depends on many factors, such as the efficiency of our code structure (concurrency), which parts can be tackled in parallel, and the level of contention among the computation units. This post reminds us about some fundamental knowledge of concurrency in Go; then we will see a concrete example where a concurrent solution isn’t necessarily faster.</p>\n<h2 id=\"go-scheduling\">Go Scheduling</h2>\n<p>A thread is the smallest unit of processing that an OS can perform. If a process wants to execute multiple actions simultaneously, it spins up multiple threads. These threads can be:</p>\n<ul>\n<li><em>Concurrent</em> — Two or more threads can start, run, and complete in overlapping time periods.</li>\n<li><em>Parallel</em> — The same task can be executed multiple times at once.</li>\n</ul>\n<p>The OS is responsible for scheduling the thread’s processes optimally so that:</p>\n<ul>\n<li>All the threads can consume CPU cycles without being starved for too much time.</li>\n<li>The workload is distributed as evenly as possible among the different CPU cores.</li>\n</ul>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>The word thread can also have a different meaning at a CPU level. Each physical core can be composed of multiple logical cores (the concept of <a href=\"https://en.wikipedia.org/wiki/Hyper-threading\">hyper-threading</a>), and a logical core is also called a thread. In this post, when we use the word thread, we mean the unit of processing, not a logical core.</p>\n</details>\n<p>A CPU core executes different threads. When it switches from one thread to another, it executes an operation called <em>context switching</em>. The active thread consuming CPU cycles was in an <em>executing</em> state and moves to a <em>runnable</em> state, meaning it’s ready to be executed pending an available core. Context switching is considered an expensive operation because the OS needs to save the current execution state of a thread before the switch (such as the current register values).</p>\n<p>As Go developers, we can’t create threads directly, but we can create goroutines, which can be thought of as application-level threads. However, whereas an OS thread is context-switched on and off a CPU core by the OS, a goroutine is context-switched on and off an OS thread by the Go runtime. Also, compared to an OS thread, a goroutine has a smaller memory footprint: 2 KB for goroutines from Go 1.4. An OS thread depends on the OS, but, for example, on Linux/x86–32, the default size is 2 MB (see https://man7.org/linux/man-pages/man3/pthread_create.3.html). Having a smaller size makes context switching faster.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>Context switching a goroutine versus a thread is about 80% to 90% faster, depending on the architecture.</p>\n</details>\n<p>Let’s now discuss how the Go scheduler works to overview how goroutines are handled. Internally, the Go scheduler uses the following terminology (see <a href=\"https://github.com/golang/go/blob/go1.17.6/src/runtime/proc.go#L22\">proc.go</a>):</p>\n<ul>\n<li><em>G</em> — Goroutine</li>\n<li><em>M</em> — OS thread (stands for machine)</li>\n<li><em>P</em> — CPU core (stands for processor)</li>\n</ul>\n<p>Each OS thread (M) is assigned to a CPU core (P) by the OS scheduler. Then, each goroutine (G) runs on an M. The <abbr title=\"The variable defines the limit of OS threads in charge of executing user-level code simultaneously\">GOMAXPROCS</abbr> variable defines the limit of Ms in charge of executing user-level code simultaneously. But if a thread is blocked in a system call (for example, I/O), the scheduler can spin up more Ms. As of Go 1.5, <abbr title=\"The variable defines the limit of OS threads in charge of executing user-level code simultaneously\">GOMAXPROCS</abbr> is by default equal to the number of available CPU cores.</p>\n<p>A goroutine has a simpler lifecycle than an OS thread. It can be doing one of the following:</p>\n<ul>\n<li><em>Executing</em> — The goroutine is scheduled on an M and executing its instructions.</li>\n<li><em>Runnable</em> — The goroutine is waiting to be in an executing state.</li>\n<li><em>Waiting</em> — The goroutine is stopped and pending something completing, such as a system call or a synchronization operation (such as acquiring a mutex).</li>\n</ul>\n<p>There’s one last stage to understand about the implementation of Go scheduling: when a goroutine is created but cannot be executed yet; for example, all the other Ms are already executing a G. In this scenario, what will the Go runtime do about it? The answer is queuing. The Go runtime handles two kinds of queues: one local queue per P and a global queue shared among all the Ps.</p>\n<p>Figure 1 shows a given scheduling situation on a four-core machine with <abbr title=\"The variable defines the limit of OS threads in charge of executing user-level code simultaneously\">GOMAXPROCS</abbr> equal to 4. The parts are the logical cores (Ps), goroutines (Gs), OS threads (Ms), local queues, and global queue:</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/go-scheduler.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/go-scheduler.png\"></a>\n  </p>\n<figcaption>Figure 1: An example of the current state of a Go application executed on a four-core machine. Goroutines that aren’t in an executing state are either runnable (pending being executed) or waiting (pending a blocking operation)</figcaption>\n</figure>\n<p>First, we can see five Ms, whereas <abbr title=\"The variable defines the limit of OS threads in charge of executing user-level code simultaneously\">GOMAXPROCS</abbr> is set to 4. But as we mentioned, if needed, the Go runtime can create more OS threads than the <abbr title=\"The variable defines the limit of OS threads in charge of executing user-level code simultaneously\">GOMAXPROCS</abbr> value.</p>\n<p>P0, P1, and P3 are currently busy executing Go runtime threads. But P2 is presently idle as M3 is switched off P2, and there’s no goroutine to be executed. This isn’t a good situation because six runnable goroutines are pending being executed, some in the global queue and some in other local queues. How will the Go runtime handle this situation? Here’s the scheduling implementation in pseudocode (see <a href=\"https://github.com/golang/go/blob/go1.17.6/src/runtime/proc.go#L3291\">proc.go</a>):</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-0-1\"><a id=\"__codelineno-0-1\" name=\"__codelineno-0-1\" href=\"#__codelineno-0-1\"></a>runtime.schedule() {\n</span><span id=\"__span-0-2\"><a id=\"__codelineno-0-2\" name=\"__codelineno-0-2\" href=\"#__codelineno-0-2\"></a>    // Only 1/61 of the time, check the global runnable queue for a G.\n</span><span id=\"__span-0-3\"><a id=\"__codelineno-0-3\" name=\"__codelineno-0-3\" href=\"#__codelineno-0-3\"></a>    // If not found, check the local queue.\n</span><span id=\"__span-0-4\"><a id=\"__codelineno-0-4\" name=\"__codelineno-0-4\" href=\"#__codelineno-0-4\"></a>    // If not found,\n</span><span id=\"__span-0-5\"><a id=\"__codelineno-0-5\" name=\"__codelineno-0-5\" href=\"#__codelineno-0-5\"></a>    //     Try to steal from other Ps.\n</span><span id=\"__span-0-6\"><a id=\"__codelineno-0-6\" name=\"__codelineno-0-6\" href=\"#__codelineno-0-6\"></a>    //     If not, check the global runnable queue.\n</span><span id=\"__span-0-7\"><a id=\"__codelineno-0-7\" name=\"__codelineno-0-7\" href=\"#__codelineno-0-7\"></a>    //     If not found, poll network.\n</span><span id=\"__span-0-8\"><a id=\"__codelineno-0-8\" name=\"__codelineno-0-8\" href=\"#__codelineno-0-8\"></a>}\n</span></code></pre></div>\n<p>Every sixty-first execution, the Go scheduler will check whether goroutines from the global queue are available. If not, it will check its local queue. Meanwhile, if both the global and local queues are empty, the Go scheduler can pick up goroutines from other local queues. This principle in scheduling is called <em>work stealing</em>, and it allows an underutilized processor to actively look for another processor’s goroutines and <em>steal</em> some.</p>\n<p>One last important thing to mention: prior to Go 1.14, the scheduler was cooperative, which meant a goroutine could be context-switched off a thread only in specific blocking cases (for example, channel send or receive, I/O, waiting to acquire a mutex). Since Go 1.14, the Go scheduler is now preemptive: when a goroutine is running for a specific amount of time (10 ms), it will be marked preemptible and can be context-switched off to be replaced by another goroutine. This allows a long-running job to be forced to share CPU time.</p>\n<p>Now that we understand the fundamentals of scheduling in Go, let’s look at a concrete example: implementing a merge sort in a parallel manner.</p>\n<h2 id=\"parallel-merge-sort\">Parallel Merge Sort</h2>\n<p>First, let’s briefly review how the merge sort algorithm works. Then we will implement a parallel version. Note that the objective isn’t to implement the most efficient version but to support a concrete example showing why concurrency isn’t always faster.</p>\n<p>The merge sort algorithm works by breaking a list repeatedly into two sublists until each sublist consists of a single element and then merging these sublists so that the result is a sorted list (see figure 2). Each split operation splits the list into two sublists, whereas the merge operation merges two sublists into a sorted list.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/mergesort.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/mergesort.png\"></a>\n  </p>\n<figcaption>Figure 2: Applying the merge sort algorithm repeatedly breaks each list into two sublists. Then the algorithm uses a merge operation such that the resulting list is sorted</figcaption>\n</figure>\n<p>Here is the sequential implementation of this algorithm. We don’t include all of the code as it’s not the main point of this section:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-1-1\"><a id=\"__codelineno-1-1\" name=\"__codelineno-1-1\" href=\"#__codelineno-1-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">sequentialMergesort</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-2\"><a id=\"__codelineno-1-2\" name=\"__codelineno-1-2\" href=\"#__codelineno-1-2\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">&lt;=</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-3\"><a id=\"__codelineno-1-3\" name=\"__codelineno-1-3\" href=\"#__codelineno-1-3\"></a><span class=\"w\">        </span><span class=\"k\">return</span>\n</span><span id=\"__span-1-4\"><a id=\"__codelineno-1-4\" name=\"__codelineno-1-4\" href=\"#__codelineno-1-4\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-1-5\"><a id=\"__codelineno-1-5\" name=\"__codelineno-1-5\" href=\"#__codelineno-1-5\"></a>\n</span><span id=\"__span-1-6\"><a id=\"__codelineno-1-6\" name=\"__codelineno-1-6\" href=\"#__codelineno-1-6\"></a><span class=\"w\">    </span><span class=\"nx\">middle</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">/</span><span class=\"w\"> </span><span class=\"mi\">2</span>\n</span><span id=\"__span-1-7\"><a id=\"__codelineno-1-7\" name=\"__codelineno-1-7\" href=\"#__codelineno-1-7\"></a><span class=\"w\">    </span><span class=\"nx\">sequentialMergesort</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">[:</span><span class=\"nx\">middle</span><span class=\"p\">])</span><span class=\"w\"> </span><span class=\"c1\">// First half</span>\n</span><span id=\"__span-1-8\"><a id=\"__codelineno-1-8\" name=\"__codelineno-1-8\" href=\"#__codelineno-1-8\"></a><span class=\"w\">    </span><span class=\"nx\">sequentialMergesort</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">[</span><span class=\"nx\">middle</span><span class=\"p\">:])</span><span class=\"w\"> </span><span class=\"c1\">// Second half</span>\n</span><span id=\"__span-1-9\"><a id=\"__codelineno-1-9\" name=\"__codelineno-1-9\" href=\"#__codelineno-1-9\"></a><span class=\"w\">    </span><span class=\"nx\">merge</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">middle</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// Merges the two halves</span>\n</span><span id=\"__span-1-10\"><a id=\"__codelineno-1-10\" name=\"__codelineno-1-10\" href=\"#__codelineno-1-10\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-1-11\"><a id=\"__codelineno-1-11\" name=\"__codelineno-1-11\" href=\"#__codelineno-1-11\"></a>\n</span><span id=\"__span-1-12\"><a id=\"__codelineno-1-12\" name=\"__codelineno-1-12\" href=\"#__codelineno-1-12\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">merge</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">middle</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-13\"><a id=\"__codelineno-1-13\" name=\"__codelineno-1-13\" href=\"#__codelineno-1-13\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-1-14\"><a id=\"__codelineno-1-14\" name=\"__codelineno-1-14\" href=\"#__codelineno-1-14\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>This algorithm has a structure that makes it open to concurrency. Indeed, as each <em>sequentialMergesort</em> operation works on an independent set of data that doesn’t need to be fully copied (here, an independent view of the underlying array using slicing), we could distribute this workload among the CPU cores by spinning up each <em>sequentialMergesort</em> operation in a different goroutine. Let’s write a first parallel implementation:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-2-1\"><a id=\"__codelineno-2-1\" name=\"__codelineno-2-1\" href=\"#__codelineno-2-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">parallelMergesortV1</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-2-2\"><a id=\"__codelineno-2-2\" name=\"__codelineno-2-2\" href=\"#__codelineno-2-2\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">&lt;=</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-2-3\"><a id=\"__codelineno-2-3\" name=\"__codelineno-2-3\" href=\"#__codelineno-2-3\"></a><span class=\"w\">        </span><span class=\"k\">return</span>\n</span><span id=\"__span-2-4\"><a id=\"__codelineno-2-4\" name=\"__codelineno-2-4\" href=\"#__codelineno-2-4\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-2-5\"><a id=\"__codelineno-2-5\" name=\"__codelineno-2-5\" href=\"#__codelineno-2-5\"></a>\n</span><span id=\"__span-2-6\"><a id=\"__codelineno-2-6\" name=\"__codelineno-2-6\" href=\"#__codelineno-2-6\"></a><span class=\"w\">    </span><span class=\"nx\">middle</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">/</span><span class=\"w\"> </span><span class=\"mi\">2</span>\n</span><span id=\"__span-2-7\"><a id=\"__codelineno-2-7\" name=\"__codelineno-2-7\" href=\"#__codelineno-2-7\"></a>\n</span><span id=\"__span-2-8\"><a id=\"__codelineno-2-8\" name=\"__codelineno-2-8\" href=\"#__codelineno-2-8\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">wg</span><span class=\"w\"> </span><span class=\"nx\">sync</span><span class=\"p\">.</span><span class=\"nx\">WaitGroup</span>\n</span><span id=\"__span-2-9\"><a id=\"__codelineno-2-9\" name=\"__codelineno-2-9\" href=\"#__codelineno-2-9\"></a><span class=\"w\">    </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Add</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n</span><span id=\"__span-2-10\"><a id=\"__codelineno-2-10\" name=\"__codelineno-2-10\" href=\"#__codelineno-2-10\"></a>\n</span><span id=\"__span-2-11\"><a id=\"__codelineno-2-11\" name=\"__codelineno-2-11\" href=\"#__codelineno-2-11\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Spins up the first half of the work in a goroutine</span>\n</span><span id=\"__span-2-12\"><a id=\"__codelineno-2-12\" name=\"__codelineno-2-12\" href=\"#__codelineno-2-12\"></a><span class=\"w\">        </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Done</span><span class=\"p\">()</span>\n</span><span id=\"__span-2-13\"><a id=\"__codelineno-2-13\" name=\"__codelineno-2-13\" href=\"#__codelineno-2-13\"></a><span class=\"w\">        </span><span class=\"nx\">parallelMergesortV1</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">[:</span><span class=\"nx\">middle</span><span class=\"p\">])</span>\n</span><span id=\"__span-2-14\"><a id=\"__codelineno-2-14\" name=\"__codelineno-2-14\" href=\"#__codelineno-2-14\"></a><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span><span id=\"__span-2-15\"><a id=\"__codelineno-2-15\" name=\"__codelineno-2-15\" href=\"#__codelineno-2-15\"></a>\n</span><span id=\"__span-2-16\"><a id=\"__codelineno-2-16\" name=\"__codelineno-2-16\" href=\"#__codelineno-2-16\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Spins up the second half of the work in a goroutine</span>\n</span><span id=\"__span-2-17\"><a id=\"__codelineno-2-17\" name=\"__codelineno-2-17\" href=\"#__codelineno-2-17\"></a><span class=\"w\">        </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Done</span><span class=\"p\">()</span>\n</span><span id=\"__span-2-18\"><a id=\"__codelineno-2-18\" name=\"__codelineno-2-18\" href=\"#__codelineno-2-18\"></a><span class=\"w\">        </span><span class=\"nx\">parallelMergesortV1</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">[</span><span class=\"nx\">middle</span><span class=\"p\">:])</span>\n</span><span id=\"__span-2-19\"><a id=\"__codelineno-2-19\" name=\"__codelineno-2-19\" href=\"#__codelineno-2-19\"></a><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span><span id=\"__span-2-20\"><a id=\"__codelineno-2-20\" name=\"__codelineno-2-20\" href=\"#__codelineno-2-20\"></a>\n</span><span id=\"__span-2-21\"><a id=\"__codelineno-2-21\" name=\"__codelineno-2-21\" href=\"#__codelineno-2-21\"></a><span class=\"w\">    </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Wait</span><span class=\"p\">()</span>\n</span><span id=\"__span-2-22\"><a id=\"__codelineno-2-22\" name=\"__codelineno-2-22\" href=\"#__codelineno-2-22\"></a><span class=\"w\">    </span><span class=\"nx\">merge</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">middle</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// Merges the halves</span>\n</span><span id=\"__span-2-23\"><a id=\"__codelineno-2-23\" name=\"__codelineno-2-23\" href=\"#__codelineno-2-23\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>In this version, each half of the workload is handled in a separate goroutine. The parent goroutine waits for both parts by using <em>sync.WaitGroup</em>. Hence, we call the Wait method before the merge operation.</p>\n<p>We now have a parallel version of the merge sort algorithm. Therefore, if we run a benchmark to compare this version against the sequential one, the parallel version should be faster, correct? Let’s run it on a four-core machine with 10,000 elements:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-3-1\"><a id=\"__codelineno-3-1\" name=\"__codelineno-3-1\" href=\"#__codelineno-3-1\"></a>Benchmark_sequentialMergesort-4       2278993555 ns/op\n</span><span id=\"__span-3-2\"><a id=\"__codelineno-3-2\" name=\"__codelineno-3-2\" href=\"#__codelineno-3-2\"></a>Benchmark_parallelMergesortV1-4      17525998709 ns/op\n</span></code></pre></div>\n<p>Surprisingly, the parallel version is almost an order of magnitude slower. How can we explain this result? How is it possible that a parallel version that distributes a workload across four cores is slower than a sequential version running on a single machine? Let’s analyze the problem.</p>\n<p>If we have a slice of, say, 1,024 elements, the parent goroutine will spin up two goroutines, each in charge of handling a half consisting of 512 elements. Each of these goroutines will spin up two new goroutines in charge of handling 256 elements, then 128, and so on, until we spin up a goroutine to compute a single element.</p>\n<p>If the workload that we want to parallelize is too small, meaning we’re going to compute it too fast, the benefit of distributing a job across cores is destroyed: the time it takes to create a goroutine and have the scheduler execute it is much too high compared to directly merging a tiny number of items in the current goroutine. Although goroutines are lightweight and faster to start than threads, we can still face cases where a workload is too small.</p>\n<p>So what can we conclude from this result? Does it mean the merge sort algorithm cannot be parallelized? Wait, not so fast.</p>\n<p>Let’s try another approach. Because merging a tiny number of elements within a new goroutine isn’t efficient, let’s define a threshold. This threshold will represent how many elements a half should contain in order to be handled in a parallel manner. If the number of elements in the half is fewer than this value, we will handle it sequentially. Here’s a new version:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-4-1\"><a id=\"__codelineno-4-1\" name=\"__codelineno-4-1\" href=\"#__codelineno-4-1\"></a><span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"nx\">max</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"mi\">2048</span><span class=\"w\"> </span><span class=\"c1\">// Defines the threshold</span>\n</span><span id=\"__span-4-2\"><a id=\"__codelineno-4-2\" name=\"__codelineno-4-2\" href=\"#__codelineno-4-2\"></a>\n</span><span id=\"__span-4-3\"><a id=\"__codelineno-4-3\" name=\"__codelineno-4-3\" href=\"#__codelineno-4-3\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">parallelMergesortV2</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-4-4\"><a id=\"__codelineno-4-4\" name=\"__codelineno-4-4\" href=\"#__codelineno-4-4\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">&lt;=</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-4-5\"><a id=\"__codelineno-4-5\" name=\"__codelineno-4-5\" href=\"#__codelineno-4-5\"></a><span class=\"w\">        </span><span class=\"k\">return</span>\n</span><span id=\"__span-4-6\"><a id=\"__codelineno-4-6\" name=\"__codelineno-4-6\" href=\"#__codelineno-4-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-4-7\"><a id=\"__codelineno-4-7\" name=\"__codelineno-4-7\" href=\"#__codelineno-4-7\"></a>\n</span><span id=\"__span-4-8\"><a id=\"__codelineno-4-8\" name=\"__codelineno-4-8\" href=\"#__codelineno-4-8\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">&lt;=</span><span class=\"w\"> </span><span class=\"nx\">max</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-4-9\"><a id=\"__codelineno-4-9\" name=\"__codelineno-4-9\" href=\"#__codelineno-4-9\"></a><span class=\"w\">        </span><span class=\"nx\">sequentialMergesort</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// Calls our initial sequential version</span>\n</span><span id=\"__span-4-10\"><a id=\"__codelineno-4-10\" name=\"__codelineno-4-10\" href=\"#__codelineno-4-10\"></a><span class=\"w\">    </span><span class=\"p\">}</span><span class=\"w\"> </span><span class=\"k\">else</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// If bigger than the threshold, keeps the parallel version</span>\n</span><span id=\"__span-4-11\"><a id=\"__codelineno-4-11\" name=\"__codelineno-4-11\" href=\"#__codelineno-4-11\"></a><span class=\"w\">        </span><span class=\"nx\">middle</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">/</span><span class=\"w\"> </span><span class=\"mi\">2</span>\n</span><span id=\"__span-4-12\"><a id=\"__codelineno-4-12\" name=\"__codelineno-4-12\" href=\"#__codelineno-4-12\"></a>\n</span><span id=\"__span-4-13\"><a id=\"__codelineno-4-13\" name=\"__codelineno-4-13\" href=\"#__codelineno-4-13\"></a><span class=\"w\">        </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">wg</span><span class=\"w\"> </span><span class=\"nx\">sync</span><span class=\"p\">.</span><span class=\"nx\">WaitGroup</span>\n</span><span id=\"__span-4-14\"><a id=\"__codelineno-4-14\" name=\"__codelineno-4-14\" href=\"#__codelineno-4-14\"></a><span class=\"w\">        </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Add</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n</span><span id=\"__span-4-15\"><a id=\"__codelineno-4-15\" name=\"__codelineno-4-15\" href=\"#__codelineno-4-15\"></a>\n</span><span id=\"__span-4-16\"><a id=\"__codelineno-4-16\" name=\"__codelineno-4-16\" href=\"#__codelineno-4-16\"></a><span class=\"w\">        </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-4-17\"><a id=\"__codelineno-4-17\" name=\"__codelineno-4-17\" href=\"#__codelineno-4-17\"></a><span class=\"w\">            </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Done</span><span class=\"p\">()</span>\n</span><span id=\"__span-4-18\"><a id=\"__codelineno-4-18\" name=\"__codelineno-4-18\" href=\"#__codelineno-4-18\"></a><span class=\"w\">            </span><span class=\"nx\">parallelMergesortV2</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">[:</span><span class=\"nx\">middle</span><span class=\"p\">])</span>\n</span><span id=\"__span-4-19\"><a id=\"__codelineno-4-19\" name=\"__codelineno-4-19\" href=\"#__codelineno-4-19\"></a><span class=\"w\">        </span><span class=\"p\">}()</span>\n</span><span id=\"__span-4-20\"><a id=\"__codelineno-4-20\" name=\"__codelineno-4-20\" href=\"#__codelineno-4-20\"></a>\n</span><span id=\"__span-4-21\"><a id=\"__codelineno-4-21\" name=\"__codelineno-4-21\" href=\"#__codelineno-4-21\"></a><span class=\"w\">        </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-4-22\"><a id=\"__codelineno-4-22\" name=\"__codelineno-4-22\" href=\"#__codelineno-4-22\"></a><span class=\"w\">            </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Done</span><span class=\"p\">()</span>\n</span><span id=\"__span-4-23\"><a id=\"__codelineno-4-23\" name=\"__codelineno-4-23\" href=\"#__codelineno-4-23\"></a><span class=\"w\">            </span><span class=\"nx\">parallelMergesortV2</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">[</span><span class=\"nx\">middle</span><span class=\"p\">:])</span>\n</span><span id=\"__span-4-24\"><a id=\"__codelineno-4-24\" name=\"__codelineno-4-24\" href=\"#__codelineno-4-24\"></a><span class=\"w\">        </span><span class=\"p\">}()</span>\n</span><span id=\"__span-4-25\"><a id=\"__codelineno-4-25\" name=\"__codelineno-4-25\" href=\"#__codelineno-4-25\"></a>\n</span><span id=\"__span-4-26\"><a id=\"__codelineno-4-26\" name=\"__codelineno-4-26\" href=\"#__codelineno-4-26\"></a><span class=\"w\">        </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Wait</span><span class=\"p\">()</span>\n</span><span id=\"__span-4-27\"><a id=\"__codelineno-4-27\" name=\"__codelineno-4-27\" href=\"#__codelineno-4-27\"></a><span class=\"w\">        </span><span class=\"nx\">merge</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">middle</span><span class=\"p\">)</span>\n</span><span id=\"__span-4-28\"><a id=\"__codelineno-4-28\" name=\"__codelineno-4-28\" href=\"#__codelineno-4-28\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-4-29\"><a id=\"__codelineno-4-29\" name=\"__codelineno-4-29\" href=\"#__codelineno-4-29\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>If the number of elements in the s slice is smaller than max, we call the sequential version. Otherwise, we keep calling our parallel implementation. Does this approach impact the result? Yes, it does:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-5-1\"><a id=\"__codelineno-5-1\" name=\"__codelineno-5-1\" href=\"#__codelineno-5-1\"></a>Benchmark_sequentialMergesort-4       2278993555 ns/op\n</span><span id=\"__span-5-2\"><a id=\"__codelineno-5-2\" name=\"__codelineno-5-2\" href=\"#__codelineno-5-2\"></a>Benchmark_parallelMergesortV1-4      17525998709 ns/op\n</span><span id=\"__span-5-3\"><a id=\"__codelineno-5-3\" name=\"__codelineno-5-3\" href=\"#__codelineno-5-3\"></a>Benchmark_parallelMergesortV2-4       1313010260 ns/op\n</span></code></pre></div>\n<p>Our v2 parallel implementation is more than 40% faster than the sequential one, thanks to this idea of defining a threshold to indicate when parallel should be more efficient than sequential.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>Why did I set the threshold to 2,048? Because it was the optimal value for this specific workload on my machine. In general, such magic values should be defined carefully with benchmarks (running on an execution environment similar to production). It’s also pretty interesting to note that running the same algorithm in a programming language that doesn’t implement the concept of goroutines has an impact on the value. For example, running the same example in Java using threads means an optimal value closer to 8,192. This tends to illustrate how goroutines are more efficient than threads.</p>\n</details>\n<h2 id=\"conclusion\">Conclusion</h2>\n<p>We have seen throughout this post the fundamental concepts of scheduling in Go: the differences between a thread and a goroutine and how the Go runtime schedules goroutines. Meanwhile, using the parallel merge sort example, we illustrated that concurrency isn’t always necessarily faster. As we have seen, spinning up goroutines to handle minimal workloads (merging only a small set of elements) demolishes the benefit we could get from parallelism.</p>\n<p>So, where should we go from here? We must keep in mind that concurrency isn’t always faster and shouldn’t be considered the default way to go for all problems. First, it makes things more complex. Also, modern CPUs have become incredibly efficient at executing sequential code and predictable code. For example, a superscalar processor can parallelize instruction execution over a single core with high efficiency.</p>\n<p>Does this mean we shouldn’t use concurrency? Of course not. However, it’s essential to keep these conclusions in mind. If we’re not sure that a parallel version will be faster, the right approach may be to start with a simple sequential version and build from there using profiling (mistake #98, “<a href=\"https://100go.co/98-profiling-execution-tracing/\">Not using Go diagnostics tooling</a>”) and benchmarks (mistake #89, “<a href=\"https://100go.co/89-benchmarks/\">Writing inaccurate benchmarks</a>”), for example. It can be the only way to ensure that a concurrent implementation is worth it.</p>\n\n\n\n\n\n\n\n  \n  \n\n\n\n  \n\n\n  \n\n\n\n<h2 id=\"__comments\">Comments</h2>\n<!-- Insert generated snippet here -->\n<script src=\"https://giscus.app/client.js\" data-repo=\"teivah/100-go-mistakes\" data-repo-id=\"MDEwOlJlcG9zaXRvcnkzMjA4MTg5NjI=\" data-category=\"Discussions\" data-category-id=\"DIC_kwDOEx9PEs4CZQUm\" data-mapping=\"pathname\" data-strict=\"0\" data-reactions-enabled=\"1\" data-emit-metadata=\"0\" data-input-position=\"bottom\" data-theme=\"preferred_color_scheme\" data-lang=\"en\" crossorigin=\"anonymous\" async>\n</script>\n<!-- Synchronize Giscus theme with palette -->\n<script>\n  var giscus = document.querySelector(\"script[src*=giscus]\")\n\n  // Set palette on initial load\n  var palette = __md_get(\"__palette\")\n  if (palette && typeof palette.color === \"object\") {\n    var theme = palette.color.scheme === \"slate\"\n        ? \"transparent_dark\"\n        : \"light\"\n\n    // Instruct Giscus to set theme\n    giscus.setAttribute(\"data-theme\", theme)\n  }\n\n  // Register event handlers after documented loaded\n  document.addEventListener(\"DOMContentLoaded\", function() {\n    var ref = document.querySelector(\"[data-md-component=palette]\")\n    ref.addEventListener(\"change\", function() {\n      var palette = __md_get(\"__palette\")\n      if (palette && typeof palette.color === \"object\") {\n        var theme = palette.color.scheme === \"slate\"\n            ? \"transparent_dark\"\n            : \"light\"\n\n        // Instruct Giscus to change theme\n        var frame = document.querySelector(\".giscus-frame\")\n        frame.contentWindow.postMessage(\n            { giscus: { setConfig: { theme } } },\n            \"https://giscus.app\"\n        )\n      }\n    })\n  })\n</script>\n\n                \n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright © 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"></path></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \"..\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"../assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"../assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  \n<script id=\"init-glightbox\">const lightbox = GLightbox({\"touchNavigation\": true, \"loop\": false, \"zoomable\": true, \"draggable\": true, \"openEffect\": \"zoom\", \"closeEffect\": \"zoom\", \"slideEffect\": \"slide\"});\ndocument$.subscribe(()=>{ lightbox.reload(); });\n</script></body></html>"
  },
  {
    "path": "site/89-benchmarks/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\" class=\"no-js\"><head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n      \n      \n        <link rel=\"canonical\" href=\"https://100go.co/89-benchmarks/\">\n      \n      \n        <link rel=\"prev\" href=\"../56-concurrency-faster/\">\n      \n      \n        <link rel=\"next\" href=\"../92-false-sharing/\">\n      \n      \n      <link rel=\"icon\" href=\"../img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>Writing inaccurate benchmarks (#89) - 100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"../assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\"..\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n      \n        <meta property=\"og:type\" content=\"website\">\n      \n        <meta property=\"og:title\" content=\"Writing inaccurate benchmarks (#89) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta property=\"og:description\" content=\"None\">\n      \n        <meta property=\"og:image\" content=\"https://100go.co/assets/images/social/89-benchmarks.png\">\n      \n        <meta property=\"og:image:type\" content=\"image/png\">\n      \n        <meta property=\"og:image:width\" content=\"1200\">\n      \n        <meta property=\"og:image:height\" content=\"630\">\n      \n        <meta property=\"og:url\" content=\"https://100go.co/89-benchmarks/\">\n      \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n      \n        <meta name=\"twitter:title\" content=\"Writing inaccurate benchmarks (#89) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta name=\"twitter:description\" content=\"None\">\n      \n        <meta name=\"twitter:image\" content=\"https://100go.co/assets/images/social/89-benchmarks.png\">\n      \n    \n    \n  <link href=\"../assets/stylesheets/glightbox.min.css\" rel=\"stylesheet\"><script src=\"../assets/javascripts/glightbox.min.js\"></script><style id=\"glightbox-style\">\n            html.glightbox-open { overflow: initial; height: 100%; }\n            .gslide-title { margin-top: 0px; user-select: text; }\n            .gslide-desc { color: #666; user-select: text; }\n            .gslide-image img { background: white; }\n            .gscrollbar-fixer { padding-right: 15px; }\n            .gdesc-inner { font-size: 0.75rem; }\n            body[data-md-color-scheme=\"slate\"] .gdesc-inner { background: var(--md-default-bg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-title { color: var(--md-default-fg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-desc { color: var(--md-default-fg-color); }\n        </style></head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n        \n        <a href=\"#writing-inaccurate-benchmarks\" class=\"md-skip\">\n          Skip to content\n        </a>\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"></path></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              Writing inaccurate benchmarks (#89)\n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"></path></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"></path></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"></path></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n    \n  \n  \n    \n    \n      <li class=\"md-tabs__item md-tabs__item--active\">\n        <a href=\"..\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"../book/\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n        \n        \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"..\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1_2\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../5-interface-pollution/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../9-generics/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../20-slice/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../28-maps-memory-leaks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../56-concurrency-faster/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    <li class=\"md-nav__item md-nav__item--active\">\n      \n      <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n      \n      \n        \n      \n      \n        <label class=\"md-nav__link md-nav__link--active\" for=\"__toc\">\n          \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n          <span class=\"md-nav__icon md-icon\"></span>\n        </label>\n      \n      <a href=\"./\" class=\"md-nav__link md-nav__link--active\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n      \n        \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#general-concepts\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      General concepts\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#not-resetting-or-pausing-the-timer\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not resetting or pausing the timer\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#making-wrong-assumptions-about-micro-benchmarks\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Making wrong assumptions about micro-benchmarks\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#not-being-careful-about-compiler-optimizations\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not being careful about compiler optimizations\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#being-fooled-by-the-observer-effect\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Being fooled by the observer effect\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../92-false-sharing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../98-profiling-execution-tracing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_3\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../zh/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../ja/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../pt-br/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../book/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../chapter-1/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../external/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\" hidden>\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#general-concepts\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      General concepts\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#not-resetting-or-pausing-the-timer\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not resetting or pausing the timer\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#making-wrong-assumptions-about-micro-benchmarks\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Making wrong assumptions about micro-benchmarks\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#not-being-careful-about-compiler-optimizations\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not being careful about compiler optimizations\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#being-fooled-by-the-observer-effect\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Being fooled by the observer effect\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n                  \n  \n\n\n\n  \n  \n\n\n<h1 id=\"writing-inaccurate-benchmarks\">Writing inaccurate benchmarks</h1>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/89-benchmarks.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/89-benchmarks.png\"></a></p>\n<p>In general, we should never guess about performance. When writing optimizations, so many factors may come into play that even if we have a strong opinion about the results, it’s rarely a bad idea to test them. However, writing benchmarks isn’t straightforward. It can be pretty simple to write inaccurate benchmarks and make wrong assumptions based on them. The goal of this post is to examine four common and concrete traps leading to inaccuracy:</p>\n<ul>\n<li>Not resetting or pausing the timer</li>\n<li>Making wrong assumptions about micro-benchmarks</li>\n<li>Not being careful about compiler optimizations</li>\n<li>Being fooled by the observer effect</li>\n</ul>\n<h2 id=\"general-concepts\">General concepts</h2>\n<p>Before discussing these traps, let’s briefly review how benchmarks work in Go. The skeleton of a benchmark is as follows:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-0-1\"><a id=\"__codelineno-0-1\" name=\"__codelineno-0-1\" href=\"#__codelineno-0-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">BenchmarkFoo</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">B</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-0-2\"><a id=\"__codelineno-0-2\" name=\"__codelineno-0-2\" href=\"#__codelineno-0-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">N</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-0-3\"><a id=\"__codelineno-0-3\" name=\"__codelineno-0-3\" href=\"#__codelineno-0-3\"></a><span class=\"w\">        </span><span class=\"nx\">foo</span><span class=\"p\">()</span>\n</span><span id=\"__span-0-4\"><a id=\"__codelineno-0-4\" name=\"__codelineno-0-4\" href=\"#__codelineno-0-4\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-0-5\"><a id=\"__codelineno-0-5\" name=\"__codelineno-0-5\" href=\"#__codelineno-0-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>The function name starts with the <code>Benchmark</code> prefix. The function under test (foo) is called within the <code>for</code> loop. <code>b.N</code> represents a variable number of iterations. When running a benchmark, Go tries to make it match the requested benchmark time. The benchmark time is set by default to 1 second and can be changed with the <code>-benchtime</code> flag. <code>b.N</code> starts at 1; if the benchmark completes in under 1 second, <code>b.N</code> is increased, and the benchmark runs again until <code>b.N</code> roughly matches benchtime:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-1-1\"><a id=\"__codelineno-1-1\" name=\"__codelineno-1-1\" href=\"#__codelineno-1-1\"></a>$ go test -bench=.\n</span><span id=\"__span-1-2\"><a id=\"__codelineno-1-2\" name=\"__codelineno-1-2\" href=\"#__codelineno-1-2\"></a>cpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\n</span><span id=\"__span-1-3\"><a id=\"__codelineno-1-3\" name=\"__codelineno-1-3\" href=\"#__codelineno-1-3\"></a>BenchmarkFoo-4                73          16511228 ns/op\n</span></code></pre></div>\n<p>Here, the benchmark took about 1 second, and <code>foo</code> was executed 73 times, for an average execution time of 16,511,228 nanoseconds. We can change the benchmark time using <code>-benchtime</code>:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-2-1\"><a id=\"__codelineno-2-1\" name=\"__codelineno-2-1\" href=\"#__codelineno-2-1\"></a>$ go test -bench=. -benchtime=2s\n</span><span id=\"__span-2-2\"><a id=\"__codelineno-2-2\" name=\"__codelineno-2-2\" href=\"#__codelineno-2-2\"></a>BenchmarkFoo-4               150          15832169 ns/op\n</span></code></pre></div>\n<p><code>foo</code> was executed roughly twice more than during the previous benchmark.</p>\n<p>Next, let’s look at some common traps.</p>\n<h2 id=\"not-resetting-or-pausing-the-timer\">Not resetting or pausing the timer</h2>\n<p>In some cases, we need to perform operations before the benchmark loop. These operations may take quite a while (for example, generating a large slice of data) and may significantly impact the benchmark results:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-3-1\"><a id=\"__codelineno-3-1\" name=\"__codelineno-3-1\" href=\"#__codelineno-3-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">BenchmarkFoo</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">B</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-3-2\"><a id=\"__codelineno-3-2\" name=\"__codelineno-3-2\" href=\"#__codelineno-3-2\"></a><span class=\"w\">    </span><span class=\"nx\">expensiveSetup</span><span class=\"p\">()</span>\n</span><span id=\"__span-3-3\"><a id=\"__codelineno-3-3\" name=\"__codelineno-3-3\" href=\"#__codelineno-3-3\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">N</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-3-4\"><a id=\"__codelineno-3-4\" name=\"__codelineno-3-4\" href=\"#__codelineno-3-4\"></a><span class=\"w\">        </span><span class=\"nx\">functionUnderTest</span><span class=\"p\">()</span>\n</span><span id=\"__span-3-5\"><a id=\"__codelineno-3-5\" name=\"__codelineno-3-5\" href=\"#__codelineno-3-5\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-3-6\"><a id=\"__codelineno-3-6\" name=\"__codelineno-3-6\" href=\"#__codelineno-3-6\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>In this case, we can use the <code>ResetTimer</code> method before entering the loop:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-4-1\"><a id=\"__codelineno-4-1\" name=\"__codelineno-4-1\" href=\"#__codelineno-4-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">BenchmarkFoo</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">B</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-4-2\"><a id=\"__codelineno-4-2\" name=\"__codelineno-4-2\" href=\"#__codelineno-4-2\"></a><span class=\"w\">    </span><span class=\"nx\">expensiveSetup</span><span class=\"p\">()</span>\n</span><span id=\"__span-4-3\"><a id=\"__codelineno-4-3\" name=\"__codelineno-4-3\" href=\"#__codelineno-4-3\"></a><span class=\"w\">    </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">ResetTimer</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// Reset the benchmark timer</span>\n</span><span id=\"__span-4-4\"><a id=\"__codelineno-4-4\" name=\"__codelineno-4-4\" href=\"#__codelineno-4-4\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">N</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-4-5\"><a id=\"__codelineno-4-5\" name=\"__codelineno-4-5\" href=\"#__codelineno-4-5\"></a><span class=\"w\">        </span><span class=\"nx\">functionUnderTest</span><span class=\"p\">()</span>\n</span><span id=\"__span-4-6\"><a id=\"__codelineno-4-6\" name=\"__codelineno-4-6\" href=\"#__codelineno-4-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-4-7\"><a id=\"__codelineno-4-7\" name=\"__codelineno-4-7\" href=\"#__codelineno-4-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Calling <code>ResetTimer</code> zeroes the elapsed benchmark time and memory allocation counters since the beginning of the test. This way, an expensive setup can be discarded from the test results.</p>\n<p>What if we have to perform an expensive setup not just once but within each loop iteration?</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-5-1\"><a id=\"__codelineno-5-1\" name=\"__codelineno-5-1\" href=\"#__codelineno-5-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">BenchmarkFoo</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">B</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-2\"><a id=\"__codelineno-5-2\" name=\"__codelineno-5-2\" href=\"#__codelineno-5-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">N</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-3\"><a id=\"__codelineno-5-3\" name=\"__codelineno-5-3\" href=\"#__codelineno-5-3\"></a><span class=\"w\">        </span><span class=\"nx\">expensiveSetup</span><span class=\"p\">()</span>\n</span><span id=\"__span-5-4\"><a id=\"__codelineno-5-4\" name=\"__codelineno-5-4\" href=\"#__codelineno-5-4\"></a><span class=\"w\">        </span><span class=\"nx\">functionUnderTest</span><span class=\"p\">()</span>\n</span><span id=\"__span-5-5\"><a id=\"__codelineno-5-5\" name=\"__codelineno-5-5\" href=\"#__codelineno-5-5\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-6\"><a id=\"__codelineno-5-6\" name=\"__codelineno-5-6\" href=\"#__codelineno-5-6\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>We can’t reset the timer, because that would be executed during each loop iteration. But we can stop and resume the benchmark timer, surrounding the call to <code>expensiveSetup</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-6-1\"><a id=\"__codelineno-6-1\" name=\"__codelineno-6-1\" href=\"#__codelineno-6-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">BenchmarkFoo</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">B</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-6-2\"><a id=\"__codelineno-6-2\" name=\"__codelineno-6-2\" href=\"#__codelineno-6-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">N</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-6-3\"><a id=\"__codelineno-6-3\" name=\"__codelineno-6-3\" href=\"#__codelineno-6-3\"></a><span class=\"w\">        </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">StopTimer</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// Pause the benchmark timer</span>\n</span><span id=\"__span-6-4\"><a id=\"__codelineno-6-4\" name=\"__codelineno-6-4\" href=\"#__codelineno-6-4\"></a><span class=\"w\">        </span><span class=\"nx\">expensiveSetup</span><span class=\"p\">()</span>\n</span><span id=\"__span-6-5\"><a id=\"__codelineno-6-5\" name=\"__codelineno-6-5\" href=\"#__codelineno-6-5\"></a><span class=\"w\">        </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">StartTimer</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// Resume the benchmark timer</span>\n</span><span id=\"__span-6-6\"><a id=\"__codelineno-6-6\" name=\"__codelineno-6-6\" href=\"#__codelineno-6-6\"></a><span class=\"w\">        </span><span class=\"nx\">functionUnderTest</span><span class=\"p\">()</span>\n</span><span id=\"__span-6-7\"><a id=\"__codelineno-6-7\" name=\"__codelineno-6-7\" href=\"#__codelineno-6-7\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-6-8\"><a id=\"__codelineno-6-8\" name=\"__codelineno-6-8\" href=\"#__codelineno-6-8\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Here, we pause the benchmark timer to perform the expensive setup and then resume the timer.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>There’s one catch to remember about this approach: if the function under test is too fast to execute compared to the setup function, the benchmark may take too long to complete. The reason is that it would take much longer than 1 second to reach <code>benchtime</code>. Calculating the benchmark time is based solely on the execution time of <code>functionUnderTest</code>. So, if we wait a significant time in each loop iteration, the benchmark will be much slower than 1 second. If we want to keep the benchmark, one possible mitigation is to decrease <code>benchtime</code>.</p>\n</details>\n<p>We must be sure to use the timer methods to preserve the accuracy of a benchmark.</p>\n<h2 id=\"making-wrong-assumptions-about-micro-benchmarks\">Making wrong assumptions about micro-benchmarks</h2>\n<p>A micro-benchmark measures a tiny computation unit, and it can be extremely easy to make wrong assumptions about it. Let’s say, for example, that we aren’t sure whether to use <code>atomic.StoreInt32</code> or <code>atomic.StoreInt64</code> (assuming that the values we handle will always fit in 32 bits). We want to write a benchmark to compare both functions:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-7-1\"><a id=\"__codelineno-7-1\" name=\"__codelineno-7-1\" href=\"#__codelineno-7-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">BenchmarkAtomicStoreInt32</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">B</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-7-2\"><a id=\"__codelineno-7-2\" name=\"__codelineno-7-2\" href=\"#__codelineno-7-2\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"kt\">int32</span>\n</span><span id=\"__span-7-3\"><a id=\"__codelineno-7-3\" name=\"__codelineno-7-3\" href=\"#__codelineno-7-3\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">N</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-7-4\"><a id=\"__codelineno-7-4\" name=\"__codelineno-7-4\" href=\"#__codelineno-7-4\"></a><span class=\"w\">        </span><span class=\"nx\">atomic</span><span class=\"p\">.</span><span class=\"nx\">StoreInt32</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">v</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-7-5\"><a id=\"__codelineno-7-5\" name=\"__codelineno-7-5\" href=\"#__codelineno-7-5\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-7-6\"><a id=\"__codelineno-7-6\" name=\"__codelineno-7-6\" href=\"#__codelineno-7-6\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-7-7\"><a id=\"__codelineno-7-7\" name=\"__codelineno-7-7\" href=\"#__codelineno-7-7\"></a>\n</span><span id=\"__span-7-8\"><a id=\"__codelineno-7-8\" name=\"__codelineno-7-8\" href=\"#__codelineno-7-8\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">BenchmarkAtomicStoreInt64</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">B</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-7-9\"><a id=\"__codelineno-7-9\" name=\"__codelineno-7-9\" href=\"#__codelineno-7-9\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"kt\">int64</span>\n</span><span id=\"__span-7-10\"><a id=\"__codelineno-7-10\" name=\"__codelineno-7-10\" href=\"#__codelineno-7-10\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">N</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-7-11\"><a id=\"__codelineno-7-11\" name=\"__codelineno-7-11\" href=\"#__codelineno-7-11\"></a><span class=\"w\">        </span><span class=\"nx\">atomic</span><span class=\"p\">.</span><span class=\"nx\">StoreInt64</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">v</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-7-12\"><a id=\"__codelineno-7-12\" name=\"__codelineno-7-12\" href=\"#__codelineno-7-12\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-7-13\"><a id=\"__codelineno-7-13\" name=\"__codelineno-7-13\" href=\"#__codelineno-7-13\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>If we run this benchmark, here’s some example output:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-8-1\"><a id=\"__codelineno-8-1\" name=\"__codelineno-8-1\" href=\"#__codelineno-8-1\"></a>cpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\n</span><span id=\"__span-8-2\"><a id=\"__codelineno-8-2\" name=\"__codelineno-8-2\" href=\"#__codelineno-8-2\"></a>BenchmarkAtomicStoreInt32\n</span><span id=\"__span-8-3\"><a id=\"__codelineno-8-3\" name=\"__codelineno-8-3\" href=\"#__codelineno-8-3\"></a>BenchmarkAtomicStoreInt32-4    197107742           5.682 ns/op\n</span><span id=\"__span-8-4\"><a id=\"__codelineno-8-4\" name=\"__codelineno-8-4\" href=\"#__codelineno-8-4\"></a>BenchmarkAtomicStoreInt64\n</span><span id=\"__span-8-5\"><a id=\"__codelineno-8-5\" name=\"__codelineno-8-5\" href=\"#__codelineno-8-5\"></a>BenchmarkAtomicStoreInt64-4    213917528           5.134 ns/op\n</span></code></pre></div>\n<p>We could easily take this benchmark for granted and decide to use <code>atomic.StoreInt64</code> because it appears to be faster. Now, for the sake of doing a fair benchmark, we reverse the order and test <code>atomic.StoreInt64</code> first, followed by <code>atomic.StoreInt32</code>. Here is some example output:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-9-1\"><a id=\"__codelineno-9-1\" name=\"__codelineno-9-1\" href=\"#__codelineno-9-1\"></a>BenchmarkAtomicStoreInt64\n</span><span id=\"__span-9-2\"><a id=\"__codelineno-9-2\" name=\"__codelineno-9-2\" href=\"#__codelineno-9-2\"></a>BenchmarkAtomicStoreInt64-4    224900722           5.434 ns/op\n</span><span id=\"__span-9-3\"><a id=\"__codelineno-9-3\" name=\"__codelineno-9-3\" href=\"#__codelineno-9-3\"></a>BenchmarkAtomicStoreInt32\n</span><span id=\"__span-9-4\"><a id=\"__codelineno-9-4\" name=\"__codelineno-9-4\" href=\"#__codelineno-9-4\"></a>BenchmarkAtomicStoreInt32-4    230253900           5.159 ns/op\n</span></code></pre></div>\n<p>This time, <code>atomic.StoreInt32</code> has better results. What happened?</p>\n<p>In the case of micro-benchmarks, many factors can impact the results, such as machine activity while running the benchmarks, power management, thermal scaling, and better cache alignment of a sequence of instructions. We must remember that many factors, even outside the scope of our Go project, can impact the results.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>We should make sure the machine executing the benchmark is idle. However, external processes may run in the background, which may affect benchmark results. For that reason, tools such as <code>perflock</code> can limit how much CPU a benchmark can consume. For example, we can run a benchmark with 70% of the total available CPU, giving 30% to the OS and other processes and reducing the impact of the machine activity factor on the results.</p>\n</details>\n<p>One option is to increase the benchmark time using the <code>-benchtime</code> option. Similar to the law of large numbers in probability theory, if we run a benchmark a large number of times, it should tend to approach its expected value (assuming we omit the benefits of instructions caching and similar mechanics).</p>\n<p>Another option is to use external tools on top of the classic benchmark tooling. For instance, the <code>benchstat</code> tool, which is part of the <code>golang.org/x</code> repository, allows us to compute and compare statistics about benchmark executions.</p>\n<p>Let’s run the benchmark 10 times using the <code>-count</code> option and pipe the output to a specific file:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-10-1\"><a id=\"__codelineno-10-1\" name=\"__codelineno-10-1\" href=\"#__codelineno-10-1\"></a>$ go test -bench=. -count=10 | tee stats.txt\n</span><span id=\"__span-10-2\"><a id=\"__codelineno-10-2\" name=\"__codelineno-10-2\" href=\"#__codelineno-10-2\"></a>cpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\n</span><span id=\"__span-10-3\"><a id=\"__codelineno-10-3\" name=\"__codelineno-10-3\" href=\"#__codelineno-10-3\"></a>BenchmarkAtomicStoreInt32-4     234935682                5.124 ns/op\n</span><span id=\"__span-10-4\"><a id=\"__codelineno-10-4\" name=\"__codelineno-10-4\" href=\"#__codelineno-10-4\"></a>BenchmarkAtomicStoreInt32-4     235307204                5.112 ns/op\n</span><span id=\"__span-10-5\"><a id=\"__codelineno-10-5\" name=\"__codelineno-10-5\" href=\"#__codelineno-10-5\"></a>// ...\n</span><span id=\"__span-10-6\"><a id=\"__codelineno-10-6\" name=\"__codelineno-10-6\" href=\"#__codelineno-10-6\"></a>BenchmarkAtomicStoreInt64-4     235548591                5.107 ns/op\n</span><span id=\"__span-10-7\"><a id=\"__codelineno-10-7\" name=\"__codelineno-10-7\" href=\"#__codelineno-10-7\"></a>BenchmarkAtomicStoreInt64-4     235210292                5.090 ns/op\n</span><span id=\"__span-10-8\"><a id=\"__codelineno-10-8\" name=\"__codelineno-10-8\" href=\"#__codelineno-10-8\"></a>// ...\n</span></code></pre></div>\n<p>We can then run <code>benchstat</code> on this file:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-11-1\"><a id=\"__codelineno-11-1\" name=\"__codelineno-11-1\" href=\"#__codelineno-11-1\"></a>$ benchstat stats.txt\n</span><span id=\"__span-11-2\"><a id=\"__codelineno-11-2\" name=\"__codelineno-11-2\" href=\"#__codelineno-11-2\"></a>name                time/op\n</span><span id=\"__span-11-3\"><a id=\"__codelineno-11-3\" name=\"__codelineno-11-3\" href=\"#__codelineno-11-3\"></a>AtomicStoreInt32-4  5.10ns ± 1%\n</span><span id=\"__span-11-4\"><a id=\"__codelineno-11-4\" name=\"__codelineno-11-4\" href=\"#__codelineno-11-4\"></a>AtomicStoreInt64-4  5.10ns ± 1%\n</span></code></pre></div>\n<p>The results are the same: both functions take on average 5.10 nanoseconds to complete. We also see the percent variation between the executions of a given benchmark: ± 1%. This metric tells us that both benchmarks are stable, giving us more confidence in the computed average results. Therefore, instead of concluding that <code>atomic.StoreInt32</code> is faster or slower, we can conclude that its execution time is similar to that of <code>atomic.StoreInt64</code> for the usage we tested (in a specific Go version on a particular machine).</p>\n<p>In general, we should be cautious about micro-benchmarks. Many factors can significantly impact the results and potentially lead to wrong assumptions. Increasing the benchmark time or repeating the benchmark executions and computing stats with tools such as <code>benchstat</code> can be an efficient way to limit external factors and get more accurate results, leading to better conclusions.</p>\n<p>Let’s also highlight that we should be careful about using the results of a micro-benchmark executed on a given machine if another system ends up running the application. The production system may act quite differently from the one on which we ran the micro-benchmark.</p>\n<h2 id=\"not-being-careful-about-compiler-optimizations\">Not being careful about compiler optimizations</h2>\n<p>Another common mistake related to writing benchmarks is being fooled by compiler optimizations, which can also lead to wrong benchmark assumptions. In this section, we look at Go issue 14813 (https://github.com/golang/go/issues/14813, also discussed by Go project member Dave Cheney) with a population count function (a function that counts the number of bits set to 1):</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-12-1\"><a id=\"__codelineno-12-1\" name=\"__codelineno-12-1\" href=\"#__codelineno-12-1\"></a><span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"nx\">m1</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"mh\">0x5555555555555555</span>\n</span><span id=\"__span-12-2\"><a id=\"__codelineno-12-2\" name=\"__codelineno-12-2\" href=\"#__codelineno-12-2\"></a><span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"nx\">m2</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"mh\">0x3333333333333333</span>\n</span><span id=\"__span-12-3\"><a id=\"__codelineno-12-3\" name=\"__codelineno-12-3\" href=\"#__codelineno-12-3\"></a><span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"nx\">m4</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"mh\">0x0f0f0f0f0f0f0f0f</span>\n</span><span id=\"__span-12-4\"><a id=\"__codelineno-12-4\" name=\"__codelineno-12-4\" href=\"#__codelineno-12-4\"></a><span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"nx\">h01</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"mh\">0x0101010101010101</span>\n</span><span id=\"__span-12-5\"><a id=\"__codelineno-12-5\" name=\"__codelineno-12-5\" href=\"#__codelineno-12-5\"></a>\n</span><span id=\"__span-12-6\"><a id=\"__codelineno-12-6\" name=\"__codelineno-12-6\" href=\"#__codelineno-12-6\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">popcnt</span><span class=\"p\">(</span><span class=\"nx\">x</span><span class=\"w\"> </span><span class=\"kt\">uint64</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">uint64</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-12-7\"><a id=\"__codelineno-12-7\" name=\"__codelineno-12-7\" href=\"#__codelineno-12-7\"></a><span class=\"w\">    </span><span class=\"nx\">x</span><span class=\"w\"> </span><span class=\"o\">-=</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">x</span><span class=\"w\"> </span><span class=\"o\">&gt;&gt;</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">&amp;</span><span class=\"w\"> </span><span class=\"nx\">m1</span>\n</span><span id=\"__span-12-8\"><a id=\"__codelineno-12-8\" name=\"__codelineno-12-8\" href=\"#__codelineno-12-8\"></a><span class=\"w\">    </span><span class=\"nx\">x</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">x</span><span class=\"w\"> </span><span class=\"o\">&amp;</span><span class=\"w\"> </span><span class=\"nx\">m2</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">+</span><span class=\"w\"> </span><span class=\"p\">((</span><span class=\"nx\">x</span><span class=\"w\"> </span><span class=\"o\">&gt;&gt;</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">&amp;</span><span class=\"w\"> </span><span class=\"nx\">m2</span><span class=\"p\">)</span>\n</span><span id=\"__span-12-9\"><a id=\"__codelineno-12-9\" name=\"__codelineno-12-9\" href=\"#__codelineno-12-9\"></a><span class=\"w\">    </span><span class=\"nx\">x</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">x</span><span class=\"w\"> </span><span class=\"o\">+</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">x</span><span class=\"w\"> </span><span class=\"o\">&gt;&gt;</span><span class=\"w\"> </span><span class=\"mi\">4</span><span class=\"p\">))</span><span class=\"w\"> </span><span class=\"o\">&amp;</span><span class=\"w\"> </span><span class=\"nx\">m4</span>\n</span><span id=\"__span-12-10\"><a id=\"__codelineno-12-10\" name=\"__codelineno-12-10\" href=\"#__codelineno-12-10\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">x</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"w\"> </span><span class=\"nx\">h01</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">&gt;&gt;</span><span class=\"w\"> </span><span class=\"mi\">56</span>\n</span><span id=\"__span-12-11\"><a id=\"__codelineno-12-11\" name=\"__codelineno-12-11\" href=\"#__codelineno-12-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>This function takes and returns a <code>uint64</code>. To benchmark this function, we can write the following:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-13-1\"><a id=\"__codelineno-13-1\" name=\"__codelineno-13-1\" href=\"#__codelineno-13-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">BenchmarkPopcnt1</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">B</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-2\"><a id=\"__codelineno-13-2\" name=\"__codelineno-13-2\" href=\"#__codelineno-13-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">N</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-3\"><a id=\"__codelineno-13-3\" name=\"__codelineno-13-3\" href=\"#__codelineno-13-3\"></a><span class=\"w\">        </span><span class=\"nx\">popcnt</span><span class=\"p\">(</span><span class=\"nb\">uint64</span><span class=\"p\">(</span><span class=\"nx\">i</span><span class=\"p\">))</span>\n</span><span id=\"__span-13-4\"><a id=\"__codelineno-13-4\" name=\"__codelineno-13-4\" href=\"#__codelineno-13-4\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-13-5\"><a id=\"__codelineno-13-5\" name=\"__codelineno-13-5\" href=\"#__codelineno-13-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>However, if we execute this benchmark, we get a surprisingly low result:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-14-1\"><a id=\"__codelineno-14-1\" name=\"__codelineno-14-1\" href=\"#__codelineno-14-1\"></a>cpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\n</span><span id=\"__span-14-2\"><a id=\"__codelineno-14-2\" name=\"__codelineno-14-2\" href=\"#__codelineno-14-2\"></a>BenchmarkPopcnt1-4      1000000000               0.2858 ns/op\n</span></code></pre></div>\n<p>A duration of 0.28 nanoseconds is roughly one clock cycle, so this number is unreasonably low. The problem is that the developer wasn’t careful enough about compiler optimizations. In this case, the function under test is simple enough to be a candidate for inlining: an optimization that replaces a function call with the body of the called function and lets us prevent a function call, which has a small footprint. Once the function is inlined, the compiler notices that the call has no side effects and replaces it with the following benchmark:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-15-1\"><a id=\"__codelineno-15-1\" name=\"__codelineno-15-1\" href=\"#__codelineno-15-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">BenchmarkPopcnt1</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">B</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-15-2\"><a id=\"__codelineno-15-2\" name=\"__codelineno-15-2\" href=\"#__codelineno-15-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">N</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-15-3\"><a id=\"__codelineno-15-3\" name=\"__codelineno-15-3\" href=\"#__codelineno-15-3\"></a><span class=\"w\">        </span><span class=\"c1\">// Empty</span>\n</span><span id=\"__span-15-4\"><a id=\"__codelineno-15-4\" name=\"__codelineno-15-4\" href=\"#__codelineno-15-4\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-15-5\"><a id=\"__codelineno-15-5\" name=\"__codelineno-15-5\" href=\"#__codelineno-15-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>The benchmark is now empty — which is why we got a result close to one clock cycle. To prevent this from happening, a best practice is to follow this pattern:</p>\n<ol>\n<li>During each loop iteration, assign the result to a local variable (local in the context of the benchmark function).</li>\n<li>Assign the latest result to a global variable.</li>\n</ol>\n<p>In our case, we write the following benchmark:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-16-1\"><a id=\"__codelineno-16-1\" name=\"__codelineno-16-1\" href=\"#__codelineno-16-1\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">global</span><span class=\"w\"> </span><span class=\"kt\">uint64</span><span class=\"w\"> </span><span class=\"c1\">// Define a global variable</span>\n</span><span id=\"__span-16-2\"><a id=\"__codelineno-16-2\" name=\"__codelineno-16-2\" href=\"#__codelineno-16-2\"></a>\n</span><span id=\"__span-16-3\"><a id=\"__codelineno-16-3\" name=\"__codelineno-16-3\" href=\"#__codelineno-16-3\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">BenchmarkPopcnt2</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">B</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-16-4\"><a id=\"__codelineno-16-4\" name=\"__codelineno-16-4\" href=\"#__codelineno-16-4\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"kt\">uint64</span><span class=\"w\"> </span><span class=\"c1\">// Define a local variable</span>\n</span><span id=\"__span-16-5\"><a id=\"__codelineno-16-5\" name=\"__codelineno-16-5\" href=\"#__codelineno-16-5\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">N</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-16-6\"><a id=\"__codelineno-16-6\" name=\"__codelineno-16-6\" href=\"#__codelineno-16-6\"></a><span class=\"w\">        </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">popcnt</span><span class=\"p\">(</span><span class=\"nb\">uint64</span><span class=\"p\">(</span><span class=\"nx\">i</span><span class=\"p\">))</span><span class=\"w\"> </span><span class=\"c1\">// Assign the result to the local variable</span>\n</span><span id=\"__span-16-7\"><a id=\"__codelineno-16-7\" name=\"__codelineno-16-7\" href=\"#__codelineno-16-7\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-16-8\"><a id=\"__codelineno-16-8\" name=\"__codelineno-16-8\" href=\"#__codelineno-16-8\"></a><span class=\"w\">    </span><span class=\"nx\">global</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"c1\">// Assign the result to the global variable</span>\n</span><span id=\"__span-16-9\"><a id=\"__codelineno-16-9\" name=\"__codelineno-16-9\" href=\"#__codelineno-16-9\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p><code>global</code> is a global variable, whereas v is a local variable whose scope is the benchmark function. During each loop iteration, we assign the result of <code>popcnt</code> to the local variable. Then we assign the latest result to the global variable.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>Why not assign the result of the popcnt call directly to global to simplify the test? Writing to a global variable is slower than writing to a local variable (these concepts are discussed in 100 Go Mistakes, mistake #95: “<a href=\"https://100go.co#not-understanding-stack-vs-heap-95\">Not understanding stack vs. heap</a>”). Therefore, we should write each result to a local variable to limit the footprint during each loop iteration.</p>\n</details>\n<p>If we run these two benchmarks, we now get a significant difference in the results:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-17-1\"><a id=\"__codelineno-17-1\" name=\"__codelineno-17-1\" href=\"#__codelineno-17-1\"></a>cpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\n</span><span id=\"__span-17-2\"><a id=\"__codelineno-17-2\" name=\"__codelineno-17-2\" href=\"#__codelineno-17-2\"></a>BenchmarkPopcnt1-4      1000000000               0.2858 ns/op\n</span><span id=\"__span-17-3\"><a id=\"__codelineno-17-3\" name=\"__codelineno-17-3\" href=\"#__codelineno-17-3\"></a>BenchmarkPopcnt2-4      606402058                1.993 ns/op\n</span></code></pre></div>\n<p><code>BenchmarkPopcnt2</code> is the accurate version of the benchmark. It guarantees that we avoid the inlining optimizations, which can artificially lower the execution time or even remove the call to the function under test. Relying on the results of <code>BenchmarkPopcnt1</code> could have led to wrong assumptions.</p>\n<p>Let’s remember the pattern to avoid compiler optimizations fooling benchmark results: assign the result of the function under test to a local variable, and then assign the latest result to a global variable. This best practice also prevents us from making incorrect assumptions.</p>\n<h2 id=\"being-fooled-by-the-observer-effect\">Being fooled by the observer effect</h2>\n<p>In physics, the observer effect is the disturbance of an observed system by the act of observation. This effect can also be seen in benchmarks and can lead to wrong assumptions about results. Let’s look at a concrete example and then try to mitigate it.</p>\n<p>We want to implement a function receiving a matrix of <code>int64</code> elements. This matrix has a fixed number of 512 columns, and we want to compute the total sum of the first eight columns, as shown in figure 1.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/matrix.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/matrix.png\"></a>\n  </p>\n<figcaption>Figure 1: Computing the sum of the first eight columns.</figcaption>\n</figure>\n<p>For the sake of optimizations, we also want to determine whether varying the number of columns has an impact, so we also implement a second function with 513 columns. The implementation is the following:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-18-1\"><a id=\"__codelineno-18-1\" name=\"__codelineno-18-1\" href=\"#__codelineno-18-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">calculateSum512</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">[][</span><span class=\"mi\">512</span><span class=\"p\">]</span><span class=\"kt\">int64</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">int64</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-18-2\"><a id=\"__codelineno-18-2\" name=\"__codelineno-18-2\" href=\"#__codelineno-18-2\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"kt\">int64</span>\n</span><span id=\"__span-18-3\"><a id=\"__codelineno-18-3\" name=\"__codelineno-18-3\" href=\"#__codelineno-18-3\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">);</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Iterate over each row</span>\n</span><span id=\"__span-18-4\"><a id=\"__codelineno-18-4\" name=\"__codelineno-18-4\" href=\"#__codelineno-18-4\"></a><span class=\"w\">        </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">j</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">j</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">8</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">j</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Iterate over the first eight columns</span>\n</span><span id=\"__span-18-5\"><a id=\"__codelineno-18-5\" name=\"__codelineno-18-5\" href=\"#__codelineno-18-5\"></a><span class=\"w\">            </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"p\">[</span><span class=\"nx\">i</span><span class=\"p\">][</span><span class=\"nx\">j</span><span class=\"p\">]</span><span class=\"w\"> </span><span class=\"c1\">// Increment sum</span>\n</span><span id=\"__span-18-6\"><a id=\"__codelineno-18-6\" name=\"__codelineno-18-6\" href=\"#__codelineno-18-6\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-18-7\"><a id=\"__codelineno-18-7\" name=\"__codelineno-18-7\" href=\"#__codelineno-18-7\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-18-8\"><a id=\"__codelineno-18-8\" name=\"__codelineno-18-8\" href=\"#__codelineno-18-8\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">sum</span>\n</span><span id=\"__span-18-9\"><a id=\"__codelineno-18-9\" name=\"__codelineno-18-9\" href=\"#__codelineno-18-9\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-18-10\"><a id=\"__codelineno-18-10\" name=\"__codelineno-18-10\" href=\"#__codelineno-18-10\"></a>\n</span><span id=\"__span-18-11\"><a id=\"__codelineno-18-11\" name=\"__codelineno-18-11\" href=\"#__codelineno-18-11\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">calculateSum513</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">[][</span><span class=\"mi\">513</span><span class=\"p\">]</span><span class=\"kt\">int64</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">int64</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-18-12\"><a id=\"__codelineno-18-12\" name=\"__codelineno-18-12\" href=\"#__codelineno-18-12\"></a><span class=\"w\">    </span><span class=\"c1\">// Same implementation as calculateSum512</span>\n</span><span id=\"__span-18-13\"><a id=\"__codelineno-18-13\" name=\"__codelineno-18-13\" href=\"#__codelineno-18-13\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>We iterate over each row and then over the first eight columns, and we increment a sum variable that we return. The implementation in <code>calculateSum513</code> remains the same.</p>\n<p>We want to benchmark these functions to decide which one is the most performant given a fixed number of rows:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-19-1\"><a id=\"__codelineno-19-1\" name=\"__codelineno-19-1\" href=\"#__codelineno-19-1\"></a><span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"nx\">rows</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"mi\">1000</span>\n</span><span id=\"__span-19-2\"><a id=\"__codelineno-19-2\" name=\"__codelineno-19-2\" href=\"#__codelineno-19-2\"></a>\n</span><span id=\"__span-19-3\"><a id=\"__codelineno-19-3\" name=\"__codelineno-19-3\" href=\"#__codelineno-19-3\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">res</span><span class=\"w\"> </span><span class=\"kt\">int64</span>\n</span><span id=\"__span-19-4\"><a id=\"__codelineno-19-4\" name=\"__codelineno-19-4\" href=\"#__codelineno-19-4\"></a>\n</span><span id=\"__span-19-5\"><a id=\"__codelineno-19-5\" name=\"__codelineno-19-5\" href=\"#__codelineno-19-5\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">BenchmarkCalculateSum512</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">B</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-19-6\"><a id=\"__codelineno-19-6\" name=\"__codelineno-19-6\" href=\"#__codelineno-19-6\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"kt\">int64</span>\n</span><span id=\"__span-19-7\"><a id=\"__codelineno-19-7\" name=\"__codelineno-19-7\" href=\"#__codelineno-19-7\"></a><span class=\"w\">    </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">createMatrix512</span><span class=\"p\">(</span><span class=\"nx\">rows</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// Create a matrix of 512 columns</span>\n</span><span id=\"__span-19-8\"><a id=\"__codelineno-19-8\" name=\"__codelineno-19-8\" href=\"#__codelineno-19-8\"></a><span class=\"w\">    </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">ResetTimer</span><span class=\"p\">()</span>\n</span><span id=\"__span-19-9\"><a id=\"__codelineno-19-9\" name=\"__codelineno-19-9\" href=\"#__codelineno-19-9\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">N</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-19-10\"><a id=\"__codelineno-19-10\" name=\"__codelineno-19-10\" href=\"#__codelineno-19-10\"></a><span class=\"w\">        </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">calculateSum512</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// Create a matrix of 512 columns</span>\n</span><span id=\"__span-19-11\"><a id=\"__codelineno-19-11\" name=\"__codelineno-19-11\" href=\"#__codelineno-19-11\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-19-12\"><a id=\"__codelineno-19-12\" name=\"__codelineno-19-12\" href=\"#__codelineno-19-12\"></a><span class=\"w\">    </span><span class=\"nx\">res</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">sum</span>\n</span><span id=\"__span-19-13\"><a id=\"__codelineno-19-13\" name=\"__codelineno-19-13\" href=\"#__codelineno-19-13\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-19-14\"><a id=\"__codelineno-19-14\" name=\"__codelineno-19-14\" href=\"#__codelineno-19-14\"></a>\n</span><span id=\"__span-19-15\"><a id=\"__codelineno-19-15\" name=\"__codelineno-19-15\" href=\"#__codelineno-19-15\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">BenchmarkCalculateSum513</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">B</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-19-16\"><a id=\"__codelineno-19-16\" name=\"__codelineno-19-16\" href=\"#__codelineno-19-16\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"kt\">int64</span>\n</span><span id=\"__span-19-17\"><a id=\"__codelineno-19-17\" name=\"__codelineno-19-17\" href=\"#__codelineno-19-17\"></a><span class=\"w\">    </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">createMatrix513</span><span class=\"p\">(</span><span class=\"nx\">rows</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// Create a matrix of 513 columns</span>\n</span><span id=\"__span-19-18\"><a id=\"__codelineno-19-18\" name=\"__codelineno-19-18\" href=\"#__codelineno-19-18\"></a><span class=\"w\">    </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">ResetTimer</span><span class=\"p\">()</span>\n</span><span id=\"__span-19-19\"><a id=\"__codelineno-19-19\" name=\"__codelineno-19-19\" href=\"#__codelineno-19-19\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">N</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-19-20\"><a id=\"__codelineno-19-20\" name=\"__codelineno-19-20\" href=\"#__codelineno-19-20\"></a><span class=\"w\">        </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">calculateSum513</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// Calculate the sum</span>\n</span><span id=\"__span-19-21\"><a id=\"__codelineno-19-21\" name=\"__codelineno-19-21\" href=\"#__codelineno-19-21\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-19-22\"><a id=\"__codelineno-19-22\" name=\"__codelineno-19-22\" href=\"#__codelineno-19-22\"></a><span class=\"w\">    </span><span class=\"nx\">res</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">sum</span>\n</span><span id=\"__span-19-23\"><a id=\"__codelineno-19-23\" name=\"__codelineno-19-23\" href=\"#__codelineno-19-23\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>We want to create the matrix only once, to limit the footprint on the results. Therefore, we call <code>createMatrix512</code> and <code>createMatrix513</code> outside of the loop. We may expect the results to be similar as again we only want to iterate on the first eight columns, but this isn’t the case (on my machine):</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-20-1\"><a id=\"__codelineno-20-1\" name=\"__codelineno-20-1\" href=\"#__codelineno-20-1\"></a>cpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\n</span><span id=\"__span-20-2\"><a id=\"__codelineno-20-2\" name=\"__codelineno-20-2\" href=\"#__codelineno-20-2\"></a>BenchmarkCalculateSum512-4        81854             15073 ns/op\n</span><span id=\"__span-20-3\"><a id=\"__codelineno-20-3\" name=\"__codelineno-20-3\" href=\"#__codelineno-20-3\"></a>BenchmarkCalculateSum513-4       161479              7358 ns/op\n</span></code></pre></div>\n<p>The second benchmark with 513 columns is about 50% faster. Again, because we iterate only over the first eight columns, this result is quite surprising.</p>\n<p>To understand this difference, we need to understand the basics of CPU caches. In a nutshell, a CPU is composed of different caches (usually L1, L2, and L3). These caches reduce the average cost of accessing data from the main memory. In some conditions, the CPU can fetch data from the main memory and copy it to L1. In this case, the CPU tries to fetch into L1 the matrix’s subset that <code>calculateSum</code> is interested in (the first eight columns of each row). However, the matrix fits in memory in one case (513 columns) but not in the other case (512 columns).</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>This isn’t in the scope of this post to explain why, but we look at this problem in 100 Go Mistakes, mistake #91: “<a href=\"https://100go.co#not-understanding-cpu-caches-91\">Not understanding CPU caches.</a>”</p>\n</details>\n<p>Coming back to the benchmark, the main issue is that we keep reusing the same matrix in both cases. Because the function is repeated thousands of times, we don’t measure the function’s execution when it receives a plain new matrix. Instead, we measure a function that gets a matrix that already has a subset of the cells present in the cache. Therefore, because <code>calculateSum513</code> leads to fewer cache misses, it has a better execution time.</p>\n<p>This is an example of the observer effect. Because we keep observing a repeatedly called CPU-bound function, CPU caching may come into play and significantly affect the results. In this example, to prevent this effect, we should create a matrix during each test instead of reusing one:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-21-1\"><a id=\"__codelineno-21-1\" name=\"__codelineno-21-1\" href=\"#__codelineno-21-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">BenchmarkCalculateSum512</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">B</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-21-2\"><a id=\"__codelineno-21-2\" name=\"__codelineno-21-2\" href=\"#__codelineno-21-2\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"kt\">int64</span>\n</span><span id=\"__span-21-3\"><a id=\"__codelineno-21-3\" name=\"__codelineno-21-3\" href=\"#__codelineno-21-3\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">N</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-21-4\"><a id=\"__codelineno-21-4\" name=\"__codelineno-21-4\" href=\"#__codelineno-21-4\"></a><span class=\"w\">        </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">StopTimer</span><span class=\"p\">()</span>\n</span><span id=\"__span-21-5\"><a id=\"__codelineno-21-5\" name=\"__codelineno-21-5\" href=\"#__codelineno-21-5\"></a><span class=\"w\">        </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">createMatrix512</span><span class=\"p\">(</span><span class=\"nx\">rows</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// Create a new matrix during each loop iteration</span>\n</span><span id=\"__span-21-6\"><a id=\"__codelineno-21-6\" name=\"__codelineno-21-6\" href=\"#__codelineno-21-6\"></a><span class=\"w\">        </span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">StartTimer</span><span class=\"p\">()</span>\n</span><span id=\"__span-21-7\"><a id=\"__codelineno-21-7\" name=\"__codelineno-21-7\" href=\"#__codelineno-21-7\"></a><span class=\"w\">        </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">calculateSum512</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span>\n</span><span id=\"__span-21-8\"><a id=\"__codelineno-21-8\" name=\"__codelineno-21-8\" href=\"#__codelineno-21-8\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-21-9\"><a id=\"__codelineno-21-9\" name=\"__codelineno-21-9\" href=\"#__codelineno-21-9\"></a><span class=\"w\">    </span><span class=\"nx\">res</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">sum</span>\n</span><span id=\"__span-21-10\"><a id=\"__codelineno-21-10\" name=\"__codelineno-21-10\" href=\"#__codelineno-21-10\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>A new matrix is now created during each loop iteration. If we run the benchmark again (and adjust <code>benchtime</code> — otherwise, it takes too long to execute), the results are closer to each other:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-22-1\"><a id=\"__codelineno-22-1\" name=\"__codelineno-22-1\" href=\"#__codelineno-22-1\"></a>cpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\n</span><span id=\"__span-22-2\"><a id=\"__codelineno-22-2\" name=\"__codelineno-22-2\" href=\"#__codelineno-22-2\"></a>BenchmarkCalculateSum512-4         1116             33547 ns/op\n</span><span id=\"__span-22-3\"><a id=\"__codelineno-22-3\" name=\"__codelineno-22-3\" href=\"#__codelineno-22-3\"></a>BenchmarkCalculateSum513-4          998             35507 ns/op\n</span></code></pre></div>\n<p>Instead of making the incorrect assumption that calculateSum513 is faster, we see that both benchmarks lead to similar results when receiving a new matrix.</p>\n<p>As we have seen in this post, because we were reusing the same matrix, CPU caches significantly impacted the results. To prevent this, we had to create a new matrix during each loop iteration. In general, we should remember that observing a function under test may lead to significant differences in results, especially in the context of micro-benchmarks of CPU-bound functions where low-level optimizations matter. Forcing a benchmark to re-create data during each iteration can be a good way to prevent this effect.</p>\n\n\n\n\n\n\n\n  \n  \n\n\n\n  \n\n\n  \n\n\n\n<h2 id=\"__comments\">Comments</h2>\n<!-- Insert generated snippet here -->\n<script src=\"https://giscus.app/client.js\" data-repo=\"teivah/100-go-mistakes\" data-repo-id=\"MDEwOlJlcG9zaXRvcnkzMjA4MTg5NjI=\" data-category=\"Discussions\" data-category-id=\"DIC_kwDOEx9PEs4CZQUm\" data-mapping=\"pathname\" data-strict=\"0\" data-reactions-enabled=\"1\" data-emit-metadata=\"0\" data-input-position=\"bottom\" data-theme=\"preferred_color_scheme\" data-lang=\"en\" crossorigin=\"anonymous\" async>\n</script>\n<!-- Synchronize Giscus theme with palette -->\n<script>\n  var giscus = document.querySelector(\"script[src*=giscus]\")\n\n  // Set palette on initial load\n  var palette = __md_get(\"__palette\")\n  if (palette && typeof palette.color === \"object\") {\n    var theme = palette.color.scheme === \"slate\"\n        ? \"transparent_dark\"\n        : \"light\"\n\n    // Instruct Giscus to set theme\n    giscus.setAttribute(\"data-theme\", theme)\n  }\n\n  // Register event handlers after documented loaded\n  document.addEventListener(\"DOMContentLoaded\", function() {\n    var ref = document.querySelector(\"[data-md-component=palette]\")\n    ref.addEventListener(\"change\", function() {\n      var palette = __md_get(\"__palette\")\n      if (palette && typeof palette.color === \"object\") {\n        var theme = palette.color.scheme === \"slate\"\n            ? \"transparent_dark\"\n            : \"light\"\n\n        // Instruct Giscus to change theme\n        var frame = document.querySelector(\".giscus-frame\")\n        frame.contentWindow.postMessage(\n            { giscus: { setConfig: { theme } } },\n            \"https://giscus.app\"\n        )\n      }\n    })\n  })\n</script>\n\n                \n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright © 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"></path></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \"..\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"../assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"../assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  \n<script id=\"init-glightbox\">const lightbox = GLightbox({\"touchNavigation\": true, \"loop\": false, \"zoomable\": true, \"draggable\": true, \"openEffect\": \"zoom\", \"closeEffect\": \"zoom\", \"slideEffect\": \"slide\"});\ndocument$.subscribe(()=>{ lightbox.reload(); });\n</script></body></html>"
  },
  {
    "path": "site/9-generics/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\" class=\"no-js\"><head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n      \n      \n        <link rel=\"canonical\" href=\"https://100go.co/9-generics/\">\n      \n      \n        <link rel=\"prev\" href=\"../5-interface-pollution/\">\n      \n      \n        <link rel=\"next\" href=\"../20-slice/\">\n      \n      \n      <link rel=\"icon\" href=\"../img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>Being confused about when to use generics (#9) - 100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"../assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\"..\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n      \n        <meta property=\"og:type\" content=\"website\">\n      \n        <meta property=\"og:title\" content=\"Being confused about when to use generics (#9) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta property=\"og:description\" content=\"None\">\n      \n        <meta property=\"og:image\" content=\"https://100go.co/assets/images/social/9-generics.png\">\n      \n        <meta property=\"og:image:type\" content=\"image/png\">\n      \n        <meta property=\"og:image:width\" content=\"1200\">\n      \n        <meta property=\"og:image:height\" content=\"630\">\n      \n        <meta property=\"og:url\" content=\"https://100go.co/9-generics/\">\n      \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n      \n        <meta name=\"twitter:title\" content=\"Being confused about when to use generics (#9) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta name=\"twitter:description\" content=\"None\">\n      \n        <meta name=\"twitter:image\" content=\"https://100go.co/assets/images/social/9-generics.png\">\n      \n    \n    \n  <link href=\"../assets/stylesheets/glightbox.min.css\" rel=\"stylesheet\"><script src=\"../assets/javascripts/glightbox.min.js\"></script><style id=\"glightbox-style\">\n            html.glightbox-open { overflow: initial; height: 100%; }\n            .gslide-title { margin-top: 0px; user-select: text; }\n            .gslide-desc { color: #666; user-select: text; }\n            .gslide-image img { background: white; }\n            .gscrollbar-fixer { padding-right: 15px; }\n            .gdesc-inner { font-size: 0.75rem; }\n            body[data-md-color-scheme=\"slate\"] .gdesc-inner { background: var(--md-default-bg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-title { color: var(--md-default-fg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-desc { color: var(--md-default-fg-color); }\n        </style></head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n        \n        <a href=\"#being-confused-about-when-to-use-generics\" class=\"md-skip\">\n          Skip to content\n        </a>\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"></path></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              Being confused about when to use generics (#9)\n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"></path></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"></path></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"></path></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n    \n  \n  \n    \n    \n      <li class=\"md-tabs__item md-tabs__item--active\">\n        <a href=\"..\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"../book/\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n        \n        \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"..\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1_2\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../5-interface-pollution/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    <li class=\"md-nav__item md-nav__item--active\">\n      \n      <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n      \n      \n        \n      \n      \n        <label class=\"md-nav__link md-nav__link--active\" for=\"__toc\">\n          \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n          <span class=\"md-nav__icon md-icon\"></span>\n        </label>\n      \n      <a href=\"./\" class=\"md-nav__link md-nav__link--active\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n      \n        \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#concepts\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Concepts\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#common-uses-and-misuses\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Common uses and misuses\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#conclusion\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Conclusion\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../20-slice/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../28-maps-memory-leaks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../56-concurrency-faster/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../89-benchmarks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../92-false-sharing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../98-profiling-execution-tracing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_3\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../zh/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../ja/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../pt-br/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../book/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../chapter-1/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../external/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\" hidden>\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#concepts\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Concepts\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#common-uses-and-misuses\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Common uses and misuses\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#conclusion\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Conclusion\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n                  \n  \n\n\n\n  \n  \n\n\n<h1 id=\"being-confused-about-when-to-use-generics\">Being confused about when to use generics</h1>\n<p>Generics is a fresh addition to the language. In a nutshell, it allows writing code with types that can be specified later and instantiated when needed. However, it can be pretty easy to be confused about when to use generics and when not to. Throughout this post, we will describe the concept of generics in Go and then delve into common use and misuses.</p>\n<h2 id=\"concepts\">Concepts</h2>\n<p>Consider the following function that extracts all the keys from a <code>map[string]int</code> type:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-0-1\"><a id=\"__codelineno-0-1\" name=\"__codelineno-0-1\" href=\"#__codelineno-0-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">getKeys</span><span class=\"p\">(</span><span class=\"nx\">m</span><span class=\"w\"> </span><span class=\"kd\">map</span><span class=\"p\">[</span><span class=\"kt\">string</span><span class=\"p\">]</span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">string</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-0-2\"><a id=\"__codelineno-0-2\" name=\"__codelineno-0-2\" href=\"#__codelineno-0-2\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">keys</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">string</span>\n</span><span id=\"__span-0-3\"><a id=\"__codelineno-0-3\" name=\"__codelineno-0-3\" href=\"#__codelineno-0-3\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">k</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">m</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-0-4\"><a id=\"__codelineno-0-4\" name=\"__codelineno-0-4\" href=\"#__codelineno-0-4\"></a><span class=\"w\">        </span><span class=\"nx\">keys</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">keys</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">k</span><span class=\"p\">)</span>\n</span><span id=\"__span-0-5\"><a id=\"__codelineno-0-5\" name=\"__codelineno-0-5\" href=\"#__codelineno-0-5\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-0-6\"><a id=\"__codelineno-0-6\" name=\"__codelineno-0-6\" href=\"#__codelineno-0-6\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">keys</span>\n</span><span id=\"__span-0-7\"><a id=\"__codelineno-0-7\" name=\"__codelineno-0-7\" href=\"#__codelineno-0-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>What if we would like to use a similar feature for another map type such as a <code>map[int]string</code>? Before generics, Go developers had a couple of options: using code generation, reflection, or duplicating code.</p>\n<p>For example, we could write two functions, one for each map type, or even try to extend <code>getKeys</code> to accept different map types:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-1-1\"><a id=\"__codelineno-1-1\" name=\"__codelineno-1-1\" href=\"#__codelineno-1-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">getKeys</span><span class=\"p\">(</span><span class=\"nx\">m</span><span class=\"w\"> </span><span class=\"kt\">any</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">([]</span><span class=\"kt\">any</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-2\"><a id=\"__codelineno-1-2\" name=\"__codelineno-1-2\" href=\"#__codelineno-1-2\"></a><span class=\"w\">    </span><span class=\"k\">switch</span><span class=\"w\"> </span><span class=\"nx\">t</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">m</span><span class=\"p\">.(</span><span class=\"kd\">type</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-3\"><a id=\"__codelineno-1-3\" name=\"__codelineno-1-3\" href=\"#__codelineno-1-3\"></a><span class=\"w\">    </span><span class=\"k\">default</span><span class=\"p\">:</span>\n</span><span id=\"__span-1-4\"><a id=\"__codelineno-1-4\" name=\"__codelineno-1-4\" href=\"#__codelineno-1-4\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Errorf</span><span class=\"p\">(</span><span class=\"s\">\"unknown type: %T\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">t</span><span class=\"p\">)</span>\n</span><span id=\"__span-1-5\"><a id=\"__codelineno-1-5\" name=\"__codelineno-1-5\" href=\"#__codelineno-1-5\"></a><span class=\"w\">    </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"kd\">map</span><span class=\"p\">[</span><span class=\"kt\">string</span><span class=\"p\">]</span><span class=\"kt\">int</span><span class=\"p\">:</span>\n</span><span id=\"__span-1-6\"><a id=\"__codelineno-1-6\" name=\"__codelineno-1-6\" href=\"#__codelineno-1-6\"></a><span class=\"w\">        </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">keys</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">any</span>\n</span><span id=\"__span-1-7\"><a id=\"__codelineno-1-7\" name=\"__codelineno-1-7\" href=\"#__codelineno-1-7\"></a><span class=\"w\">        </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">k</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">t</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-8\"><a id=\"__codelineno-1-8\" name=\"__codelineno-1-8\" href=\"#__codelineno-1-8\"></a><span class=\"w\">            </span><span class=\"nx\">keys</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">keys</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">k</span><span class=\"p\">)</span>\n</span><span id=\"__span-1-9\"><a id=\"__codelineno-1-9\" name=\"__codelineno-1-9\" href=\"#__codelineno-1-9\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-1-10\"><a id=\"__codelineno-1-10\" name=\"__codelineno-1-10\" href=\"#__codelineno-1-10\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">keys</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-1-11\"><a id=\"__codelineno-1-11\" name=\"__codelineno-1-11\" href=\"#__codelineno-1-11\"></a><span class=\"w\">    </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"kd\">map</span><span class=\"p\">[</span><span class=\"kt\">int</span><span class=\"p\">]</span><span class=\"kt\">string</span><span class=\"p\">:</span>\n</span><span id=\"__span-1-12\"><a id=\"__codelineno-1-12\" name=\"__codelineno-1-12\" href=\"#__codelineno-1-12\"></a><span class=\"w\">        </span><span class=\"c1\">// Copy the extraction logic</span>\n</span><span id=\"__span-1-13\"><a id=\"__codelineno-1-13\" name=\"__codelineno-1-13\" href=\"#__codelineno-1-13\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-1-14\"><a id=\"__codelineno-1-14\" name=\"__codelineno-1-14\" href=\"#__codelineno-1-14\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>We can start noticing a couple of issues:</p>\n<ul>\n<li>First, it increases boilerplate code. Indeed, whenever we want to add a case, it will require duplicating the <code>range</code> loop.</li>\n<li>Meanwhile, the function now accepts an empty interface, which means we are losing some of the benefits of Go being a typed language. Indeed, checking whether a type is supported is done at runtime instead of compile-time. Hence, we also need to return an error if the provided type is unknown.</li>\n<li>Last but not least, as the key type can be either <code>int</code> or <code>string</code>, we are obliged to return a slice of empty interfaces to factor out key types. This approach increases the effort on the caller-side as the client may also have to perform a type check of the keys or extra conversion.</li>\n</ul>\n<p>Thanks to generics, we can now refactor this code using type parameters.</p>\n<p>Type parameters are generic types we can use with functions and types. For example, the following function accepts a type parameter:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-2-1\"><a id=\"__codelineno-2-1\" name=\"__codelineno-2-1\" href=\"#__codelineno-2-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">foo</span><span class=\"p\">[</span><span class=\"nx\">T</span><span class=\"w\"> </span><span class=\"kt\">any</span><span class=\"p\">](</span><span class=\"nx\">t</span><span class=\"w\"> </span><span class=\"nx\">T</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-2-2\"><a id=\"__codelineno-2-2\" name=\"__codelineno-2-2\" href=\"#__codelineno-2-2\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-2-3\"><a id=\"__codelineno-2-3\" name=\"__codelineno-2-3\" href=\"#__codelineno-2-3\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>When calling <code>foo</code>, we will pass a type argument of any type. Passing a type argument is called instantiation because the work is done at compile time which keeps type safety as part of the core language features and avoids runtime overheads.</p>\n<p>Let’s get back to the <code>getKeys</code> function and use type parameters to write a generic version that would accept any kind of map:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-3-1\"><a id=\"__codelineno-3-1\" name=\"__codelineno-3-1\" href=\"#__codelineno-3-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">getKeys</span><span class=\"p\">[</span><span class=\"nx\">K</span><span class=\"w\"> </span><span class=\"kt\">comparable</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">V</span><span class=\"w\"> </span><span class=\"kt\">any</span><span class=\"p\">](</span><span class=\"nx\">m</span><span class=\"w\"> </span><span class=\"kd\">map</span><span class=\"p\">[</span><span class=\"nx\">K</span><span class=\"p\">]</span><span class=\"nx\">V</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"nx\">K</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-3-2\"><a id=\"__codelineno-3-2\" name=\"__codelineno-3-2\" href=\"#__codelineno-3-2\"></a><span class=\"w\">  </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">keys</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"nx\">K</span>\n</span><span id=\"__span-3-3\"><a id=\"__codelineno-3-3\" name=\"__codelineno-3-3\" href=\"#__codelineno-3-3\"></a><span class=\"w\">  </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">k</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">m</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-3-4\"><a id=\"__codelineno-3-4\" name=\"__codelineno-3-4\" href=\"#__codelineno-3-4\"></a><span class=\"w\">    </span><span class=\"nx\">keys</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">keys</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">k</span><span class=\"p\">)</span>\n</span><span id=\"__span-3-5\"><a id=\"__codelineno-3-5\" name=\"__codelineno-3-5\" href=\"#__codelineno-3-5\"></a><span class=\"w\">  </span><span class=\"p\">}</span>\n</span><span id=\"__span-3-6\"><a id=\"__codelineno-3-6\" name=\"__codelineno-3-6\" href=\"#__codelineno-3-6\"></a><span class=\"w\">  </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">keys</span>\n</span><span id=\"__span-3-7\"><a id=\"__codelineno-3-7\" name=\"__codelineno-3-7\" href=\"#__codelineno-3-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>To handle the map, we defined two kinds of type parameters. First, the values can be of any type: <code>V any</code>. However, in Go, the map keys can’t be of any type. For example, we cannot use slices:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-4-1\"><a id=\"__codelineno-4-1\" name=\"__codelineno-4-1\" href=\"#__codelineno-4-1\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">m</span><span class=\"w\"> </span><span class=\"kd\">map</span><span class=\"p\">[[]</span><span class=\"kt\">byte</span><span class=\"p\">]</span><span class=\"kt\">int</span>\n</span></code></pre></div>\n<p>This code leads to a compilation error: <code>invalid map key type []byte</code>. Therefore, instead of accepting any key type, we are obliged to restrict type arguments so that the key type meets specific requirements. Here, being comparable (we can use <code>==</code> or <code>!=</code>). Hence, we defined <code>K</code> as <code>comparable</code> instead of <code>any</code>.</p>\n<p>Restricting type arguments to match specific requirements is called a constraint. A constraint is an interface type that can contain:</p>\n<ul>\n<li>A set of behaviors (methods)</li>\n<li>But also arbitrary type</li>\n</ul>\n<p>Let’s see a concrete example for the latter. Imagine we don’t want to accept any <code>comparable</code> type for map key type. For instance, we would like to restrict it to either <code>int</code> or <code>string</code> types. We can define a custom constraint this way:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-5-1\"><a id=\"__codelineno-5-1\" name=\"__codelineno-5-1\" href=\"#__codelineno-5-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">customConstraint</span><span class=\"w\"> </span><span class=\"kd\">interface</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-2\"><a id=\"__codelineno-5-2\" name=\"__codelineno-5-2\" href=\"#__codelineno-5-2\"></a><span class=\"w\">   </span><span class=\"o\">~</span><span class=\"kt\">int</span><span class=\"w\"> </span><span class=\"o\">|</span><span class=\"w\"> </span><span class=\"o\">~</span><span class=\"kt\">string</span><span class=\"w\"> </span><span class=\"c1\">// Define a custom type that will restrict types to int and string</span>\n</span><span id=\"__span-5-3\"><a id=\"__codelineno-5-3\" name=\"__codelineno-5-3\" href=\"#__codelineno-5-3\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-5-4\"><a id=\"__codelineno-5-4\" name=\"__codelineno-5-4\" href=\"#__codelineno-5-4\"></a>\n</span><span id=\"__span-5-5\"><a id=\"__codelineno-5-5\" name=\"__codelineno-5-5\" href=\"#__codelineno-5-5\"></a><span class=\"c1\">// Change the type parameter K to be custom</span>\n</span><span id=\"__span-5-6\"><a id=\"__codelineno-5-6\" name=\"__codelineno-5-6\" href=\"#__codelineno-5-6\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">getKeys</span><span class=\"p\">[</span><span class=\"nx\">K</span><span class=\"w\"> </span><span class=\"nx\">customConstraint</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">V</span><span class=\"w\"> </span><span class=\"kt\">any</span><span class=\"p\">](</span><span class=\"nx\">m</span><span class=\"w\"> </span><span class=\"kd\">map</span><span class=\"p\">[</span><span class=\"nx\">K</span><span class=\"p\">]</span><span class=\"nx\">V</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"nx\">K</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-7\"><a id=\"__codelineno-5-7\" name=\"__codelineno-5-7\" href=\"#__codelineno-5-7\"></a><span class=\"w\">   </span><span class=\"c1\">// Same implementation</span>\n</span><span id=\"__span-5-8\"><a id=\"__codelineno-5-8\" name=\"__codelineno-5-8\" href=\"#__codelineno-5-8\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>First, we define a <code>customConstraint</code> interface to restrict the types to be either <code>int</code> or <code>string</code> using the union operator <code>|</code> (we will discuss the use of <code>~</code> a bit later). Then, <code>K</code> is now a <code>customConstraint</code> instead of a <code>comparable</code> as before.</p>\n<p>Now, the signature of <code>getKeys</code> enforces that we can call it with a map of any value type, but the key type has to be an <code>int</code> or a <code>string</code>. For example, on the caller-side:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-6-1\"><a id=\"__codelineno-6-1\" name=\"__codelineno-6-1\" href=\"#__codelineno-6-1\"></a><span class=\"nx\">m</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"kd\">map</span><span class=\"p\">[</span><span class=\"kt\">string</span><span class=\"p\">]</span><span class=\"kt\">int</span><span class=\"p\">{</span>\n</span><span id=\"__span-6-2\"><a id=\"__codelineno-6-2\" name=\"__codelineno-6-2\" href=\"#__codelineno-6-2\"></a><span class=\"w\">   </span><span class=\"s\">\"one\"</span><span class=\"p\">:</span><span class=\"w\">   </span><span class=\"mi\">1</span><span class=\"p\">,</span>\n</span><span id=\"__span-6-3\"><a id=\"__codelineno-6-3\" name=\"__codelineno-6-3\" href=\"#__codelineno-6-3\"></a><span class=\"w\">   </span><span class=\"s\">\"two\"</span><span class=\"p\">:</span><span class=\"w\">   </span><span class=\"mi\">2</span><span class=\"p\">,</span>\n</span><span id=\"__span-6-4\"><a id=\"__codelineno-6-4\" name=\"__codelineno-6-4\" href=\"#__codelineno-6-4\"></a><span class=\"w\">   </span><span class=\"s\">\"three\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"mi\">3</span><span class=\"p\">,</span>\n</span><span id=\"__span-6-5\"><a id=\"__codelineno-6-5\" name=\"__codelineno-6-5\" href=\"#__codelineno-6-5\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-6-6\"><a id=\"__codelineno-6-6\" name=\"__codelineno-6-6\" href=\"#__codelineno-6-6\"></a><span class=\"nx\">keys</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">getKeys</span><span class=\"p\">(</span><span class=\"nx\">m</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>Note that Go can infer that <code>getKeys</code> is called with a <code>string</code> type argument. The previous call was similar to this:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-7-1\"><a id=\"__codelineno-7-1\" name=\"__codelineno-7-1\" href=\"#__codelineno-7-1\"></a><span class=\"nx\">keys</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">getKeys</span><span class=\"p\">[</span><span class=\"kt\">string</span><span class=\"p\">](</span><span class=\"nx\">m</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>What’s the difference between a constraint using <code>~int</code> or <code>int</code>? Using <code>int</code> restricts it to that type, whereas <code>~int</code> restricts all the types whose underlying type is an <code>int</code>.</p>\n<p>To illustrate it, let’s imagine a constraint where we would like to restrict a type to any <code>int</code> type implementing the <code>String() string</code> method:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-8-1\"><a id=\"__codelineno-8-1\" name=\"__codelineno-8-1\" href=\"#__codelineno-8-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">customConstraint</span><span class=\"w\"> </span><span class=\"kd\">interface</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-8-2\"><a id=\"__codelineno-8-2\" name=\"__codelineno-8-2\" href=\"#__codelineno-8-2\"></a><span class=\"w\">   </span><span class=\"o\">~</span><span class=\"kt\">int</span>\n</span><span id=\"__span-8-3\"><a id=\"__codelineno-8-3\" name=\"__codelineno-8-3\" href=\"#__codelineno-8-3\"></a><span class=\"w\">   </span><span class=\"nx\">String</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">string</span>\n</span><span id=\"__span-8-4\"><a id=\"__codelineno-8-4\" name=\"__codelineno-8-4\" href=\"#__codelineno-8-4\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Using this constraint will restrict type arguments to custom types like this one:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-9-1\"><a id=\"__codelineno-9-1\" name=\"__codelineno-9-1\" href=\"#__codelineno-9-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">customInt</span><span class=\"w\"> </span><span class=\"kt\">int</span>\n</span><span id=\"__span-9-2\"><a id=\"__codelineno-9-2\" name=\"__codelineno-9-2\" href=\"#__codelineno-9-2\"></a>\n</span><span id=\"__span-9-3\"><a id=\"__codelineno-9-3\" name=\"__codelineno-9-3\" href=\"#__codelineno-9-3\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"nx\">customInt</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">String</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-9-4\"><a id=\"__codelineno-9-4\" name=\"__codelineno-9-4\" href=\"#__codelineno-9-4\"></a><span class=\"w\">   </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">strconv</span><span class=\"p\">.</span><span class=\"nx\">Itoa</span><span class=\"p\">(</span><span class=\"nb\">int</span><span class=\"p\">(</span><span class=\"nx\">i</span><span class=\"p\">))</span>\n</span><span id=\"__span-9-5\"><a id=\"__codelineno-9-5\" name=\"__codelineno-9-5\" href=\"#__codelineno-9-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>As <code>customInt</code> is an <code>int</code> and implements the <code>String() string</code> method, the <code>customInt</code> type satisfies the constraint defined.</p>\n<p>However, if we change the constraint to contain an <code>int</code> instead of an <code>~int</code>, using <code>customInt</code> would lead to a compilation error because the <code>int</code> type doesn’t implement <code>String() string</code>.</p>\n</details>\n<p>Let’s also note the <code>constraints</code> package contains a set of common constraints such as <code>Signed</code> that includes all the signed integer types. Let’s ensure that a constraint doesn’t already exist in this package before creating a new one.</p>\n<p>So far, we have discussed examples using generics for functions. However, we can also use generics with data structures.</p>\n<p>For example, we will create a linked list containing values of any type. Meanwhile, we will write an <code>Add</code> method to append a node:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-10-1\"><a id=\"__codelineno-10-1\" name=\"__codelineno-10-1\" href=\"#__codelineno-10-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Node</span><span class=\"p\">[</span><span class=\"nx\">T</span><span class=\"w\"> </span><span class=\"kt\">any</span><span class=\"p\">]</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Use type parameter</span>\n</span><span id=\"__span-10-2\"><a id=\"__codelineno-10-2\" name=\"__codelineno-10-2\" href=\"#__codelineno-10-2\"></a><span class=\"w\">   </span><span class=\"nx\">Val</span><span class=\"w\">  </span><span class=\"nx\">T</span>\n</span><span id=\"__span-10-3\"><a id=\"__codelineno-10-3\" name=\"__codelineno-10-3\" href=\"#__codelineno-10-3\"></a><span class=\"w\">   </span><span class=\"nx\">next</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Node</span><span class=\"p\">[</span><span class=\"nx\">T</span><span class=\"p\">]</span>\n</span><span id=\"__span-10-4\"><a id=\"__codelineno-10-4\" name=\"__codelineno-10-4\" href=\"#__codelineno-10-4\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-10-5\"><a id=\"__codelineno-10-5\" name=\"__codelineno-10-5\" href=\"#__codelineno-10-5\"></a>\n</span><span id=\"__span-10-6\"><a id=\"__codelineno-10-6\" name=\"__codelineno-10-6\" href=\"#__codelineno-10-6\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">n</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Node</span><span class=\"p\">[</span><span class=\"nx\">T</span><span class=\"p\">])</span><span class=\"w\"> </span><span class=\"nx\">Add</span><span class=\"p\">(</span><span class=\"nx\">next</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Node</span><span class=\"p\">[</span><span class=\"nx\">T</span><span class=\"p\">])</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Instantiate type receiver</span>\n</span><span id=\"__span-10-7\"><a id=\"__codelineno-10-7\" name=\"__codelineno-10-7\" href=\"#__codelineno-10-7\"></a><span class=\"w\">   </span><span class=\"nx\">n</span><span class=\"p\">.</span><span class=\"nx\">next</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">next</span>\n</span><span id=\"__span-10-8\"><a id=\"__codelineno-10-8\" name=\"__codelineno-10-8\" href=\"#__codelineno-10-8\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>We use type parameters to define <code>T</code> and use both fields in <code>Node</code>. Regarding the method, the receiver is instantiated. Indeed, because <code>Node</code> is generic, it has to follow also the type parameter defined.</p>\n<p>One last thing to note about type parameters: they can’t be used on methods, only on functions. For example, the following method wouldn’t compile:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-11-1\"><a id=\"__codelineno-11-1\" name=\"__codelineno-11-1\" href=\"#__codelineno-11-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Foo</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{}</span>\n</span><span id=\"__span-11-2\"><a id=\"__codelineno-11-2\" name=\"__codelineno-11-2\" href=\"#__codelineno-11-2\"></a>\n</span><span id=\"__span-11-3\"><a id=\"__codelineno-11-3\" name=\"__codelineno-11-3\" href=\"#__codelineno-11-3\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">Foo</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">bar</span><span class=\"p\">[</span><span class=\"nx\">T</span><span class=\"w\"> </span><span class=\"kt\">any</span><span class=\"p\">](</span><span class=\"nx\">t</span><span class=\"w\"> </span><span class=\"nx\">T</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{}</span>\n</span></code></pre></div>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-12-1\"><a id=\"__codelineno-12-1\" name=\"__codelineno-12-1\" href=\"#__codelineno-12-1\"></a>./main.go:29:15: methods cannot have type parameters\n</span></code></pre></div>\n<p>Now, let’s delve into concrete cases where we should and shouldn’t use generics.</p>\n<h2 id=\"common-uses-and-misuses\">Common uses and misuses</h2>\n<p>So when are generics useful? Let’s discuss a couple of common uses where generics <strong>are</strong> recommended:</p>\n<ul>\n<li>Data structures. For example, we can use generics to factor out the element type if we implement a binary tree, a linked list, or a heap.</li>\n<li>Functions working with slices, maps, and channels of any type. For example, a function to merge two channels would work with any channel type. Hence, we could use type parameters to factor out the channel type:</li>\n</ul>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-13-1\"><a id=\"__codelineno-13-1\" name=\"__codelineno-13-1\" href=\"#__codelineno-13-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">merge</span><span class=\"p\">[</span><span class=\"nx\">T</span><span class=\"w\"> </span><span class=\"kt\">any</span><span class=\"p\">](</span><span class=\"nx\">ch1</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">ch2</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"nx\">T</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"nx\">T</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-2\"><a id=\"__codelineno-13-2\" name=\"__codelineno-13-2\" href=\"#__codelineno-13-2\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-13-3\"><a id=\"__codelineno-13-3\" name=\"__codelineno-13-3\" href=\"#__codelineno-13-3\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<ul>\n<li>Meanwhile, instead of factoring out a type, we can factor out behaviors. For example, the <code>sort</code> package contains functions to sort different slice types such as <code>sort.Ints</code> or <code>sort.Float64s</code>. Using type parameters, we can factor out the sorting behaviors that rely on three methods, <code>Len</code>, <code>Less</code>, and <code>Swap</code>:</li>\n</ul>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-14-1\"><a id=\"__codelineno-14-1\" name=\"__codelineno-14-1\" href=\"#__codelineno-14-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">sliceFn</span><span class=\"p\">[</span><span class=\"nx\">T</span><span class=\"w\"> </span><span class=\"kt\">any</span><span class=\"p\">]</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Use type parameter</span>\n</span><span id=\"__span-14-2\"><a id=\"__codelineno-14-2\" name=\"__codelineno-14-2\" href=\"#__codelineno-14-2\"></a><span class=\"w\">   </span><span class=\"nx\">s</span><span class=\"w\">       </span><span class=\"p\">[]</span><span class=\"nx\">T</span>\n</span><span id=\"__span-14-3\"><a id=\"__codelineno-14-3\" name=\"__codelineno-14-3\" href=\"#__codelineno-14-3\"></a><span class=\"w\">   </span><span class=\"nx\">compare</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">(</span><span class=\"nx\">T</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">T</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">bool</span><span class=\"w\"> </span><span class=\"c1\">// Compare two T elements</span>\n</span><span id=\"__span-14-4\"><a id=\"__codelineno-14-4\" name=\"__codelineno-14-4\" href=\"#__codelineno-14-4\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-14-5\"><a id=\"__codelineno-14-5\" name=\"__codelineno-14-5\" href=\"#__codelineno-14-5\"></a>\n</span><span id=\"__span-14-6\"><a id=\"__codelineno-14-6\" name=\"__codelineno-14-6\" href=\"#__codelineno-14-6\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"nx\">sliceFn</span><span class=\"p\">[</span><span class=\"nx\">T</span><span class=\"p\">])</span><span class=\"w\"> </span><span class=\"nx\">Len</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"w\">           </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">.</span><span class=\"nx\">s</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">}</span>\n</span><span id=\"__span-14-7\"><a id=\"__codelineno-14-7\" name=\"__codelineno-14-7\" href=\"#__codelineno-14-7\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"nx\">sliceFn</span><span class=\"p\">[</span><span class=\"nx\">T</span><span class=\"p\">])</span><span class=\"w\"> </span><span class=\"nx\">Less</span><span class=\"p\">(</span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">j</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">bool</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"p\">.</span><span class=\"nx\">compare</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">.</span><span class=\"nx\">s</span><span class=\"p\">[</span><span class=\"nx\">i</span><span class=\"p\">],</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"p\">.</span><span class=\"nx\">s</span><span class=\"p\">[</span><span class=\"nx\">j</span><span class=\"p\">])</span><span class=\"w\"> </span><span class=\"p\">}</span>\n</span><span id=\"__span-14-8\"><a id=\"__codelineno-14-8\" name=\"__codelineno-14-8\" href=\"#__codelineno-14-8\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"nx\">sliceFn</span><span class=\"p\">[</span><span class=\"nx\">T</span><span class=\"p\">])</span><span class=\"w\"> </span><span class=\"nx\">Swap</span><span class=\"p\">(</span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">j</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\">      </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"p\">.</span><span class=\"nx\">s</span><span class=\"p\">[</span><span class=\"nx\">i</span><span class=\"p\">],</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"p\">.</span><span class=\"nx\">s</span><span class=\"p\">[</span><span class=\"nx\">j</span><span class=\"p\">]</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"p\">.</span><span class=\"nx\">s</span><span class=\"p\">[</span><span class=\"nx\">j</span><span class=\"p\">],</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"p\">.</span><span class=\"nx\">s</span><span class=\"p\">[</span><span class=\"nx\">i</span><span class=\"p\">]</span><span class=\"w\"> </span><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Conversely, when is it recommended <strong>not</strong> to use generics?</p>\n<ul>\n<li>When just calling a method of the type argument. For example, consider a function that receives an <code>io.Writer</code> and call the <code>Write</code> method:</li>\n</ul>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-15-1\"><a id=\"__codelineno-15-1\" name=\"__codelineno-15-1\" href=\"#__codelineno-15-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">foo</span><span class=\"p\">[</span><span class=\"nx\">T</span><span class=\"w\"> </span><span class=\"nx\">io</span><span class=\"p\">.</span><span class=\"nx\">Writer</span><span class=\"p\">](</span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"nx\">T</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-15-2\"><a id=\"__codelineno-15-2\" name=\"__codelineno-15-2\" href=\"#__codelineno-15-2\"></a><span class=\"w\">   </span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">getBytes</span><span class=\"p\">()</span>\n</span><span id=\"__span-15-3\"><a id=\"__codelineno-15-3\" name=\"__codelineno-15-3\" href=\"#__codelineno-15-3\"></a><span class=\"w\">   </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">Write</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"p\">)</span>\n</span><span id=\"__span-15-4\"><a id=\"__codelineno-15-4\" name=\"__codelineno-15-4\" href=\"#__codelineno-15-4\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<ul>\n<li>When it makes our code more complex. Generics are never mandatory, and as Go developers, we have been able to live without them for more than a decade. If writing generic functions or structures we figure out that it doesn’t make our code clearer, we should probably reconsider our decision for this particular use case.</li>\n</ul>\n<h2 id=\"conclusion\">Conclusion</h2>\n<p>Though generics can be very helpful in particular conditions, we should be cautious about when to use them and not use them.</p>\n<p>In general, when we want to answer when not to use generics, we can find similarities with when not to use interfaces. Indeed, generics introduce a form of abstraction, and we have to remember that unnecessary abstractions introduce complexity.</p>\n<p>Let’s not pollute our code with needless abstractions, and let’s focus on solving concrete problems for now. It means that we shouldn’t use type parameters prematurely. Let’s wait until we are about to write boilerplate code to consider using generics.</p>\n\n\n\n\n\n\n\n  \n  \n\n\n\n  \n\n\n  \n\n\n\n<h2 id=\"__comments\">Comments</h2>\n<!-- Insert generated snippet here -->\n<script src=\"https://giscus.app/client.js\" data-repo=\"teivah/100-go-mistakes\" data-repo-id=\"MDEwOlJlcG9zaXRvcnkzMjA4MTg5NjI=\" data-category=\"Discussions\" data-category-id=\"DIC_kwDOEx9PEs4CZQUm\" data-mapping=\"pathname\" data-strict=\"0\" data-reactions-enabled=\"1\" data-emit-metadata=\"0\" data-input-position=\"bottom\" data-theme=\"preferred_color_scheme\" data-lang=\"en\" crossorigin=\"anonymous\" async>\n</script>\n<!-- Synchronize Giscus theme with palette -->\n<script>\n  var giscus = document.querySelector(\"script[src*=giscus]\")\n\n  // Set palette on initial load\n  var palette = __md_get(\"__palette\")\n  if (palette && typeof palette.color === \"object\") {\n    var theme = palette.color.scheme === \"slate\"\n        ? \"transparent_dark\"\n        : \"light\"\n\n    // Instruct Giscus to set theme\n    giscus.setAttribute(\"data-theme\", theme)\n  }\n\n  // Register event handlers after documented loaded\n  document.addEventListener(\"DOMContentLoaded\", function() {\n    var ref = document.querySelector(\"[data-md-component=palette]\")\n    ref.addEventListener(\"change\", function() {\n      var palette = __md_get(\"__palette\")\n      if (palette && typeof palette.color === \"object\") {\n        var theme = palette.color.scheme === \"slate\"\n            ? \"transparent_dark\"\n            : \"light\"\n\n        // Instruct Giscus to change theme\n        var frame = document.querySelector(\".giscus-frame\")\n        frame.contentWindow.postMessage(\n            { giscus: { setConfig: { theme } } },\n            \"https://giscus.app\"\n        )\n      }\n    })\n  })\n</script>\n\n                \n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright © 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"></path></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \"..\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"../assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"../assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  \n<script id=\"init-glightbox\">const lightbox = GLightbox({\"touchNavigation\": true, \"loop\": false, \"zoomable\": true, \"draggable\": true, \"openEffect\": \"zoom\", \"closeEffect\": \"zoom\", \"slideEffect\": \"slide\"});\ndocument$.subscribe(()=>{ lightbox.reload(); });\n</script></body></html>"
  },
  {
    "path": "site/92-false-sharing/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\" class=\"no-js\"><head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n      \n      \n        <link rel=\"canonical\" href=\"https://100go.co/92-false-sharing/\">\n      \n      \n        <link rel=\"prev\" href=\"../89-benchmarks/\">\n      \n      \n        <link rel=\"next\" href=\"../98-profiling-execution-tracing/\">\n      \n      \n      <link rel=\"icon\" href=\"../img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>Writing concurrent code that leads to false sharing (#92) - 100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"../assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\"..\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n      \n        <meta property=\"og:type\" content=\"website\">\n      \n        <meta property=\"og:title\" content=\"Writing concurrent code that leads to false sharing (#92) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta property=\"og:description\" content=\"None\">\n      \n        <meta property=\"og:image\" content=\"https://100go.co/assets/images/social/92-false-sharing.png\">\n      \n        <meta property=\"og:image:type\" content=\"image/png\">\n      \n        <meta property=\"og:image:width\" content=\"1200\">\n      \n        <meta property=\"og:image:height\" content=\"630\">\n      \n        <meta property=\"og:url\" content=\"https://100go.co/92-false-sharing/\">\n      \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n      \n        <meta name=\"twitter:title\" content=\"Writing concurrent code that leads to false sharing (#92) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta name=\"twitter:description\" content=\"None\">\n      \n        <meta name=\"twitter:image\" content=\"https://100go.co/assets/images/social/92-false-sharing.png\">\n      \n    \n    \n  <link href=\"../assets/stylesheets/glightbox.min.css\" rel=\"stylesheet\"><script src=\"../assets/javascripts/glightbox.min.js\"></script><style id=\"glightbox-style\">\n            html.glightbox-open { overflow: initial; height: 100%; }\n            .gslide-title { margin-top: 0px; user-select: text; }\n            .gslide-desc { color: #666; user-select: text; }\n            .gslide-image img { background: white; }\n            .gscrollbar-fixer { padding-right: 15px; }\n            .gdesc-inner { font-size: 0.75rem; }\n            body[data-md-color-scheme=\"slate\"] .gdesc-inner { background: var(--md-default-bg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-title { color: var(--md-default-fg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-desc { color: var(--md-default-fg-color); }\n        </style></head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n        \n        <a href=\"#writing-concurrent-code-that-leads-to-false-sharing\" class=\"md-skip\">\n          Skip to content\n        </a>\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"></path></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              Writing concurrent code that leads to false sharing (#92)\n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"></path></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"></path></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"></path></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n    \n  \n  \n    \n    \n      <li class=\"md-tabs__item md-tabs__item--active\">\n        <a href=\"..\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"../book/\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n        \n        \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"..\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1_2\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../5-interface-pollution/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../9-generics/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../20-slice/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../28-maps-memory-leaks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../56-concurrency-faster/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../89-benchmarks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    <li class=\"md-nav__item md-nav__item--active\">\n      \n      <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n      \n      \n        \n      \n      \n      <a href=\"./\" class=\"md-nav__link md-nav__link--active\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../98-profiling-execution-tracing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_3\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../zh/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../ja/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../pt-br/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../book/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../chapter-1/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../external/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\" hidden>\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n                  \n  \n\n\n\n  \n  \n\n\n<h1 id=\"writing-concurrent-code-that-leads-to-false-sharing\">Writing concurrent code that leads to false sharing</h1>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/false-sharing.jpeg\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/false-sharing.jpeg\"></a></p>\n<p>In previous sections, we have discussed the fundamental concepts of CPU caching. We have seen that some specific caches (typically, L1 and L2) aren’t shared among all the logical cores but are specific to a physical core. This specificity has some concrete impacts such as concurrency and the concept of false sharing, which can lead to a significant performance decrease. Let’s look at what false sharing is via an example and then see how to prevent it.</p>\n<p>In this example, we use two structs, <code>Input</code> and <code>Result</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-0-1\"><a id=\"__codelineno-0-1\" name=\"__codelineno-0-1\" href=\"#__codelineno-0-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Input</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-0-2\"><a id=\"__codelineno-0-2\" name=\"__codelineno-0-2\" href=\"#__codelineno-0-2\"></a><span class=\"w\">    </span><span class=\"nx\">a</span><span class=\"w\"> </span><span class=\"kt\">int64</span>\n</span><span id=\"__span-0-3\"><a id=\"__codelineno-0-3\" name=\"__codelineno-0-3\" href=\"#__codelineno-0-3\"></a><span class=\"w\">    </span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"kt\">int64</span>\n</span><span id=\"__span-0-4\"><a id=\"__codelineno-0-4\" name=\"__codelineno-0-4\" href=\"#__codelineno-0-4\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-0-5\"><a id=\"__codelineno-0-5\" name=\"__codelineno-0-5\" href=\"#__codelineno-0-5\"></a>\n</span><span id=\"__span-0-6\"><a id=\"__codelineno-0-6\" name=\"__codelineno-0-6\" href=\"#__codelineno-0-6\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Result</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-0-7\"><a id=\"__codelineno-0-7\" name=\"__codelineno-0-7\" href=\"#__codelineno-0-7\"></a><span class=\"w\">    </span><span class=\"nx\">sumA</span><span class=\"w\"> </span><span class=\"kt\">int64</span>\n</span><span id=\"__span-0-8\"><a id=\"__codelineno-0-8\" name=\"__codelineno-0-8\" href=\"#__codelineno-0-8\"></a><span class=\"w\">    </span><span class=\"nx\">sumB</span><span class=\"w\"> </span><span class=\"kt\">int64</span>\n</span><span id=\"__span-0-9\"><a id=\"__codelineno-0-9\" name=\"__codelineno-0-9\" href=\"#__codelineno-0-9\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>The goal is to implement a <code>count</code> function that receives a slice of <code>Input</code> and computes the following:</p>\n<ul>\n<li>The sum of all the <code>Input.a</code> fields into <code>Result.sumA</code></li>\n<li>The sum of all the <code>Input.b</code> fields into <code>Result.sumB</code></li>\n</ul>\n<p>For the sake of the example, we implement a concurrent solution with one goroutine that computes <code>sumA</code> and another that computes <code>sumB</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-1-1\"><a id=\"__codelineno-1-1\" name=\"__codelineno-1-1\" href=\"#__codelineno-1-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">count</span><span class=\"p\">(</span><span class=\"nx\">inputs</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"nx\">Input</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">Result</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-2\"><a id=\"__codelineno-1-2\" name=\"__codelineno-1-2\" href=\"#__codelineno-1-2\"></a><span class=\"w\">    </span><span class=\"nx\">wg</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">sync</span><span class=\"p\">.</span><span class=\"nx\">WaitGroup</span><span class=\"p\">{}</span>\n</span><span id=\"__span-1-3\"><a id=\"__codelineno-1-3\" name=\"__codelineno-1-3\" href=\"#__codelineno-1-3\"></a><span class=\"w\">    </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Add</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n</span><span id=\"__span-1-4\"><a id=\"__codelineno-1-4\" name=\"__codelineno-1-4\" href=\"#__codelineno-1-4\"></a>\n</span><span id=\"__span-1-5\"><a id=\"__codelineno-1-5\" name=\"__codelineno-1-5\" href=\"#__codelineno-1-5\"></a><span class=\"w\">    </span><span class=\"nx\">result</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">Result</span><span class=\"p\">{}</span><span class=\"w\"> </span><span class=\"c1\">// Init the result struct</span>\n</span><span id=\"__span-1-6\"><a id=\"__codelineno-1-6\" name=\"__codelineno-1-6\" href=\"#__codelineno-1-6\"></a>\n</span><span id=\"__span-1-7\"><a id=\"__codelineno-1-7\" name=\"__codelineno-1-7\" href=\"#__codelineno-1-7\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-8\"><a id=\"__codelineno-1-8\" name=\"__codelineno-1-8\" href=\"#__codelineno-1-8\"></a><span class=\"w\">        </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">inputs</span><span class=\"p\">);</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-9\"><a id=\"__codelineno-1-9\" name=\"__codelineno-1-9\" href=\"#__codelineno-1-9\"></a><span class=\"w\">            </span><span class=\"nx\">result</span><span class=\"p\">.</span><span class=\"nx\">sumA</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"nx\">inputs</span><span class=\"p\">[</span><span class=\"nx\">i</span><span class=\"p\">].</span><span class=\"nx\">a</span><span class=\"w\"> </span><span class=\"c1\">// Computes sumA</span>\n</span><span id=\"__span-1-10\"><a id=\"__codelineno-1-10\" name=\"__codelineno-1-10\" href=\"#__codelineno-1-10\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-1-11\"><a id=\"__codelineno-1-11\" name=\"__codelineno-1-11\" href=\"#__codelineno-1-11\"></a><span class=\"w\">        </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Done</span><span class=\"p\">()</span>\n</span><span id=\"__span-1-12\"><a id=\"__codelineno-1-12\" name=\"__codelineno-1-12\" href=\"#__codelineno-1-12\"></a><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span><span id=\"__span-1-13\"><a id=\"__codelineno-1-13\" name=\"__codelineno-1-13\" href=\"#__codelineno-1-13\"></a>\n</span><span id=\"__span-1-14\"><a id=\"__codelineno-1-14\" name=\"__codelineno-1-14\" href=\"#__codelineno-1-14\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-15\"><a id=\"__codelineno-1-15\" name=\"__codelineno-1-15\" href=\"#__codelineno-1-15\"></a><span class=\"w\">        </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">inputs</span><span class=\"p\">);</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-16\"><a id=\"__codelineno-1-16\" name=\"__codelineno-1-16\" href=\"#__codelineno-1-16\"></a><span class=\"w\">            </span><span class=\"nx\">result</span><span class=\"p\">.</span><span class=\"nx\">sumB</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"nx\">inputs</span><span class=\"p\">[</span><span class=\"nx\">i</span><span class=\"p\">].</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"c1\">// Computes sumB</span>\n</span><span id=\"__span-1-17\"><a id=\"__codelineno-1-17\" name=\"__codelineno-1-17\" href=\"#__codelineno-1-17\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-1-18\"><a id=\"__codelineno-1-18\" name=\"__codelineno-1-18\" href=\"#__codelineno-1-18\"></a><span class=\"w\">        </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Done</span><span class=\"p\">()</span>\n</span><span id=\"__span-1-19\"><a id=\"__codelineno-1-19\" name=\"__codelineno-1-19\" href=\"#__codelineno-1-19\"></a><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span><span id=\"__span-1-20\"><a id=\"__codelineno-1-20\" name=\"__codelineno-1-20\" href=\"#__codelineno-1-20\"></a>\n</span><span id=\"__span-1-21\"><a id=\"__codelineno-1-21\" name=\"__codelineno-1-21\" href=\"#__codelineno-1-21\"></a><span class=\"w\">    </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Wait</span><span class=\"p\">()</span>\n</span><span id=\"__span-1-22\"><a id=\"__codelineno-1-22\" name=\"__codelineno-1-22\" href=\"#__codelineno-1-22\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">result</span>\n</span><span id=\"__span-1-23\"><a id=\"__codelineno-1-23\" name=\"__codelineno-1-23\" href=\"#__codelineno-1-23\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>We spin up two goroutines: one that iterates over each a field and another that iterates over each b field. This example is fine from a concurrency perspective. For instance, it doesn’t lead to a data race, because each goroutine increments its own variable. But this example illustrates the false sharing concept that degrades expected performance.</p>\n<p>Let’s look at the main memory. Because <code>sumA</code> and <code>sumB</code> are allocated contiguously, in most cases (seven out of eight), both variables are allocated to the same memory block:</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/false-sharing-1.svg\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/false-sharing-1.svg\"></a>\n  </p>\n<figcaption>In this example, sumA and sumB are part of the same memory block.</figcaption>\n</figure>\n<p>Now, let’s assume that the machine contains two cores. In most cases, we should eventually have two threads scheduled on different cores. So if the CPU decides to copy this memory block to a cache line, it is copied twice:</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/false-sharing-2.svg\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/false-sharing-2.svg\"></a>\n  </p>\n<figcaption>Each block is copied to a cache line on both code 0 and core 1.</figcaption>\n</figure>\n<p>Both cache lines are replicated because L1D (L1 data) is per core. Recall that in our example, each goroutine updates its own variable: <code>sumA</code> on one side, and <code>sumB</code> on the other side:</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/false-sharing-3.svg\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/false-sharing-3.svg\"></a>\n  </p>\n<figcaption>Each goroutine updates its own variable.</figcaption>\n</figure>\n<p>Because these cache lines are replicated, one of the goals of the CPU is to guarantee cache coherency. For example, if one goroutine updates <code>sumA</code> and another reads <code>sumA</code> (after some synchronization), we expect our application to get the latest value.</p>\n<p>However, our example doesn’t do exactly this. Both goroutines access their own variables, not a shared one. We might expect the CPU to know about this and understand that it isn’t a conflict, but this isn’t the case. When we write a variable that’s in a cache, the granularity tracked by the CPU isn’t the variable: it’s the cache line.</p>\n<p>When a cache line is shared across multiple cores and at least one goroutine is a writer, the entire cache line is invalidated. This happens even if the updates are logically independent (for example, <code>sumA</code> and <code>sumB</code>). This is the problem of false sharing, and it degrades performance.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>Internally, a CPU uses the <a href=\"https://en.wikipedia.org/wiki/MESI_protocol\">MESI protocol</a> to guarantee cache coherency. It tracks each cache line, marking it modified, exclusive, shared, or invalid (MESI).</p>\n</details>\n<p>One of the most important aspects to understand about memory and caching is that sharing memory across cores isn’t real—it’s an illusion. This understanding comes from the fact that we don’t consider a machine a black box; instead, we try to have mechanical sympathy with underlying levels.</p>\n<p>So how do we solve false sharing? There are two main solutions.</p>\n<p>The first solution is to use the same approach we’ve shown but ensure that <code>sumA</code> and <code>sumB</code> aren’t part of the same cache line. For example, we can update the <code>Result</code> struct to add <em>padding</em> between the fields. Padding is a technique to allocate extra memory. Because an <code>int64</code> requires an 8-byte allocation and a cache line 64 bytes long, we need 64 – 8 = 56 bytes of padding:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-2-1\"><a id=\"__codelineno-2-1\" name=\"__codelineno-2-1\" href=\"#__codelineno-2-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Result</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-2-2\"><a id=\"__codelineno-2-2\" name=\"__codelineno-2-2\" href=\"#__codelineno-2-2\"></a><span class=\"w\">    </span><span class=\"nx\">sumA</span><span class=\"w\"> </span><span class=\"kt\">int64</span>\n</span><span id=\"__span-2-3\"><a id=\"__codelineno-2-3\" name=\"__codelineno-2-3\" href=\"#__codelineno-2-3\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"nx\">_</span><span class=\"w\">    </span><span class=\"p\">[</span><span class=\"mi\">56</span><span class=\"p\">]</span><span class=\"kt\">byte</span><span class=\"w\"> </span><span class=\"c1\">// Padding</span>\n</span></span><span id=\"__span-2-4\"><a id=\"__codelineno-2-4\" name=\"__codelineno-2-4\" href=\"#__codelineno-2-4\"></a><span class=\"w\">    </span><span class=\"nx\">sumB</span><span class=\"w\"> </span><span class=\"kt\">int64</span>\n</span><span id=\"__span-2-5\"><a id=\"__codelineno-2-5\" name=\"__codelineno-2-5\" href=\"#__codelineno-2-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>The next figure shows a possible memory allocation. Using padding, <code>sumA</code> and <code>sumB</code> will always be part of different memory blocks and hence different cache lines.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/false-sharing-4.svg\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/false-sharing-4.svg\"></a>\n  </p>\n<figcaption>sumA and sumB are part of different memory blocks.</figcaption>\n</figure>\n<p>If we benchmark both solutions (with and without padding), we see that the padding solution is significantly faster (about 40% on my machine). This is an important improvement that results from the addition of padding between the two fields to prevent false sharing.</p>\n<p>The second solution is to rework the structure of the algorithm. For example, instead of having both goroutines share the same struct, we can make them communicate their local result via channels. The result benchmark is roughly the same as with padding.</p>\n<p>In summary, we must remember that sharing memory across goroutines is an illusion at the lowest memory levels. False sharing occurs when a cache line is shared across two cores when at least one goroutine is a writer. If we need to optimize an application that relies on concurrency, we should check whether false sharing applies, because this pattern is known to degrade application performance. We can prevent false sharing with either padding or communication.</p>\n\n\n\n\n\n\n\n  \n  \n\n\n\n  \n\n\n  \n\n\n\n<h2 id=\"__comments\">Comments</h2>\n<!-- Insert generated snippet here -->\n<script src=\"https://giscus.app/client.js\" data-repo=\"teivah/100-go-mistakes\" data-repo-id=\"MDEwOlJlcG9zaXRvcnkzMjA4MTg5NjI=\" data-category=\"Discussions\" data-category-id=\"DIC_kwDOEx9PEs4CZQUm\" data-mapping=\"pathname\" data-strict=\"0\" data-reactions-enabled=\"1\" data-emit-metadata=\"0\" data-input-position=\"bottom\" data-theme=\"preferred_color_scheme\" data-lang=\"en\" crossorigin=\"anonymous\" async>\n</script>\n<!-- Synchronize Giscus theme with palette -->\n<script>\n  var giscus = document.querySelector(\"script[src*=giscus]\")\n\n  // Set palette on initial load\n  var palette = __md_get(\"__palette\")\n  if (palette && typeof palette.color === \"object\") {\n    var theme = palette.color.scheme === \"slate\"\n        ? \"transparent_dark\"\n        : \"light\"\n\n    // Instruct Giscus to set theme\n    giscus.setAttribute(\"data-theme\", theme)\n  }\n\n  // Register event handlers after documented loaded\n  document.addEventListener(\"DOMContentLoaded\", function() {\n    var ref = document.querySelector(\"[data-md-component=palette]\")\n    ref.addEventListener(\"change\", function() {\n      var palette = __md_get(\"__palette\")\n      if (palette && typeof palette.color === \"object\") {\n        var theme = palette.color.scheme === \"slate\"\n            ? \"transparent_dark\"\n            : \"light\"\n\n        // Instruct Giscus to change theme\n        var frame = document.querySelector(\".giscus-frame\")\n        frame.contentWindow.postMessage(\n            { giscus: { setConfig: { theme } } },\n            \"https://giscus.app\"\n        )\n      }\n    })\n  })\n</script>\n\n                \n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright © 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"></path></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \"..\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"../assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"../assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  \n<script id=\"init-glightbox\">const lightbox = GLightbox({\"touchNavigation\": true, \"loop\": false, \"zoomable\": true, \"draggable\": true, \"openEffect\": \"zoom\", \"closeEffect\": \"zoom\", \"slideEffect\": \"slide\"});\ndocument$.subscribe(()=>{ lightbox.reload(); });\n</script></body></html>"
  },
  {
    "path": "site/98-profiling-execution-tracing/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\" class=\"no-js\"><head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n      \n      \n        <link rel=\"canonical\" href=\"https://100go.co/98-profiling-execution-tracing/\">\n      \n      \n        <link rel=\"prev\" href=\"../92-false-sharing/\">\n      \n      \n        <link rel=\"next\" href=\"../zh/\">\n      \n      \n      <link rel=\"icon\" href=\"../img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>Not using Go diagnostics tooling (#98) - 100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"../assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\"..\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n      \n        <meta property=\"og:type\" content=\"website\">\n      \n        <meta property=\"og:title\" content=\"Not using Go diagnostics tooling (#98) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta property=\"og:description\" content=\"None\">\n      \n        <meta property=\"og:image\" content=\"https://100go.co/assets/images/social/98-profiling-execution-tracing.png\">\n      \n        <meta property=\"og:image:type\" content=\"image/png\">\n      \n        <meta property=\"og:image:width\" content=\"1200\">\n      \n        <meta property=\"og:image:height\" content=\"630\">\n      \n        <meta property=\"og:url\" content=\"https://100go.co/98-profiling-execution-tracing/\">\n      \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n      \n        <meta name=\"twitter:title\" content=\"Not using Go diagnostics tooling (#98) - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta name=\"twitter:description\" content=\"None\">\n      \n        <meta name=\"twitter:image\" content=\"https://100go.co/assets/images/social/98-profiling-execution-tracing.png\">\n      \n    \n    \n  <link href=\"../assets/stylesheets/glightbox.min.css\" rel=\"stylesheet\"><script src=\"../assets/javascripts/glightbox.min.js\"></script><style id=\"glightbox-style\">\n            html.glightbox-open { overflow: initial; height: 100%; }\n            .gslide-title { margin-top: 0px; user-select: text; }\n            .gslide-desc { color: #666; user-select: text; }\n            .gslide-image img { background: white; }\n            .gscrollbar-fixer { padding-right: 15px; }\n            .gdesc-inner { font-size: 0.75rem; }\n            body[data-md-color-scheme=\"slate\"] .gdesc-inner { background: var(--md-default-bg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-title { color: var(--md-default-fg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-desc { color: var(--md-default-fg-color); }\n        </style></head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n        \n        <a href=\"#not-using-go-diagnostics-tooling\" class=\"md-skip\">\n          Skip to content\n        </a>\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"></path></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              Not using Go diagnostics tooling (#98)\n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"></path></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"></path></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"></path></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n    \n  \n  \n    \n    \n      <li class=\"md-tabs__item md-tabs__item--active\">\n        <a href=\"..\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"../book/\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n        \n        \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"..\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1_2\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../5-interface-pollution/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../9-generics/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../20-slice/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../28-maps-memory-leaks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../56-concurrency-faster/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../89-benchmarks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../92-false-sharing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    <li class=\"md-nav__item md-nav__item--active\">\n      \n      <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n      \n      \n        \n      \n      \n        <label class=\"md-nav__link md-nav__link--active\" for=\"__toc\">\n          \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n          <span class=\"md-nav__icon md-icon\"></span>\n        </label>\n      \n      <a href=\"./\" class=\"md-nav__link md-nav__link--active\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n      \n        \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#profiling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Profiling\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Profiling\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#enabling-pprof\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Enabling pprof\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#cpu-profiling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      CPU Profiling\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#heap-profiling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Heap Profiling\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#goroutine-profiling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Goroutine Profiling\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#block-profiling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Block Profiling\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#mutex-profiling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Mutex Profiling\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#execution-tracer\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Execution Tracer\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_3\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../zh/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../ja/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../pt-br/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../book/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../chapter-1/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../external/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\" hidden>\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#profiling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Profiling\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Profiling\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#enabling-pprof\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Enabling pprof\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#cpu-profiling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      CPU Profiling\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#heap-profiling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Heap Profiling\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#goroutine-profiling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Goroutine Profiling\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#block-profiling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Block Profiling\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#mutex-profiling\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Mutex Profiling\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#execution-tracer\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Execution Tracer\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n                  \n  \n\n\n\n  \n  \n\n\n<h1 id=\"not-using-go-diagnostics-tooling\">Not using Go diagnostics tooling</h1>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/98-profiling-execution-tracing.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/98-profiling-execution-tracing.png\"></a></p>\n<p>Go offers a few excellent diagnostics tools to help us get insights into how an application performs. This post focuses on the most important ones: profiling and the execution tracer. Both tools are so important that they should be part of the core toolset of any Go developer who is interested in optimization. First, let’s discuss profiling.</p>\n<h2 id=\"profiling\">Profiling</h2>\n<p>Profiling provides insights into the execution of an application. It allows us to resolve performance issues, detect contention, locate memory leaks, and more. These insights can be collected via several profiles:</p>\n<ul>\n<li><code>CPU</code>— Determines where an application spends its time</li>\n<li><code>Goroutine</code>— Reports the stack traces of the ongoing goroutines</li>\n<li><code>Heap</code>— Reports heap memory allocation to monitor current memory usage and check for possible memory leaks</li>\n<li><code>Mutex</code>— Reports lock contentions to see the behaviors of the mutexes used in our code and whether an application spends too much time in locking calls</li>\n<li><code>Block</code>— Shows where goroutines block waiting on synchronization primitives</li>\n</ul>\n<p>Profiling is achieved via instrumentation using a tool called a profiler, in Go: <code>pprof</code>. First, let’s understand how and when to enable <code>pprof</code>; then, we discuss the most critical profile types.</p>\n<h3 id=\"enabling-pprof\">Enabling pprof</h3>\n<p>There are several ways to enable <code>pprof</code>. For example, we can use the <code>net/http/pprof</code> package to serve the profiling data via HTTP:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-0-1\"><a id=\"__codelineno-0-1\" name=\"__codelineno-0-1\" href=\"#__codelineno-0-1\"></a><span class=\"kn\">package</span><span class=\"w\"> </span><span class=\"nx\">main</span>\n</span><span id=\"__span-0-2\"><a id=\"__codelineno-0-2\" name=\"__codelineno-0-2\" href=\"#__codelineno-0-2\"></a>\n</span><span id=\"__span-0-3\"><a id=\"__codelineno-0-3\" name=\"__codelineno-0-3\" href=\"#__codelineno-0-3\"></a><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"p\">(</span>\n</span><span id=\"__span-0-4\"><a id=\"__codelineno-0-4\" name=\"__codelineno-0-4\" href=\"#__codelineno-0-4\"></a><span class=\"w\">    </span><span class=\"s\">\"fmt\"</span>\n</span><span id=\"__span-0-5\"><a id=\"__codelineno-0-5\" name=\"__codelineno-0-5\" href=\"#__codelineno-0-5\"></a><span class=\"w\">    </span><span class=\"s\">\"log\"</span>\n</span><span id=\"__span-0-6\"><a id=\"__codelineno-0-6\" name=\"__codelineno-0-6\" href=\"#__codelineno-0-6\"></a><span class=\"w\">    </span><span class=\"s\">\"net/http\"</span>\n</span><span id=\"__span-0-7\"><a id=\"__codelineno-0-7\" name=\"__codelineno-0-7\" href=\"#__codelineno-0-7\"></a><span class=\"w\">    </span><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"s\">\"net/http/pprof\"</span><span class=\"w\"> </span><span class=\"c1\">// Blank import to pprof</span>\n</span><span id=\"__span-0-8\"><a id=\"__codelineno-0-8\" name=\"__codelineno-0-8\" href=\"#__codelineno-0-8\"></a><span class=\"p\">)</span>\n</span><span id=\"__span-0-9\"><a id=\"__codelineno-0-9\" name=\"__codelineno-0-9\" href=\"#__codelineno-0-9\"></a>\n</span><span id=\"__span-0-10\"><a id=\"__codelineno-0-10\" name=\"__codelineno-0-10\" href=\"#__codelineno-0-10\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-0-11\"><a id=\"__codelineno-0-11\" name=\"__codelineno-0-11\" href=\"#__codelineno-0-11\"></a><span class=\"w\">    </span><span class=\"c1\">// Exposes an HTTP endpoint</span>\n</span><span id=\"__span-0-12\"><a id=\"__codelineno-0-12\" name=\"__codelineno-0-12\" href=\"#__codelineno-0-12\"></a><span class=\"w\">    </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">HandleFunc</span><span class=\"p\">(</span><span class=\"s\">\"/\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">ResponseWriter</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Request</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-0-13\"><a id=\"__codelineno-0-13\" name=\"__codelineno-0-13\" href=\"#__codelineno-0-13\"></a><span class=\"w\">        </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Fprintf</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s\">\"\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-0-14\"><a id=\"__codelineno-0-14\" name=\"__codelineno-0-14\" href=\"#__codelineno-0-14\"></a><span class=\"w\">    </span><span class=\"p\">})</span>\n</span><span id=\"__span-0-15\"><a id=\"__codelineno-0-15\" name=\"__codelineno-0-15\" href=\"#__codelineno-0-15\"></a><span class=\"w\">    </span><span class=\"nx\">log</span><span class=\"p\">.</span><span class=\"nx\">Fatal</span><span class=\"p\">(</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">ListenAndServe</span><span class=\"p\">(</span><span class=\"s\">\":80\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"p\">))</span>\n</span><span id=\"__span-0-16\"><a id=\"__codelineno-0-16\" name=\"__codelineno-0-16\" href=\"#__codelineno-0-16\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Importing <code>net/http/pprof</code> leads to a side effect that allows us to reach the pprof URL: <a href=\"http://host/debug/pprof\">http://host/debug/pprof</a>. Note that enabling <code>pprof</code> is safe even in production (<a href=\"https://go.dev/doc/diagnostics#profiling\">https://go.dev/doc/diagnostics#profiling</a>). The profiles that impact performance, such as CPU profiling, aren’t enabled by default, nor do they run continuously: they are activated only for a specific period.</p>\n<p>Now that we have seen how to expose a <code>pprof</code> endpoint, let’s discuss the most common profiles.</p>\n<h3 id=\"cpu-profiling\">CPU Profiling</h3>\n<p>The CPU profiler relies on the OS and signaling. When it is activated, the application asks the OS to interrupt it every 10 ms by default via a <code>SIGPROF</code> signal. When the application receives a <code>SIGPROF</code>, it suspends the current activity and transfers the execution to the profiler. The profiler collects data such as the current goroutine activity and aggregates execution statistics that we can retrieve. Then it stops, and the execution resumes until the next <code>SIGPROF</code>.</p>\n<p>We can access the /debug/pprof/profile endpoint to activate CPU profiling. Accessing this endpoint executes CPU profiling for 30 seconds by default. For 30 seconds, our application is interrupted every 10 ms. Note that we can change these two default values: we can use the <code>seconds</code> parameter to pass to the endpoint how long the profiling should last (for example, /debug/pprof/profile?seconds=15), and we can change the interruption rate (even to less than 10 ms). But in most cases, 10 ms should be enough, and in decreasing this value (meaning increasing the rate), we should be careful not to harm performance. After 30 seconds, we download the results of the CPU profiler.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>We can also enable the CPU profiler using the <code>-cpuprofile</code> flag, such as when running a benchmark. For example, the following command produces the same type of file that can be downloaded via /debug/ pprof/profile.</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-1-1\"><a id=\"__codelineno-1-1\" name=\"__codelineno-1-1\" href=\"#__codelineno-1-1\"></a>$ go test -bench=. -cpuprofile profile.out\n</span></code></pre></div>\n</details>\n<p>From this file, we can navigate to the results using <code>go tool</code>:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-2-1\"><a id=\"__codelineno-2-1\" name=\"__codelineno-2-1\" href=\"#__codelineno-2-1\"></a>$ go tool pprof -http=:8080 &lt;file&gt;\n</span></code></pre></div>\n<p>This command opens a web UI showing the call graph. The next figure shows an example taken from an application. The larger the arrow, the more it was a hot path. We can then navigate into this graph and get execution insights.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/screen-pprof-cpu.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/screen-pprof-cpu.png\"></a>\n  </p>\n<figcaption>Figure 1: The call graph of an application during 30 seconds.</figcaption>\n</figure>\n<p>For example, the graph in the next figure tells us that during 30 seconds, 0.06 seconds were spent in the <code>decode</code> method (<code>*FetchResponse</code> receiver). Of these 0.06 seconds, 0.02 were spent in <code>RecordBatch.decode</code> and 0.01 in <code>makemap</code> (creating a map).</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/screen-pprof-sarama.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/screen-pprof-sarama.png\"></a>\n  </p>\n<figcaption>Figure 2: Example call graph.</figcaption>\n</figure>\n<p>We can also access this kind of information from the web UI with different representations. For example, the Top view sorts the functions per execution time, and Flame Graph visualizes the execution time hierarchy. The UI can even display the expensive parts of the source code line by line.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>We can also delve into profiling data via a command line. However, we focus on the web UI in this post.</p>\n</details>\n<p>Thanks to this data, we can get a general idea of how an application behaves:</p>\n<ul>\n<li>Too many calls to <code>runtime.mallogc</code> can mean an excessive number of small heap allocations that we can try to minimize.</li>\n<li>Too much time spent in channel operations or mutex locks can indicate excessive contention that is harming the application’s performance.</li>\n<li>Too much time spent on <code>syscall.Read</code> or <code>syscall.Write</code> means the application spends a significant amount of time in Kernel mode. Working on I/O buffering may be an avenue for improvement.</li>\n</ul>\n<p>These are the kinds of insights we can get from the CPU profiler. It’s valuable to understand the hottest code path and identify bottlenecks. But it won’t determine more than the configured rate because the CPU profiler is executed at a fixed pace (by default, 10 ms). To get finer-grained insights, we should use tracing, which we discuss later in this post.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>We can also attach labels to the different functions. For example, imagine a common function called from different clients. To track the time spent for both clients, we can use <code>pprof.Labels</code>.</p>\n</details>\n<h3 id=\"heap-profiling\">Heap Profiling</h3>\n<p>Heap profiling allows us to get statistics about the current heap usage. Like CPU profiling, heap profiling is sample-based. We can change this rate, but we shouldn’t be too granular because the more we decrease the rate, the more effort heap profiling will require to collect data. By default, samples are profiled at one allocation for every 512 KB of heap allocation.</p>\n<p>If we reach /debug/pprof/heap/, we get raw data that can be hard to read. However, we can download a heap profile using /debug/pprof/heap/?debug=0 and then open it with <code>go tool</code> (the same command as in the previous section) to navigate into the data using the web UI.</p>\n<p>The next figure shows an example of a heap graph. Calling the <code>MetadataResponse.decode</code> method leads to allocating 1536 KB of heap data (which represents 6.32% of the total heap). However, 0 out of these 1536 KB were allocated by this function directly, so we need to inspect the second call. The <code>TopicMetadata.decode</code> method allocated 512 KB out of the 1536 KB; the rest — 1024 KB — were allocated in another method.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/screen-pprof-heap.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/screen-pprof-heap.png\"></a>\n  </p>\n<figcaption>Figure 3: A heap graph.</figcaption>\n</figure>\n<p>This is how we can navigate the call chain to understand what part of an application is responsible for most of the heap allocations. We can also look at different sample types:</p>\n<ul>\n<li><code>alloc_objects</code>— Total number of objects allocated</li>\n<li><code>alloc_space</code>— Total amount of memory allocated</li>\n<li><code>inuse_object</code>s — Number of objects allocated and not yet released</li>\n<li><code>inuse_space</code>— Amount of memory allocated and not yet released</li>\n</ul>\n<p>Another very helpful capability with heap profiling is tracking memory leaks. With a <abbr title=\"Garbage Collector\">GC</abbr>-based language, the usual procedure is the following:</p>\n<ol>\n<li>Trigger a <abbr title=\"Garbage Collector\">GC</abbr>.</li>\n<li>Download heap data.</li>\n<li>Wait for a few seconds/minutes.</li>\n<li>Trigger another <abbr title=\"Garbage Collector\">GC</abbr>.</li>\n<li>Download another heap data.</li>\n<li>Compare.</li>\n</ol>\n<p>Forcing a <abbr title=\"Garbage Collector\">GC</abbr> before downloading data is a way to prevent false assumptions. For example, if we see a peak of retained objects without running a <abbr title=\"Garbage Collector\">GC</abbr> first, we cannot be sure whether it’s a leak or objects that the next <abbr title=\"Garbage Collector\">GC</abbr> will collect.</p>\n<p>Using <code>pprof</code>, we can download a heap profile and force a <abbr title=\"Garbage Collector\">GC</abbr> in the meantime. The procedure in Go is the following:</p>\n<ol>\n<li>Go to /debug/pprof/heap?gc=1 (trigger the <abbr title=\"Garbage Collector\">GC</abbr> and download the heap profile).</li>\n<li>Wait for a few seconds/minutes.</li>\n<li>Go to /debug/pprof/heap?gc=1 again.</li>\n<li>Use go tool to compare both heap profiles:</li>\n</ol>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-3-1\"><a id=\"__codelineno-3-1\" name=\"__codelineno-3-1\" href=\"#__codelineno-3-1\"></a>$ go tool pprof -http=:8080 -diff_base &lt;file2&gt; &lt;file1&gt;\n</span></code></pre></div>\n<p>The next figure shows the kind of data we can access. For example, the amount of heap memory held by the newTopicProducer method (top left) has decreased (–513 KB). In contrast, the amount held by updateMetadata (bottom right) has increased (+512 KB). Slow increases are normal. The second heap profile may have been calculated in the middle of a service call, for example. We can repeat this process or wait longer; the important part is to track steady increases in allocations of a specific object.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/screen-pprof-heap-diff.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/screen-pprof-heap-diff.png\"></a>\n  </p>\n<figcaption>Figure 4: The differences between the two heap profiles.</figcaption>\n</figure>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>Another type of profiling related to the heap is <code>allocs</code>, which reports allocations. Heap profiling shows the current state of the heap memory. To get insights about past memory allocations since the application started, we can use allocations profiling. As discussed, because stack allocations are cheap, they aren’t part of this profiling, which only focuses on the heap.</p>\n</details>\n<h3 id=\"goroutine-profiling\">Goroutine Profiling</h3>\n<p>The <code>goroutine</code> profile reports the stack trace of all the current goroutines in an application. We can download a file using /debug/pprof/goroutine/?debug=0 and use go tool again. The next figure shows the kind of information we can get.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/screen-pprof-goroutines.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/screen-pprof-goroutines.png\"></a>\n  </p>\n<figcaption>Figure 5: Goroutine graph.</figcaption>\n</figure>\n<p>We can see the current state of the application and how many goroutines were created per function. In this case, <code>withRecover</code> has created 296 ongoing goroutines (63%), and 29 were related to a call to <code>responseFeeder</code>.</p>\n<p>This kind of information is also beneficial if we suspect goroutine leaks. We can look at goroutine profiler data to know which part of a system is the suspect.</p>\n<h3 id=\"block-profiling\">Block Profiling</h3>\n<p>The <code>block</code> profile reports where ongoing goroutines block waiting on synchronization primitives. Possibilities include</p>\n<ul>\n<li>Sending or receiving on an unbuffered channel</li>\n<li>Sending to a full channel</li>\n<li>Receiving from an empty channel</li>\n<li>Mutex contention</li>\n<li>Network or filesystem waits</li>\n</ul>\n<p>Block profiling also records the amount of time a goroutine has been waiting and is accessible via /debug/pprof/block. This profile can be extremely helpful if we suspect that performance is being harmed by blocking calls.</p>\n<p>The <code>block</code> profile isn’t enabled by default: we have to call <code>runtime.SetBlockProfileRate</code> to enable it. This function controls the fraction of goroutine blocking events that are reported. Once enabled, the profiler will keep collecting data in the background even if we don’t call the /debug/pprof/block endpoint. Let’s be cautious if we want to set a high rate so we don’t harm performance.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>If we face a deadlock or suspect that goroutines are in a blocked state, the full goroutine stack dump (/debug/pprof/goroutine/?debug=2) creates a dump of all the current goroutine stack traces. This can be helpful as a first analysis step. For example, the following dump shows a Sarama goroutine blocked for 1,420 minutes on a channel-receive operation:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-4-1\"><a id=\"__codelineno-4-1\" name=\"__codelineno-4-1\" href=\"#__codelineno-4-1\"></a>goroutine 2494290 [chan receive, 1420 minutes]:\n</span><span id=\"__span-4-2\"><a id=\"__codelineno-4-2\" name=\"__codelineno-4-2\" href=\"#__codelineno-4-2\"></a>github.com/Shopify/sarama.(*syncProducer).SendMessages(0xc00071a090,\n</span><span id=\"__span-4-3\"><a id=\"__codelineno-4-3\" name=\"__codelineno-4-3\" href=\"#__codelineno-4-3\"></a>[CA]{0xc0009bb800, 0xfb, 0xfb})\n</span><span id=\"__span-4-4\"><a id=\"__codelineno-4-4\" name=\"__codelineno-4-4\" href=\"#__codelineno-4-4\"></a>/app/vendor/github.com/Shopify/sarama/sync_producer.go:117 +0x149\n</span></code></pre></div>\n</details>\n<h3 id=\"mutex-profiling\">Mutex Profiling</h3>\n<p>The last profile type is related to blocking but only regarding mutexes. If we suspect that our application spends significant time waiting for locking mutexes, thus harming execution, we can use mutex profiling. It’s accessible via /debug/pprof/mutex.</p>\n<p>This profile works in a manner similar to that for blocking. It’s disabled by default: we have to enable it using <code>runtime.SetMutexProfileFraction</code>, which controls the fraction of mutex contention events reported.</p>\n<p>Following are a few additional notes about profiling:</p>\n<ul>\n<li>We haven’t mentioned the <code>threadcreate</code> profile because it’s been broken since 2013 (<a href=\"https://github.com/golang/go/issues/6104\">https://github.com/golang/go/issues/6104</a>).</li>\n<li>Be sure to enable only one profiler at a time: for example, do not enable CPU and heap profiling simultaneously. Doing so can lead to erroneous observations.</li>\n<li><code>pprof</code> is extensible, and we can create our own custom profiles using <code>pprof.Profile</code>.</li>\n</ul>\n<p>We have seen the most important profiles that we can enable to help us understand how an application performs and possible avenues for optimization. In general, enabling <code>pprof</code> is recommended, even in production, because in most cases it offers an excellent balance between its footprint and the amount of insight we can get from it. Some profiles, such as the CPU profile, lead to performance penalties but only during the time they are enabled.</p>\n<p>Let’s now look at the execution tracer.</p>\n<h2 id=\"execution-tracer\">Execution Tracer</h2>\n<p>The execution tracer is a tool that captures a wide range of runtime events with <code>go tool</code> to make them available for visualization. It is helpful for the following:</p>\n<ul>\n<li>Understanding runtime events such as how the <abbr title=\"Garbage Collector\">GC</abbr> performs</li>\n<li>Understanding how goroutines execute</li>\n<li>Identifying poorly parallelized execution</li>\n</ul>\n<p>Let’s try it with an example given the Concurrency isn’t Always Faster in Go section. We discussed two parallel versions of the merge sort algorithm. The issue with the first version was poor parallelization, leading to the creation of too many goroutines. Let’s see how the tracer can help us in validating this statement.</p>\n<p>We will write a benchmark for the first version and execute it with the -trace flag to enable the execution tracer:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-5-1\"><a id=\"__codelineno-5-1\" name=\"__codelineno-5-1\" href=\"#__codelineno-5-1\"></a>$ go test -bench=. -v -trace=trace.out\n</span></code></pre></div>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>We can also download a remote trace file using the /debug/pprof/ trace?debug=0 pprof endpoint.</p>\n</details>\n<p>This command creates a trace.out file that we can open using go tool:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-6-1\"><a id=\"__codelineno-6-1\" name=\"__codelineno-6-1\" href=\"#__codelineno-6-1\"></a>$ go tool trace trace.out\n</span><span id=\"__span-6-2\"><a id=\"__codelineno-6-2\" name=\"__codelineno-6-2\" href=\"#__codelineno-6-2\"></a>2021/11/26 21:36:03 Parsing trace...\n</span><span id=\"__span-6-3\"><a id=\"__codelineno-6-3\" name=\"__codelineno-6-3\" href=\"#__codelineno-6-3\"></a>2021/11/26 21:36:31 Splitting trace...\n</span><span id=\"__span-6-4\"><a id=\"__codelineno-6-4\" name=\"__codelineno-6-4\" href=\"#__codelineno-6-4\"></a>2021/11/26 21:37:00 Opening browser. Trace viewer is listening on\n</span><span id=\"__span-6-5\"><a id=\"__codelineno-6-5\" name=\"__codelineno-6-5\" href=\"#__codelineno-6-5\"></a>    http://127.0.0.1:54518\n</span></code></pre></div>\n<p>The web browser opens, and we can click View Trace to see all the traces during a specific timeframe, as shown in the next figure. This figure represents about 150 ms. We can see multiple helpful metrics, such as the goroutine count and the heap size. The heap size grows steadily until a <abbr title=\"Garbage Collector\">GC</abbr> is triggered. We can also observe the activity of the Go application per CPU core. The timeframe starts with user-level code; then a “stop the\nworld” is executed, which occupies the four CPU cores for approximately 40 ms.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/tracing.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/tracing.png\"></a>\n  </p>\n<figcaption>Figure 6: Showing goroutine activity and runtime events such as a GC phase.</figcaption>\n</figure>\n<p>Regarding concurrency, we can see that this version uses all the available CPU cores on the machine. However, the next figure zooms in on a portion of 1 ms. Each bar corresponds to a single goroutine execution. Having too many small bars doesn’t look right: it means execution that is poorly parallelized.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/screen-mergesort1.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/screen-mergesort1.png\"></a>\n  </p>\n<figcaption>Figure 7: Too many small bars mean poorly parallelized execution.</figcaption>\n</figure>\n<p>The next figure zooms even closer to see how these goroutines are orchestrated. Roughly 50% of the CPU time isn’t spent executing application code. The white spaces represent the time the Go runtime takes to spin up and orchestrate new goroutines.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/screen-mergesort11.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/screen-mergesort11.png\"></a>\n  </p>\n<figcaption>Figure 8: About 50% of CPU time is spent handling goroutine switches.</figcaption>\n</figure>\n<p>Let’s compare this with the second parallel implementation, which was about an order of magnitude faster. The next figure again zooms to a 1 ms timeframe.</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/screen-mergesort2.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/screen-mergesort2.png\"></a>\n  </p>\n<figcaption>Figure 9: The number of white spaces has been significantly reduced, proving that the CPU is more fully occupied.</figcaption>\n</figure>\n<p>Each goroutine takes more time to execute, and the number of white spaces has been significantly reduced. Hence, the CPU is much more occupied executing application code than it was in the first version. Each millisecond of CPU time is spent more efficiently, explaining the benchmark differences.</p>\n<p>Note that the granularity of the traces is per goroutine, not per function like CPU profiling. However, it’s possible to define user-level tasks to get insights per function or group of functions using the <code>runtime/trace</code> package.</p>\n<p>For example, imagine a function that computes a Fibonacci number and then writes it to a global variable using atomic. We can define two different tasks:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-7-1\"><a id=\"__codelineno-7-1\" name=\"__codelineno-7-1\" href=\"#__codelineno-7-1\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"kt\">int64</span>\n</span><span id=\"__span-7-2\"><a id=\"__codelineno-7-2\" name=\"__codelineno-7-2\" href=\"#__codelineno-7-2\"></a><span class=\"c1\">// Creates a fibonacci task</span>\n</span><span id=\"__span-7-3\"><a id=\"__codelineno-7-3\" name=\"__codelineno-7-3\" href=\"#__codelineno-7-3\"></a><span class=\"nx\">ctx</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">fibTask</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">trace</span><span class=\"p\">.</span><span class=\"nx\">NewTask</span><span class=\"p\">(</span><span class=\"nx\">context</span><span class=\"p\">.</span><span class=\"nx\">Background</span><span class=\"p\">(),</span><span class=\"w\"> </span><span class=\"s\">\"fibonacci\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-7-4\"><a id=\"__codelineno-7-4\" name=\"__codelineno-7-4\" href=\"#__codelineno-7-4\"></a><span class=\"nx\">trace</span><span class=\"p\">.</span><span class=\"nx\">WithRegion</span><span class=\"p\">(</span><span class=\"nx\">ctx</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s\">\"main\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-7-5\"><a id=\"__codelineno-7-5\" name=\"__codelineno-7-5\" href=\"#__codelineno-7-5\"></a><span class=\"w\">    </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">fibonacci</span><span class=\"p\">(</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n</span><span id=\"__span-7-6\"><a id=\"__codelineno-7-6\" name=\"__codelineno-7-6\" href=\"#__codelineno-7-6\"></a><span class=\"p\">})</span>\n</span><span id=\"__span-7-7\"><a id=\"__codelineno-7-7\" name=\"__codelineno-7-7\" href=\"#__codelineno-7-7\"></a><span class=\"nx\">fibTask</span><span class=\"p\">.</span><span class=\"nx\">End</span><span class=\"p\">()</span>\n</span><span id=\"__span-7-8\"><a id=\"__codelineno-7-8\" name=\"__codelineno-7-8\" href=\"#__codelineno-7-8\"></a>\n</span><span id=\"__span-7-9\"><a id=\"__codelineno-7-9\" name=\"__codelineno-7-9\" href=\"#__codelineno-7-9\"></a><span class=\"c1\">// Creates a store task</span>\n</span><span id=\"__span-7-10\"><a id=\"__codelineno-7-10\" name=\"__codelineno-7-10\" href=\"#__codelineno-7-10\"></a><span class=\"nx\">ctx</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">fibStore</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">trace</span><span class=\"p\">.</span><span class=\"nx\">NewTask</span><span class=\"p\">(</span><span class=\"nx\">ctx</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s\">\"store\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-7-11\"><a id=\"__codelineno-7-11\" name=\"__codelineno-7-11\" href=\"#__codelineno-7-11\"></a><span class=\"nx\">trace</span><span class=\"p\">.</span><span class=\"nx\">WithRegion</span><span class=\"p\">(</span><span class=\"nx\">ctx</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s\">\"main\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-7-12\"><a id=\"__codelineno-7-12\" name=\"__codelineno-7-12\" href=\"#__codelineno-7-12\"></a><span class=\"w\">    </span><span class=\"nx\">atomic</span><span class=\"p\">.</span><span class=\"nx\">StoreInt64</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">result</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"p\">)</span>\n</span><span id=\"__span-7-13\"><a id=\"__codelineno-7-13\" name=\"__codelineno-7-13\" href=\"#__codelineno-7-13\"></a><span class=\"p\">})</span>\n</span><span id=\"__span-7-14\"><a id=\"__codelineno-7-14\" name=\"__codelineno-7-14\" href=\"#__codelineno-7-14\"></a><span class=\"nx\">fibStore</span><span class=\"p\">.</span><span class=\"nx\">End</span><span class=\"p\">()</span>\n</span></code></pre></div>\n<p>Using <code>go tool</code>, we can get more precise information about how these two tasks perform. In the previous trace UI, we can see the boundaries for each task per goroutine. In User-Defined Tasks, we can follow the duration distribution:</p>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/screen-tracing-user-level.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/screen-tracing-user-level.png\"></a>\n  </p>\n<figcaption>Figure 10: Distribution of user-level tasks.</figcaption>\n</figure>\n<p>We see that in most cases, the <code>fibonacci</code> task is executed in less than 15 microseconds, whereas the <code>store</code> task takes less than 6309 nanoseconds.</p>\n<p>In the previous section, we discussed the kinds of information we can get from CPU profiling. What are the main differences compared to the data we can get from user-level traces?</p>\n<ul>\n<li>CPU profiling:<ul>\n<li>Sample-based</li>\n<li>Per function</li>\n<li>Doesn’t go below the sampling rate (10 ms by default)</li>\n</ul>\n</li>\n<li>User-level traces:<ul>\n<li>Not sample-based</li>\n<li>Per-goroutine execution (unless we use the <code>runtime/trace</code> package)</li>\n<li>Time executions aren’t bound by any rate</li>\n</ul>\n</li>\n</ul>\n<p>In summary, the execution tracer is a powerful tool for understanding how an application performs. As we have seen with the merge sort example, we can identify poorly parallelized execution. However, the tracer’s granularity remains per goroutine unless we manually use <code>runtime/trace</code> compared to a CPU profile, for example. We can use both profiling and the execution tracer to get the most out of the standard Go diagnostics tools when optimizing an application.</p>\n\n\n\n\n\n\n\n  \n  \n\n\n\n  \n\n\n  \n\n\n\n<h2 id=\"__comments\">Comments</h2>\n<!-- Insert generated snippet here -->\n<script src=\"https://giscus.app/client.js\" data-repo=\"teivah/100-go-mistakes\" data-repo-id=\"MDEwOlJlcG9zaXRvcnkzMjA4MTg5NjI=\" data-category=\"Discussions\" data-category-id=\"DIC_kwDOEx9PEs4CZQUm\" data-mapping=\"pathname\" data-strict=\"0\" data-reactions-enabled=\"1\" data-emit-metadata=\"0\" data-input-position=\"bottom\" data-theme=\"preferred_color_scheme\" data-lang=\"en\" crossorigin=\"anonymous\" async>\n</script>\n<!-- Synchronize Giscus theme with palette -->\n<script>\n  var giscus = document.querySelector(\"script[src*=giscus]\")\n\n  // Set palette on initial load\n  var palette = __md_get(\"__palette\")\n  if (palette && typeof palette.color === \"object\") {\n    var theme = palette.color.scheme === \"slate\"\n        ? \"transparent_dark\"\n        : \"light\"\n\n    // Instruct Giscus to set theme\n    giscus.setAttribute(\"data-theme\", theme)\n  }\n\n  // Register event handlers after documented loaded\n  document.addEventListener(\"DOMContentLoaded\", function() {\n    var ref = document.querySelector(\"[data-md-component=palette]\")\n    ref.addEventListener(\"change\", function() {\n      var palette = __md_get(\"__palette\")\n      if (palette && typeof palette.color === \"object\") {\n        var theme = palette.color.scheme === \"slate\"\n            ? \"transparent_dark\"\n            : \"light\"\n\n        // Instruct Giscus to change theme\n        var frame = document.querySelector(\".giscus-frame\")\n        frame.contentWindow.postMessage(\n            { giscus: { setConfig: { theme } } },\n            \"https://giscus.app\"\n        )\n      }\n    })\n  })\n</script>\n\n                \n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright © 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"></path></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \"..\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"../assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"../assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  \n<script id=\"init-glightbox\">const lightbox = GLightbox({\"touchNavigation\": true, \"loop\": false, \"zoomable\": true, \"draggable\": true, \"openEffect\": \"zoom\", \"closeEffect\": \"zoom\", \"slideEffect\": \"slide\"});\ndocument$.subscribe(()=>{ lightbox.reload(); });\n</script></body></html>"
  },
  {
    "path": "site/CNAME",
    "content": "100go.co\n"
  },
  {
    "path": "site/assets/javascripts/lunr/tinyseg.js",
    "content": "/**\n * export the module via AMD, CommonJS or as a browser global\n * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js\n */\n;(function (root, factory) {\n    if (typeof define === 'function' && define.amd) {\n        // AMD. Register as an anonymous module.\n        define(factory)\n    } else if (typeof exports === 'object') {\n        /**\n         * Node. Does not work with strict CommonJS, but\n         * only CommonJS-like environments that support module.exports,\n         * like Node.\n         */\n        module.exports = factory()\n    } else {\n        // Browser globals (root is window)\n        factory()(root.lunr);\n    }\n}(this, function () {\n    /**\n     * Just return a value to define the module export.\n     * This example returns an object, but the module\n     * can return a function as the exported value.\n     */\n\n    return function(lunr) {\n        // TinySegmenter 0.1 -- Super compact Japanese tokenizer in Javascript\n        // (c) 2008 Taku Kudo <taku@chasen.org>\n        // TinySegmenter is freely distributable under the terms of a new BSD licence.\n        // For details, see http://chasen.org/~taku/software/TinySegmenter/LICENCE.txt\n\n        function TinySegmenter() {\n          var patterns = {\n            \"[一二三四五六七八九十百千万億兆]\":\"M\",\n            \"[一-龠々〆ヵヶ]\":\"H\",\n            \"[ぁ-ん]\":\"I\",\n            \"[ァ-ヴーｱ-ﾝﾞｰ]\":\"K\",\n            \"[a-zA-Zａ-ｚＡ-Ｚ]\":\"A\",\n            \"[0-9０-９]\":\"N\"\n          }\n          this.chartype_ = [];\n          for (var i in patterns) {\n            var regexp = new RegExp(i);\n            this.chartype_.push([regexp, patterns[i]]);\n          }\n\n          this.BIAS__ = -332\n          this.BC1__ = {\"HH\":6,\"II\":2461,\"KH\":406,\"OH\":-1378};\n          this.BC2__ = {\"AA\":-3267,\"AI\":2744,\"AN\":-878,\"HH\":-4070,\"HM\":-1711,\"HN\":4012,\"HO\":3761,\"IA\":1327,\"IH\":-1184,\"II\":-1332,\"IK\":1721,\"IO\":5492,\"KI\":3831,\"KK\":-8741,\"MH\":-3132,\"MK\":3334,\"OO\":-2920};\n          this.BC3__ = {\"HH\":996,\"HI\":626,\"HK\":-721,\"HN\":-1307,\"HO\":-836,\"IH\":-301,\"KK\":2762,\"MK\":1079,\"MM\":4034,\"OA\":-1652,\"OH\":266};\n          this.BP1__ = {\"BB\":295,\"OB\":304,\"OO\":-125,\"UB\":352};\n          this.BP2__ = {\"BO\":60,\"OO\":-1762};\n          this.BQ1__ = {\"BHH\":1150,\"BHM\":1521,\"BII\":-1158,\"BIM\":886,\"BMH\":1208,\"BNH\":449,\"BOH\":-91,\"BOO\":-2597,\"OHI\":451,\"OIH\":-296,\"OKA\":1851,\"OKH\":-1020,\"OKK\":904,\"OOO\":2965};\n          this.BQ2__ = {\"BHH\":118,\"BHI\":-1159,\"BHM\":466,\"BIH\":-919,\"BKK\":-1720,\"BKO\":864,\"OHH\":-1139,\"OHM\":-181,\"OIH\":153,\"UHI\":-1146};\n          this.BQ3__ = {\"BHH\":-792,\"BHI\":2664,\"BII\":-299,\"BKI\":419,\"BMH\":937,\"BMM\":8335,\"BNN\":998,\"BOH\":775,\"OHH\":2174,\"OHM\":439,\"OII\":280,\"OKH\":1798,\"OKI\":-793,\"OKO\":-2242,\"OMH\":-2402,\"OOO\":11699};\n          this.BQ4__ = {\"BHH\":-3895,\"BIH\":3761,\"BII\":-4654,\"BIK\":1348,\"BKK\":-1806,\"BMI\":-3385,\"BOO\":-12396,\"OAH\":926,\"OHH\":266,\"OHK\":-2036,\"ONN\":-973};\n          this.BW1__ = {\",と\":660,\",同\":727,\"B1あ\":1404,\"B1同\":542,\"、と\":660,\"、同\":727,\"」と\":1682,\"あっ\":1505,\"いう\":1743,\"いっ\":-2055,\"いる\":672,\"うし\":-4817,\"うん\":665,\"から\":3472,\"がら\":600,\"こう\":-790,\"こと\":2083,\"こん\":-1262,\"さら\":-4143,\"さん\":4573,\"した\":2641,\"して\":1104,\"すで\":-3399,\"そこ\":1977,\"それ\":-871,\"たち\":1122,\"ため\":601,\"った\":3463,\"つい\":-802,\"てい\":805,\"てき\":1249,\"でき\":1127,\"です\":3445,\"では\":844,\"とい\":-4915,\"とみ\":1922,\"どこ\":3887,\"ない\":5713,\"なっ\":3015,\"など\":7379,\"なん\":-1113,\"にし\":2468,\"には\":1498,\"にも\":1671,\"に対\":-912,\"の一\":-501,\"の中\":741,\"ませ\":2448,\"まで\":1711,\"まま\":2600,\"まる\":-2155,\"やむ\":-1947,\"よっ\":-2565,\"れた\":2369,\"れで\":-913,\"をし\":1860,\"を見\":731,\"亡く\":-1886,\"京都\":2558,\"取り\":-2784,\"大き\":-2604,\"大阪\":1497,\"平方\":-2314,\"引き\":-1336,\"日本\":-195,\"本当\":-2423,\"毎日\":-2113,\"目指\":-724,\"Ｂ１あ\":1404,\"Ｂ１同\":542,\"｣と\":1682};\n          this.BW2__ = {\"..\":-11822,\"11\":-669,\"――\":-5730,\"−−\":-13175,\"いう\":-1609,\"うか\":2490,\"かし\":-1350,\"かも\":-602,\"から\":-7194,\"かれ\":4612,\"がい\":853,\"がら\":-3198,\"きた\":1941,\"くな\":-1597,\"こと\":-8392,\"この\":-4193,\"させ\":4533,\"され\":13168,\"さん\":-3977,\"しい\":-1819,\"しか\":-545,\"した\":5078,\"して\":972,\"しな\":939,\"その\":-3744,\"たい\":-1253,\"たた\":-662,\"ただ\":-3857,\"たち\":-786,\"たと\":1224,\"たは\":-939,\"った\":4589,\"って\":1647,\"っと\":-2094,\"てい\":6144,\"てき\":3640,\"てく\":2551,\"ては\":-3110,\"ても\":-3065,\"でい\":2666,\"でき\":-1528,\"でし\":-3828,\"です\":-4761,\"でも\":-4203,\"とい\":1890,\"とこ\":-1746,\"とと\":-2279,\"との\":720,\"とみ\":5168,\"とも\":-3941,\"ない\":-2488,\"なが\":-1313,\"など\":-6509,\"なの\":2614,\"なん\":3099,\"にお\":-1615,\"にし\":2748,\"にな\":2454,\"によ\":-7236,\"に対\":-14943,\"に従\":-4688,\"に関\":-11388,\"のか\":2093,\"ので\":-7059,\"のに\":-6041,\"のの\":-6125,\"はい\":1073,\"はが\":-1033,\"はず\":-2532,\"ばれ\":1813,\"まし\":-1316,\"まで\":-6621,\"まれ\":5409,\"めて\":-3153,\"もい\":2230,\"もの\":-10713,\"らか\":-944,\"らし\":-1611,\"らに\":-1897,\"りし\":651,\"りま\":1620,\"れた\":4270,\"れて\":849,\"れば\":4114,\"ろう\":6067,\"われ\":7901,\"を通\":-11877,\"んだ\":728,\"んな\":-4115,\"一人\":602,\"一方\":-1375,\"一日\":970,\"一部\":-1051,\"上が\":-4479,\"会社\":-1116,\"出て\":2163,\"分の\":-7758,\"同党\":970,\"同日\":-913,\"大阪\":-2471,\"委員\":-1250,\"少な\":-1050,\"年度\":-8669,\"年間\":-1626,\"府県\":-2363,\"手権\":-1982,\"新聞\":-4066,\"日新\":-722,\"日本\":-7068,\"日米\":3372,\"曜日\":-601,\"朝鮮\":-2355,\"本人\":-2697,\"東京\":-1543,\"然と\":-1384,\"社会\":-1276,\"立て\":-990,\"第に\":-1612,\"米国\":-4268,\"１１\":-669};\n          this.BW3__ = {\"あた\":-2194,\"あり\":719,\"ある\":3846,\"い.\":-1185,\"い。\":-1185,\"いい\":5308,\"いえ\":2079,\"いく\":3029,\"いた\":2056,\"いっ\":1883,\"いる\":5600,\"いわ\":1527,\"うち\":1117,\"うと\":4798,\"えと\":1454,\"か.\":2857,\"か。\":2857,\"かけ\":-743,\"かっ\":-4098,\"かに\":-669,\"から\":6520,\"かり\":-2670,\"が,\":1816,\"が、\":1816,\"がき\":-4855,\"がけ\":-1127,\"がっ\":-913,\"がら\":-4977,\"がり\":-2064,\"きた\":1645,\"けど\":1374,\"こと\":7397,\"この\":1542,\"ころ\":-2757,\"さい\":-714,\"さを\":976,\"し,\":1557,\"し、\":1557,\"しい\":-3714,\"した\":3562,\"して\":1449,\"しな\":2608,\"しま\":1200,\"す.\":-1310,\"す。\":-1310,\"する\":6521,\"ず,\":3426,\"ず、\":3426,\"ずに\":841,\"そう\":428,\"た.\":8875,\"た。\":8875,\"たい\":-594,\"たの\":812,\"たり\":-1183,\"たる\":-853,\"だ.\":4098,\"だ。\":4098,\"だっ\":1004,\"った\":-4748,\"って\":300,\"てい\":6240,\"てお\":855,\"ても\":302,\"です\":1437,\"でに\":-1482,\"では\":2295,\"とう\":-1387,\"とし\":2266,\"との\":541,\"とも\":-3543,\"どう\":4664,\"ない\":1796,\"なく\":-903,\"など\":2135,\"に,\":-1021,\"に、\":-1021,\"にし\":1771,\"にな\":1906,\"には\":2644,\"の,\":-724,\"の、\":-724,\"の子\":-1000,\"は,\":1337,\"は、\":1337,\"べき\":2181,\"まし\":1113,\"ます\":6943,\"まっ\":-1549,\"まで\":6154,\"まれ\":-793,\"らし\":1479,\"られ\":6820,\"るる\":3818,\"れ,\":854,\"れ、\":854,\"れた\":1850,\"れて\":1375,\"れば\":-3246,\"れる\":1091,\"われ\":-605,\"んだ\":606,\"んで\":798,\"カ月\":990,\"会議\":860,\"入り\":1232,\"大会\":2217,\"始め\":1681,\"市\":965,\"新聞\":-5055,\"日,\":974,\"日、\":974,\"社会\":2024,\"ｶ月\":990};\n          this.TC1__ = {\"AAA\":1093,\"HHH\":1029,\"HHM\":580,\"HII\":998,\"HOH\":-390,\"HOM\":-331,\"IHI\":1169,\"IOH\":-142,\"IOI\":-1015,\"IOM\":467,\"MMH\":187,\"OOI\":-1832};\n          this.TC2__ = {\"HHO\":2088,\"HII\":-1023,\"HMM\":-1154,\"IHI\":-1965,\"KKH\":703,\"OII\":-2649};\n          this.TC3__ = {\"AAA\":-294,\"HHH\":346,\"HHI\":-341,\"HII\":-1088,\"HIK\":731,\"HOH\":-1486,\"IHH\":128,\"IHI\":-3041,\"IHO\":-1935,\"IIH\":-825,\"IIM\":-1035,\"IOI\":-542,\"KHH\":-1216,\"KKA\":491,\"KKH\":-1217,\"KOK\":-1009,\"MHH\":-2694,\"MHM\":-457,\"MHO\":123,\"MMH\":-471,\"NNH\":-1689,\"NNO\":662,\"OHO\":-3393};\n          this.TC4__ = {\"HHH\":-203,\"HHI\":1344,\"HHK\":365,\"HHM\":-122,\"HHN\":182,\"HHO\":669,\"HIH\":804,\"HII\":679,\"HOH\":446,\"IHH\":695,\"IHO\":-2324,\"IIH\":321,\"III\":1497,\"IIO\":656,\"IOO\":54,\"KAK\":4845,\"KKA\":3386,\"KKK\":3065,\"MHH\":-405,\"MHI\":201,\"MMH\":-241,\"MMM\":661,\"MOM\":841};\n          this.TQ1__ = {\"BHHH\":-227,\"BHHI\":316,\"BHIH\":-132,\"BIHH\":60,\"BIII\":1595,\"BNHH\":-744,\"BOHH\":225,\"BOOO\":-908,\"OAKK\":482,\"OHHH\":281,\"OHIH\":249,\"OIHI\":200,\"OIIH\":-68};\n          this.TQ2__ = {\"BIHH\":-1401,\"BIII\":-1033,\"BKAK\":-543,\"BOOO\":-5591};\n          this.TQ3__ = {\"BHHH\":478,\"BHHM\":-1073,\"BHIH\":222,\"BHII\":-504,\"BIIH\":-116,\"BIII\":-105,\"BMHI\":-863,\"BMHM\":-464,\"BOMH\":620,\"OHHH\":346,\"OHHI\":1729,\"OHII\":997,\"OHMH\":481,\"OIHH\":623,\"OIIH\":1344,\"OKAK\":2792,\"OKHH\":587,\"OKKA\":679,\"OOHH\":110,\"OOII\":-685};\n          this.TQ4__ = {\"BHHH\":-721,\"BHHM\":-3604,\"BHII\":-966,\"BIIH\":-607,\"BIII\":-2181,\"OAAA\":-2763,\"OAKK\":180,\"OHHH\":-294,\"OHHI\":2446,\"OHHO\":480,\"OHIH\":-1573,\"OIHH\":1935,\"OIHI\":-493,\"OIIH\":626,\"OIII\":-4007,\"OKAK\":-8156};\n          this.TW1__ = {\"につい\":-4681,\"東京都\":2026};\n          this.TW2__ = {\"ある程\":-2049,\"いった\":-1256,\"ころが\":-2434,\"しょう\":3873,\"その後\":-4430,\"だって\":-1049,\"ていた\":1833,\"として\":-4657,\"ともに\":-4517,\"もので\":1882,\"一気に\":-792,\"初めて\":-1512,\"同時に\":-8097,\"大きな\":-1255,\"対して\":-2721,\"社会党\":-3216};\n          this.TW3__ = {\"いただ\":-1734,\"してい\":1314,\"として\":-4314,\"につい\":-5483,\"にとっ\":-5989,\"に当た\":-6247,\"ので,\":-727,\"ので、\":-727,\"のもの\":-600,\"れから\":-3752,\"十二月\":-2287};\n          this.TW4__ = {\"いう.\":8576,\"いう。\":8576,\"からな\":-2348,\"してい\":2958,\"たが,\":1516,\"たが、\":1516,\"ている\":1538,\"という\":1349,\"ました\":5543,\"ません\":1097,\"ようと\":-4258,\"よると\":5865};\n          this.UC1__ = {\"A\":484,\"K\":93,\"M\":645,\"O\":-505};\n          this.UC2__ = {\"A\":819,\"H\":1059,\"I\":409,\"M\":3987,\"N\":5775,\"O\":646};\n          this.UC3__ = {\"A\":-1370,\"I\":2311};\n          this.UC4__ = {\"A\":-2643,\"H\":1809,\"I\":-1032,\"K\":-3450,\"M\":3565,\"N\":3876,\"O\":6646};\n          this.UC5__ = {\"H\":313,\"I\":-1238,\"K\":-799,\"M\":539,\"O\":-831};\n          this.UC6__ = {\"H\":-506,\"I\":-253,\"K\":87,\"M\":247,\"O\":-387};\n          this.UP1__ = {\"O\":-214};\n          this.UP2__ = {\"B\":69,\"O\":935};\n          this.UP3__ = {\"B\":189};\n          this.UQ1__ = {\"BH\":21,\"BI\":-12,\"BK\":-99,\"BN\":142,\"BO\":-56,\"OH\":-95,\"OI\":477,\"OK\":410,\"OO\":-2422};\n          this.UQ2__ = {\"BH\":216,\"BI\":113,\"OK\":1759};\n          this.UQ3__ = {\"BA\":-479,\"BH\":42,\"BI\":1913,\"BK\":-7198,\"BM\":3160,\"BN\":6427,\"BO\":14761,\"OI\":-827,\"ON\":-3212};\n          this.UW1__ = {\",\":156,\"、\":156,\"「\":-463,\"あ\":-941,\"う\":-127,\"が\":-553,\"き\":121,\"こ\":505,\"で\":-201,\"と\":-547,\"ど\":-123,\"に\":-789,\"の\":-185,\"は\":-847,\"も\":-466,\"や\":-470,\"よ\":182,\"ら\":-292,\"り\":208,\"れ\":169,\"を\":-446,\"ん\":-137,\"・\":-135,\"主\":-402,\"京\":-268,\"区\":-912,\"午\":871,\"国\":-460,\"大\":561,\"委\":729,\"市\":-411,\"日\":-141,\"理\":361,\"生\":-408,\"県\":-386,\"都\":-718,\"｢\":-463,\"･\":-135};\n          this.UW2__ = {\",\":-829,\"、\":-829,\"〇\":892,\"「\":-645,\"」\":3145,\"あ\":-538,\"い\":505,\"う\":134,\"お\":-502,\"か\":1454,\"が\":-856,\"く\":-412,\"こ\":1141,\"さ\":878,\"ざ\":540,\"し\":1529,\"す\":-675,\"せ\":300,\"そ\":-1011,\"た\":188,\"だ\":1837,\"つ\":-949,\"て\":-291,\"で\":-268,\"と\":-981,\"ど\":1273,\"な\":1063,\"に\":-1764,\"の\":130,\"は\":-409,\"ひ\":-1273,\"べ\":1261,\"ま\":600,\"も\":-1263,\"や\":-402,\"よ\":1639,\"り\":-579,\"る\":-694,\"れ\":571,\"を\":-2516,\"ん\":2095,\"ア\":-587,\"カ\":306,\"キ\":568,\"ッ\":831,\"三\":-758,\"不\":-2150,\"世\":-302,\"中\":-968,\"主\":-861,\"事\":492,\"人\":-123,\"会\":978,\"保\":362,\"入\":548,\"初\":-3025,\"副\":-1566,\"北\":-3414,\"区\":-422,\"大\":-1769,\"天\":-865,\"太\":-483,\"子\":-1519,\"学\":760,\"実\":1023,\"小\":-2009,\"市\":-813,\"年\":-1060,\"強\":1067,\"手\":-1519,\"揺\":-1033,\"政\":1522,\"文\":-1355,\"新\":-1682,\"日\":-1815,\"明\":-1462,\"最\":-630,\"朝\":-1843,\"本\":-1650,\"東\":-931,\"果\":-665,\"次\":-2378,\"民\":-180,\"気\":-1740,\"理\":752,\"発\":529,\"目\":-1584,\"相\":-242,\"県\":-1165,\"立\":-763,\"第\":810,\"米\":509,\"自\":-1353,\"行\":838,\"西\":-744,\"見\":-3874,\"調\":1010,\"議\":1198,\"込\":3041,\"開\":1758,\"間\":-1257,\"｢\":-645,\"｣\":3145,\"ｯ\":831,\"ｱ\":-587,\"ｶ\":306,\"ｷ\":568};\n          this.UW3__ = {\",\":4889,\"1\":-800,\"−\":-1723,\"、\":4889,\"々\":-2311,\"〇\":5827,\"」\":2670,\"〓\":-3573,\"あ\":-2696,\"い\":1006,\"う\":2342,\"え\":1983,\"お\":-4864,\"か\":-1163,\"が\":3271,\"く\":1004,\"け\":388,\"げ\":401,\"こ\":-3552,\"ご\":-3116,\"さ\":-1058,\"し\":-395,\"す\":584,\"せ\":3685,\"そ\":-5228,\"た\":842,\"ち\":-521,\"っ\":-1444,\"つ\":-1081,\"て\":6167,\"で\":2318,\"と\":1691,\"ど\":-899,\"な\":-2788,\"に\":2745,\"の\":4056,\"は\":4555,\"ひ\":-2171,\"ふ\":-1798,\"へ\":1199,\"ほ\":-5516,\"ま\":-4384,\"み\":-120,\"め\":1205,\"も\":2323,\"や\":-788,\"よ\":-202,\"ら\":727,\"り\":649,\"る\":5905,\"れ\":2773,\"わ\":-1207,\"を\":6620,\"ん\":-518,\"ア\":551,\"グ\":1319,\"ス\":874,\"ッ\":-1350,\"ト\":521,\"ム\":1109,\"ル\":1591,\"ロ\":2201,\"ン\":278,\"・\":-3794,\"一\":-1619,\"下\":-1759,\"世\":-2087,\"両\":3815,\"中\":653,\"主\":-758,\"予\":-1193,\"二\":974,\"人\":2742,\"今\":792,\"他\":1889,\"以\":-1368,\"低\":811,\"何\":4265,\"作\":-361,\"保\":-2439,\"元\":4858,\"党\":3593,\"全\":1574,\"公\":-3030,\"六\":755,\"共\":-1880,\"円\":5807,\"再\":3095,\"分\":457,\"初\":2475,\"別\":1129,\"前\":2286,\"副\":4437,\"力\":365,\"動\":-949,\"務\":-1872,\"化\":1327,\"北\":-1038,\"区\":4646,\"千\":-2309,\"午\":-783,\"協\":-1006,\"口\":483,\"右\":1233,\"各\":3588,\"合\":-241,\"同\":3906,\"和\":-837,\"員\":4513,\"国\":642,\"型\":1389,\"場\":1219,\"外\":-241,\"妻\":2016,\"学\":-1356,\"安\":-423,\"実\":-1008,\"家\":1078,\"小\":-513,\"少\":-3102,\"州\":1155,\"市\":3197,\"平\":-1804,\"年\":2416,\"広\":-1030,\"府\":1605,\"度\":1452,\"建\":-2352,\"当\":-3885,\"得\":1905,\"思\":-1291,\"性\":1822,\"戸\":-488,\"指\":-3973,\"政\":-2013,\"教\":-1479,\"数\":3222,\"文\":-1489,\"新\":1764,\"日\":2099,\"旧\":5792,\"昨\":-661,\"時\":-1248,\"曜\":-951,\"最\":-937,\"月\":4125,\"期\":360,\"李\":3094,\"村\":364,\"東\":-805,\"核\":5156,\"森\":2438,\"業\":484,\"氏\":2613,\"民\":-1694,\"決\":-1073,\"法\":1868,\"海\":-495,\"無\":979,\"物\":461,\"特\":-3850,\"生\":-273,\"用\":914,\"町\":1215,\"的\":7313,\"直\":-1835,\"省\":792,\"県\":6293,\"知\":-1528,\"私\":4231,\"税\":401,\"立\":-960,\"第\":1201,\"米\":7767,\"系\":3066,\"約\":3663,\"級\":1384,\"統\":-4229,\"総\":1163,\"線\":1255,\"者\":6457,\"能\":725,\"自\":-2869,\"英\":785,\"見\":1044,\"調\":-562,\"財\":-733,\"費\":1777,\"車\":1835,\"軍\":1375,\"込\":-1504,\"通\":-1136,\"選\":-681,\"郎\":1026,\"郡\":4404,\"部\":1200,\"金\":2163,\"長\":421,\"開\":-1432,\"間\":1302,\"関\":-1282,\"雨\":2009,\"電\":-1045,\"非\":2066,\"駅\":1620,\"１\":-800,\"｣\":2670,\"･\":-3794,\"ｯ\":-1350,\"ｱ\":551,\"ｸﾞ\":1319,\"ｽ\":874,\"ﾄ\":521,\"ﾑ\":1109,\"ﾙ\":1591,\"ﾛ\":2201,\"ﾝ\":278};\n          this.UW4__ = {\",\":3930,\".\":3508,\"―\":-4841,\"、\":3930,\"。\":3508,\"〇\":4999,\"「\":1895,\"」\":3798,\"〓\":-5156,\"あ\":4752,\"い\":-3435,\"う\":-640,\"え\":-2514,\"お\":2405,\"か\":530,\"が\":6006,\"き\":-4482,\"ぎ\":-3821,\"く\":-3788,\"け\":-4376,\"げ\":-4734,\"こ\":2255,\"ご\":1979,\"さ\":2864,\"し\":-843,\"じ\":-2506,\"す\":-731,\"ず\":1251,\"せ\":181,\"そ\":4091,\"た\":5034,\"だ\":5408,\"ち\":-3654,\"っ\":-5882,\"つ\":-1659,\"て\":3994,\"で\":7410,\"と\":4547,\"な\":5433,\"に\":6499,\"ぬ\":1853,\"ね\":1413,\"の\":7396,\"は\":8578,\"ば\":1940,\"ひ\":4249,\"び\":-4134,\"ふ\":1345,\"へ\":6665,\"べ\":-744,\"ほ\":1464,\"ま\":1051,\"み\":-2082,\"む\":-882,\"め\":-5046,\"も\":4169,\"ゃ\":-2666,\"や\":2795,\"ょ\":-1544,\"よ\":3351,\"ら\":-2922,\"り\":-9726,\"る\":-14896,\"れ\":-2613,\"ろ\":-4570,\"わ\":-1783,\"を\":13150,\"ん\":-2352,\"カ\":2145,\"コ\":1789,\"セ\":1287,\"ッ\":-724,\"ト\":-403,\"メ\":-1635,\"ラ\":-881,\"リ\":-541,\"ル\":-856,\"ン\":-3637,\"・\":-4371,\"ー\":-11870,\"一\":-2069,\"中\":2210,\"予\":782,\"事\":-190,\"井\":-1768,\"人\":1036,\"以\":544,\"会\":950,\"体\":-1286,\"作\":530,\"側\":4292,\"先\":601,\"党\":-2006,\"共\":-1212,\"内\":584,\"円\":788,\"初\":1347,\"前\":1623,\"副\":3879,\"力\":-302,\"動\":-740,\"務\":-2715,\"化\":776,\"区\":4517,\"協\":1013,\"参\":1555,\"合\":-1834,\"和\":-681,\"員\":-910,\"器\":-851,\"回\":1500,\"国\":-619,\"園\":-1200,\"地\":866,\"場\":-1410,\"塁\":-2094,\"士\":-1413,\"多\":1067,\"大\":571,\"子\":-4802,\"学\":-1397,\"定\":-1057,\"寺\":-809,\"小\":1910,\"屋\":-1328,\"山\":-1500,\"島\":-2056,\"川\":-2667,\"市\":2771,\"年\":374,\"庁\":-4556,\"後\":456,\"性\":553,\"感\":916,\"所\":-1566,\"支\":856,\"改\":787,\"政\":2182,\"教\":704,\"文\":522,\"方\":-856,\"日\":1798,\"時\":1829,\"最\":845,\"月\":-9066,\"木\":-485,\"来\":-442,\"校\":-360,\"業\":-1043,\"氏\":5388,\"民\":-2716,\"気\":-910,\"沢\":-939,\"済\":-543,\"物\":-735,\"率\":672,\"球\":-1267,\"生\":-1286,\"産\":-1101,\"田\":-2900,\"町\":1826,\"的\":2586,\"目\":922,\"省\":-3485,\"県\":2997,\"空\":-867,\"立\":-2112,\"第\":788,\"米\":2937,\"系\":786,\"約\":2171,\"経\":1146,\"統\":-1169,\"総\":940,\"線\":-994,\"署\":749,\"者\":2145,\"能\":-730,\"般\":-852,\"行\":-792,\"規\":792,\"警\":-1184,\"議\":-244,\"谷\":-1000,\"賞\":730,\"車\":-1481,\"軍\":1158,\"輪\":-1433,\"込\":-3370,\"近\":929,\"道\":-1291,\"選\":2596,\"郎\":-4866,\"都\":1192,\"野\":-1100,\"銀\":-2213,\"長\":357,\"間\":-2344,\"院\":-2297,\"際\":-2604,\"電\":-878,\"領\":-1659,\"題\":-792,\"館\":-1984,\"首\":1749,\"高\":2120,\"｢\":1895,\"｣\":3798,\"･\":-4371,\"ｯ\":-724,\"ｰ\":-11870,\"ｶ\":2145,\"ｺ\":1789,\"ｾ\":1287,\"ﾄ\":-403,\"ﾒ\":-1635,\"ﾗ\":-881,\"ﾘ\":-541,\"ﾙ\":-856,\"ﾝ\":-3637};\n          this.UW5__ = {\",\":465,\".\":-299,\"1\":-514,\"E2\":-32768,\"]\":-2762,\"、\":465,\"。\":-299,\"「\":363,\"あ\":1655,\"い\":331,\"う\":-503,\"え\":1199,\"お\":527,\"か\":647,\"が\":-421,\"き\":1624,\"ぎ\":1971,\"く\":312,\"げ\":-983,\"さ\":-1537,\"し\":-1371,\"す\":-852,\"だ\":-1186,\"ち\":1093,\"っ\":52,\"つ\":921,\"て\":-18,\"で\":-850,\"と\":-127,\"ど\":1682,\"な\":-787,\"に\":-1224,\"の\":-635,\"は\":-578,\"べ\":1001,\"み\":502,\"め\":865,\"ゃ\":3350,\"ょ\":854,\"り\":-208,\"る\":429,\"れ\":504,\"わ\":419,\"を\":-1264,\"ん\":327,\"イ\":241,\"ル\":451,\"ン\":-343,\"中\":-871,\"京\":722,\"会\":-1153,\"党\":-654,\"務\":3519,\"区\":-901,\"告\":848,\"員\":2104,\"大\":-1296,\"学\":-548,\"定\":1785,\"嵐\":-1304,\"市\":-2991,\"席\":921,\"年\":1763,\"思\":872,\"所\":-814,\"挙\":1618,\"新\":-1682,\"日\":218,\"月\":-4353,\"査\":932,\"格\":1356,\"機\":-1508,\"氏\":-1347,\"田\":240,\"町\":-3912,\"的\":-3149,\"相\":1319,\"省\":-1052,\"県\":-4003,\"研\":-997,\"社\":-278,\"空\":-813,\"統\":1955,\"者\":-2233,\"表\":663,\"語\":-1073,\"議\":1219,\"選\":-1018,\"郎\":-368,\"長\":786,\"間\":1191,\"題\":2368,\"館\":-689,\"１\":-514,\"Ｅ２\":-32768,\"｢\":363,\"ｲ\":241,\"ﾙ\":451,\"ﾝ\":-343};\n          this.UW6__ = {\",\":227,\".\":808,\"1\":-270,\"E1\":306,\"、\":227,\"。\":808,\"あ\":-307,\"う\":189,\"か\":241,\"が\":-73,\"く\":-121,\"こ\":-200,\"じ\":1782,\"す\":383,\"た\":-428,\"っ\":573,\"て\":-1014,\"で\":101,\"と\":-105,\"な\":-253,\"に\":-149,\"の\":-417,\"は\":-236,\"も\":-206,\"り\":187,\"る\":-135,\"を\":195,\"ル\":-673,\"ン\":-496,\"一\":-277,\"中\":201,\"件\":-800,\"会\":624,\"前\":302,\"区\":1792,\"員\":-1212,\"委\":798,\"学\":-960,\"市\":887,\"広\":-695,\"後\":535,\"業\":-697,\"相\":753,\"社\":-507,\"福\":974,\"空\":-822,\"者\":1811,\"連\":463,\"郎\":1082,\"１\":-270,\"Ｅ１\":306,\"ﾙ\":-673,\"ﾝ\":-496};\n          \n          return this;\n        }\n        TinySegmenter.prototype.ctype_ = function(str) {\n          for (var i in this.chartype_) {\n            if (str.match(this.chartype_[i][0])) {\n              return this.chartype_[i][1];\n            }\n          }\n          return \"O\";\n        }\n\n        TinySegmenter.prototype.ts_ = function(v) {\n          if (v) { return v; }\n          return 0;\n        }\n\n        TinySegmenter.prototype.segment = function(input) {\n          if (input == null || input == undefined || input == \"\") {\n            return [];\n          }\n          var result = [];\n          var seg = [\"B3\",\"B2\",\"B1\"];\n          var ctype = [\"O\",\"O\",\"O\"];\n          var o = input.split(\"\");\n          for (i = 0; i < o.length; ++i) {\n            seg.push(o[i]);\n            ctype.push(this.ctype_(o[i]))\n          }\n          seg.push(\"E1\");\n          seg.push(\"E2\");\n          seg.push(\"E3\");\n          ctype.push(\"O\");\n          ctype.push(\"O\");\n          ctype.push(\"O\");\n          var word = seg[3];\n          var p1 = \"U\";\n          var p2 = \"U\";\n          var p3 = \"U\";\n          for (var i = 4; i < seg.length - 3; ++i) {\n            var score = this.BIAS__;\n            var w1 = seg[i-3];\n            var w2 = seg[i-2];\n            var w3 = seg[i-1];\n            var w4 = seg[i];\n            var w5 = seg[i+1];\n            var w6 = seg[i+2];\n            var c1 = ctype[i-3];\n            var c2 = ctype[i-2];\n            var c3 = ctype[i-1];\n            var c4 = ctype[i];\n            var c5 = ctype[i+1];\n            var c6 = ctype[i+2];\n            score += this.ts_(this.UP1__[p1]);\n            score += this.ts_(this.UP2__[p2]);\n            score += this.ts_(this.UP3__[p3]);\n            score += this.ts_(this.BP1__[p1 + p2]);\n            score += this.ts_(this.BP2__[p2 + p3]);\n            score += this.ts_(this.UW1__[w1]);\n            score += this.ts_(this.UW2__[w2]);\n            score += this.ts_(this.UW3__[w3]);\n            score += this.ts_(this.UW4__[w4]);\n            score += this.ts_(this.UW5__[w5]);\n            score += this.ts_(this.UW6__[w6]);\n            score += this.ts_(this.BW1__[w2 + w3]);\n            score += this.ts_(this.BW2__[w3 + w4]);\n            score += this.ts_(this.BW3__[w4 + w5]);\n            score += this.ts_(this.TW1__[w1 + w2 + w3]);\n            score += this.ts_(this.TW2__[w2 + w3 + w4]);\n            score += this.ts_(this.TW3__[w3 + w4 + w5]);\n            score += this.ts_(this.TW4__[w4 + w5 + w6]);\n            score += this.ts_(this.UC1__[c1]);\n            score += this.ts_(this.UC2__[c2]);\n            score += this.ts_(this.UC3__[c3]);\n            score += this.ts_(this.UC4__[c4]);\n            score += this.ts_(this.UC5__[c5]);\n            score += this.ts_(this.UC6__[c6]);\n            score += this.ts_(this.BC1__[c2 + c3]);\n            score += this.ts_(this.BC2__[c3 + c4]);\n            score += this.ts_(this.BC3__[c4 + c5]);\n            score += this.ts_(this.TC1__[c1 + c2 + c3]);\n            score += this.ts_(this.TC2__[c2 + c3 + c4]);\n            score += this.ts_(this.TC3__[c3 + c4 + c5]);\n            score += this.ts_(this.TC4__[c4 + c5 + c6]);\n        //  score += this.ts_(this.TC5__[c4 + c5 + c6]);    \n            score += this.ts_(this.UQ1__[p1 + c1]);\n            score += this.ts_(this.UQ2__[p2 + c2]);\n            score += this.ts_(this.UQ3__[p3 + c3]);\n            score += this.ts_(this.BQ1__[p2 + c2 + c3]);\n            score += this.ts_(this.BQ2__[p2 + c3 + c4]);\n            score += this.ts_(this.BQ3__[p3 + c2 + c3]);\n            score += this.ts_(this.BQ4__[p3 + c3 + c4]);\n            score += this.ts_(this.TQ1__[p2 + c1 + c2 + c3]);\n            score += this.ts_(this.TQ2__[p2 + c2 + c3 + c4]);\n            score += this.ts_(this.TQ3__[p3 + c1 + c2 + c3]);\n            score += this.ts_(this.TQ4__[p3 + c2 + c3 + c4]);\n            var p = \"O\";\n            if (score > 0) {\n              result.push(word);\n              word = \"\";\n              p = \"B\";\n            }\n            p1 = p2;\n            p2 = p3;\n            p3 = p;\n            word += seg[i];\n          }\n          result.push(word);\n\n          return result;\n        }\n\n        lunr.TinySegmenter = TinySegmenter;\n    };\n\n}));"
  },
  {
    "path": "site/assets/javascripts/lunr/wordcut.js",
    "content": "(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}(g.lunr || (g.lunr = {})).wordcut = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\nvar _ = require(\"underscore\");\n\nvar Acceptors = {\n  creators: null,\n  current: null,\n  tag: null,\n\n  init: function() {\n    this.creators = [];\n    this.current = [];\n    this.tag = {};\n  },\n\n  reset: function() {\n    this.current = [];\n    this.tag = {}\n  },\n\n  transit: function(ch) {\n    var self = this;\n\n    self.creators.forEach(function(creator) {\n      var acceptor = creator.createAcceptor(self.tag);\n      if (acceptor) \n        self.current.push(acceptor);\n    });\n    \n    var _current = [];\n    self.tag = {};\n\n    for (var i = 0; i < self.current.length; i++) {\n      var _acceptor = self.current[i]\n        , acceptor = _acceptor.transit(ch);\n      \n      if (!acceptor.isError) {\n        _current.push(acceptor);\n        self.tag[acceptor.tag] = acceptor;\n      }\n    }\n    self.current = _current;\n\n  },\n\n  getFinalAcceptors: function() {    \n    return this.current.filter(function(acceptor) {\n      return acceptor.isFinal;\n    });\n  }\n};\n\nmodule.exports = function() {\n  var acceptors = _.clone(Acceptors);\n  acceptors.init();\n  return acceptors;\n};\n\n},{\"underscore\":25}],2:[function(require,module,exports){\n(function (__dirname){\n\nvar LEFT = 0;\nvar RIGHT = 1;\nvar path = require(\"path\");\nvar glob = require(\"glob\");\n\nvar WordcutDict = {\n\n\n  init: function (dictPathFile, withDefault, words) {\n    withDefault = withDefault || false\n    var defaultDict = path.normalize(__dirname + \"/..\") + \"/data/tdict-*.txt\";\n    this.dict=[]\n    var dictPathIsDefined = dictPathFile !== undefined\n    var dictPath = (withDefault || !dictPathIsDefined) ? [defaultDict]: [];\n    var dictPathFile = dictPathFile || defaultDict\n\n    if(dictPathIsDefined){\n      if (Array.isArray(dictPathFile)) {\n        dictPath.concat.apply(dictPath, dictPathFile);\n      } else {\n        dictPath.push(dictPathFile)\n      }\n    }\n\n    this.addFiles(dictPath, false)\n\n    if(words!==undefined){\n      this.addWords(words, false)\n    }\n    this.finalizeDict();\n  },\n\n  addWords: function(words, finalize){\n    finalize = finalize===undefined || finalize;\n    this.dict.push.apply(this.dict, words)\n    if(finalize){\n      this.finalizeDict();\n    }\n  },\n\n  finalizeDict: function(){\n    this.dict = this.sortuniq(this.dict);\n  },\n\n  addFiles: function(files, finalize){\n    finalize = finalize===undefined || finalize;\n    \n    for (var i = 0; i < 1; i++) {\n      var words = \"ก.ก.\\nก.ก.น.\\nก.ข.ค.\\nก.ค.\\nก.จ.\\nก.ช.น.\\nก.ฌ.\\nก.ต.\\nก.ต.ง.\\nก.ต.ช.\\nก.ตร.\\nก.ท.\\nก.น.ช.\\nก.บช.\\nก.บถ.\\nก.ป.ส.\\nก.พ.\\nก.ม.\\nก.ย.\\nก.ร.\\nก.ล.ต.\\nก.ว.\\nก.ศ.ว.\\nก.ส.ท.\\nก.ส.ธ.\\nก.ส.อ.\\nก.อ.\\nกก.ตชด.\\nกก.ตร.น.\\nกก.ภ.จว.\\nกก.รสช.\\nกกบ.ขส.ทบ.\\nกกล.รพน.\\nกง.กห.\\nกง.ทบ.\\nกง.ทร.\\nกซข.ป.\\nกซม.ป.\\nกทม.กรุงเทพมหานคร\\nกบ.ทบ.\\nกป.สป.\\nกพ.ทบ.\\nกพ.ทร.\\nกพ.ทหาร\\nกร.ทบ.\\nกรป.กลาง\\nกรอ.พอ.\\nกศ.ด.\\nกศ.บ.\\nกศ.บป.\\nกศ.ม.\\nกษ.ด.\\nกษ.บ.\\nกษ.ม.\\nกส.ด.\\nกส.ทบ.\\nกส.บ.\\nกส.ม.\\nกอ.ปค.\\nกอ.รพน.\\nกอ.รมน.\\nกอ.รสต.\\nข.ต.ว.\\nขว.ทบ.\\nขว.ทร.\\nขว.ทหาร\\nขส.ทบ.\\nขส.ทร.\\nขส.ทอ.\\nค.ด.\\nค.บ.\\nค.พ.ศ.\\nค.ม.\\nค.ร.น.\\nค.ร.ฟ.\\nค.ร.ม.\\nค.ศ.\\nค.อ.ด.\\nค.อ.บ.\\nค.อ.ม.\\nคศ.ด.\\nคศ.บ.\\nคศ.ม.\\nง.ด.\\nจ.จ.\\nจ.จ.จ.\\nจ.ช.\\nจ.ต.\\nจ.ท.\\nจ.ป.ร.\\nจ.ม.\\nจ.ศ.\\nจ.ส.ต.\\nจ.ส.ท.\\nจ.ส.อ.\\nจ.อ.\\nจ.อ.ร.\\nจ.๑๘\\nจก.ธน.\\nจก.สน.\\nช.ค.\\nช.ค.บ.\\nช.พ.ค.\\nช.ส.\\nช.ส.ค.\\nฌ.ป.ค.\\nฌ.ศ.ร.\\nฌ.ส.อ.\\nฐท.สห.\\nด.ช.\\nด.ญ.\\nด.ต.\\nด.ศ.ค.\\nด.ศ.ร.\\nดย.ทร.\\nต.ก.\\nต.ค.\\nต.จ.\\nต.จ.ว.\\nต.ช.\\nต.ต.\\nต.บ.\\nต.ม.\\nต.ร.\\nต.ศ.ร.\\nต.ห.\\nต.อ.\\nต.อ.จ.\\nตร.กม.\\nตร.ซม.\\nตร.ต.\\nตร.ทล.\\nตร.น.\\nตร.ปม.\\nตร.ภ.\\nตร.ม.\\nตร.รฟ.\\nตร.ว.\\nตร.ส.\\nตร.สข.\\nท.จ.\\nท.จ.ว.\\nท.ช.\\nท.ญ.\\nท.ด.\\nท.ท.ท.\\nท.ทบ.\\nท.บ.\\nท.พ.\\nท.ม.\\nท.ศ.\\nทก.ด.\\nทก.บ.\\nทก.ม.\\nทส.ปช.\\nทส.รมว.กห.\\nทุ.ส.นิ.ม.\\nธ.ก.ส.\\nธ.ค.\\nธ.ญ\\nธ.บ.\\nน.ช.\\nน.ญ.\\nน.ด.\\nน.ต.\\nน.ท.\\nน.น.\\nน.บ.\\nน.บ.ท.\\nน.ป.ท.\\nน.พ.\\nน.ม.\\nน.ร.\\nน.ว.\\nน.ศ.\\nน.ส.\\nน.ส.พ.\\nน.ส.๓\\nน.สพ.\\nน.อ.\\nนปพ.ภ.\\nนศ.ด.\\nนศ.บ.\\nนศ.ม.\\nบ.ก.\\nบ.ข.ส.\\nบ.ช.\\nบ.ด.ท.\\nบ.ตร.\\nบ.ภ.\\nบ.ม.\\nบก.จร.\\nบก.ตชด.\\nบก.ตม.\\nบก.ทล.\\nบก.น.\\nบก.ป.\\nบก.ปค.\\nบก.ปม.\\nบก.ภ.เขต\\nบก.รน.\\nบก.รฟ.\\nบก.ร้อย.ตชด.\\nบก.ส.\\nบกข.ป.\\nบจพ.ป.\\nบช.ก.\\nบช.ด.\\nบช.ตชด.\\nบช.น.\\nบช.บ.\\nบช.ปส.\\nบช.ภ.\\nบช.ม.\\nบชท.ป.\\nบชน.ป.\\nบชส.ป.\\nบธ.ด.\\nบธ.บ.\\nบธ.ม.\\nบนท.ป.\\nบนอ.ป.\\nบปช.ป.\\nป.กท.\\nป.กศ.\\nป.กศ.สูง\\nป.จ.\\nป.จ.ว.\\nป.ช.\\nป.ธ.\\nป.ป.\\nป.ป.ก.\\nป.ป.ช.\\nป.ป.ป.\\nป.ป.ร.\\nป.ป.ส.\\nป.พ.\\nป.พ.พ.\\nป.พย.\\nป.ม.\\nป.ม.ก.\\nป.ม.ช.\\nป.ม.ธ.\\nป.ม.ศ.\\nป.ม.อ.\\nป.ร.ร.๔\\nป.ร.ร.๕\\nป.ร.ร.๖\\nป.ล.\\nป.ว.พ.\\nป.วิ.อ.\\nป.ส.ส.\\nป.อ.\\nป.อ.ร.ส.\\nป.๑\\nปม.วส.\\nปอ.พ.\\nผกก.ภ.\\nผช.ผอ.\\nผต.มท.\\nผบ.ตร.\\nผบ.ทบ.\\nผบ.ทร.\\nผบ.ทสส.\\nผบ.ทอ.\\nผบก.น.\\nผบก.ป.\\nผบก.ปค.\\nผบก.ปม.\\nผบก.ภ.\\nผบช.ก.\\nผบช.ตชด.\\nผบช.น.\\nผบช.ภ.\\nผว.กทม.\\nผอ.ปจ.\\nพ.ก.ง.\\nพ.กศ.\\nพ.ข.ต.\\nพ.ค.\\nพ.ค.ช.\\nพ.ค.ว.\\nพ.ค.ศ.\\nพ.จ.ต.\\nพ.จ.ท.\\nพ.จ.อ.\\nพ.ช.\\nพ.ช.ค.\\nพ.ด.\\nพ.ต.\\nพ.ต.ต.\\nพ.ต.ท.\\nพ.ต.อ.\\nพ.ต.อ.พิเศษ\\nพ.ท.\\nพ.บ.\\nพ.ป.\\nพ.ภ.ม.\\nพ.ม.\\nพ.ม.ช.\\nพ.ย.\\nพ.ร.ก.\\nพ.ร.ฎ.\\nพ.ร.ต.\\nพ.ร.ธ.\\nพ.ร.บ.\\nพ.ศ.\\nพ.ศ.บ.\\nพ.ส.ร.\\nพ.ส.ล.\\nพ.อ.\\nพ.อ.ต.\\nพ.อ.ท.\\nพ.อ.พิเศษ\\nพ.อ.อ.\\nพณ.ด.\\nพณ.บ.\\nพณ.ม.\\nพธ.ด.\\nพธ.บ.\\nพธ.ม.\\nพบ.ด.\\nพบ.บ.\\nพบ.ม.\\nพย.ด.\\nพย.บ.\\nพย.ม.\\nพล.จ.\\nพล.ต.\\nพล.ต.จ.\\nพล.ต.ต.\\nพล.ต.ท.\\nพล.ต.อ.\\nพล.ท.\\nพล.ปตอ.\\nพล.ม.\\nพล.ม.๒\\nพล.ร.จ.\\nพล.ร.ต.\\nพล.ร.ท.\\nพล.ร.อ.\\nพล.อ.\\nพล.อ.จ.\\nพล.อ.ต.\\nพล.อ.ท.\\nพล.อ.อ.\\nพลา.ทร.\\nพศ.ด.\\nพศ.บ.\\nพศ.ม.\\nพอ.สว.\\nภ.ง.ด.\\nภ.ง.ด.๙\\nภ.ด.\\nภ.บ.\\nภ.บ.ท.๕\\nภ.ป.ร.\\nภ.พ.\\nภ.ม.\\nภ.สถ.บ.\\nม.ค.\\nม.จ.\\nม.ป.ท.\\nม.ป.ป.\\nม.ป.พ.\\nม.ร.ว.\\nม.ศ.\\nม.อ.\\nม.อ.ปัตตานี\\nมิ.ย.\\nมี.ค.\\nยศ.ทบ.\\nยศ.ทร.\\nยศ.ทอ.\\nร.ง.\\nร.ด.\\nร.ต.\\nร.ต.ต.\\nร.ต.ท.\\nร.ต.อ.\\nร.ท.\\nร.น.\\nร.บ.\\nร.พ.\\nร.ฟ.ล.\\nร.ย.ล.\\nร.ย.ส.ท.\\nร.ล.\\nร.ศ.\\nร.ส.พ.\\nร.อ.\\nรป.ม.\\nรร.จปร.\\nรร.จอ.\\nรร.ชท.\\nรร.ตท.\\nรร.นร.\\nรร.นรต.\\nรร.นอ.\\nล.ญ.\\nล.ว.\\nลส.ชบ.\\nว.ค.\\nว.ฉ.\\nว.ช.\\nว.ด.ป.\\nว.ป.ถ.\\nวท.บ.\\nศ.บ.\\nศ.ป.ก.\\nศ.ศ.ป.\\nศฝร.ภ.\\nศศ.บ.\\nศษ.บ.\\nศส.บ.\\nส.ก.\\nส.ก.ศ.ท.\\nส.ค.\\nส.ค.1\\nส.ค.ร.\\nส.ค.ส.\\nส.ต.\\nส.ต.ต.\\nส.ต.ท.\\nส.ต.อ.\\nส.ท.\\nส.ทร.\\nส.ป.ช.\\nส.ป.ส.ท.\\nส.ป.อ.\\nส.ร.\\nส.ล.น.\\nส.ว.\\nส.ว.ท.\\nส.ว.ส.ท.\\nส.ส.\\nส.ส.ท.\\nส.ส.ร.\\nส.ห.\\nส.อ.\\nสถ.บ.\\nสนง.สสอ.\\nสพ.ญ.\\nสพ.บ.\\nสว.จร.\\nสว.ธร.\\nสว.ส.\\nสว.สป.\\nสว.สส.\\nสว.อก.\\nสส.บ.\\nสุ.จิ.ปุ.ลิ.\\nห.ร.ม.\\nอ.ก.ค.\\nอ.ก.จ.\\nอ.จ.\\nอ.ช.พ.\\nอ.ตร.\\nอ.บ.\\nอ.ส.ท.\\nอ.ส.ม.ท.\\nอ.ส.ย.\\nอ.อ.ป.\\nอส.รด.\\nอุ.อา.ก.ส.\\nฮ.จ.\\nฮ.ท.\\nฮ.ฝ.\\nฮ.ล.\\nฮ.ศ.\\nเม.ย.\\n\\nกรีนิช\\nกลันตัน\\nกัลกัตตา\\nกัวลาลัมเปอร์\\nกัศมีร์\\nกาฐมาณฑุ\\nโกลกาตา\\nควิเบก\\nคอนเนตทิคัต\\nคาบูล\\nคุชราต\\nคุนหมิง\\nเคนตักกี\\nเคนทักกี\\nเคมบริดจ์\\nแคชเมียร์\\nแคนซัส\\nแคนเบอร์รา\\nแคโรไลนา\\nแคลิฟอร์เนีย\\nโคเปนเฮเกน\\nโคลัมโบ\\nโคโลราโด\\nไครสต์เชิร์ช\\nไคโร\\nจาการ์ตา\\nจำปาศักดิ์\\nเจนไน\\nเจนีวา\\nเจ้อเจียง\\nฉงชิ่ง\\nเฉิงตู\\nชานตง\\nชิคาโก\\nเชนไน\\nเชอร์โนบิล\\nซัปโปโร\\nซานมารีโน\\nซาบาห์\\nซาราเยโว\\nซาราวัก\\nซิดนีย์\\nซีอาน\\nซีแอตเทิล\\nซูริก\\nซูริค\\nเซเชลส์\\nเซนได\\nเซี่ยงไฮ้\\nโซเฟีย\\nโซล\\nโซโลมอน\\nไซ่ง่อน\\nไซบีเรีย\\nดัลลัส\\nดาโคตา\\nดานัง\\nดีทรอยต์\\nดูไบ\\nเดนเวอร์\\nเดลาแวร์\\nเดียนเบียนฟู\\nโดเวอร์\\nโดฮา\\nไดฟุกุ\\nไดฟูกุ\\nตรังกานู\\nตริโปลี\\nตูวาลู\\nเตหะราน\\nโตเกียว\\nโตรอนโต\\nทมิฬนาฑู\\nทริโปลี\\nทิเบต\\nเทกซัส\\nเท็กซัส\\nเทนเนสซี\\nเทลอาวีฟ\\nแทสเมเนีย\\nโทรอนโต\\nไทเป\\nธากา\\nนางาซากิ\\nนาริตะ\\nนิวเจอร์ซีย์\\nนิวเดลี\\nนิวยอร์ก\\nนิวยอร์ค\\nนิวแฮมป์เชียร์\\nเนบราสกา\\nเนแบรสกา\\nเนวาดา\\nบรัสเซลส์\\nบราซิเลีย\\nบอมเบย์\\nบอสตัน\\nบังกาลอร์\\nบังคาลอร์\\nบูคาเรสต์\\nบูดาเปสต์\\nเบงกาซี\\nเบนกาซี\\nเบรุต\\nเบลเกรด\\nเบอร์ลิน\\nแบกแดด\\nปอยเปต\\nปะลิส\\nปะหัง\\nปักกิ่ง\\nปัญจาบ\\nปัฏนา\\nปารีส\\nปีนัง\\nเประ\\nเปียงยาง\\nพนมเปญ\\nพระตะบอง\\nพะโค\\nพะสิม\\nพาราณสี\\nพิหารี\\nเพนซิลวาเนีย\\nเพนซิลเวเนีย\\nฟรานซ์\\nฟลอริดา\\nฟิลาเดลเฟีย\\nฟุกุชิมะ\\nฟุกุชิมา\\nฟุกุโอกะ\\nฟูกูโอกะ\\nแฟรงก์เฟิร์ต\\nมอสโก\\nมะนิลา\\nมะละแหม่ง\\nมัณฑะเลย์\\nมัทราส\\nมาดริด\\nมิชิแกน\\nมินนิโซตา\\nมิยางิ\\nมิลาน\\nมิวนิก\\nมิสซูรี\\nมุมไบ\\nเมน\\nเมลเบิร์น\\nเมาะตะมะ\\nเมาะลำเลิง\\nแมนจูเรีย\\nแมนเชสเตอร์\\nแมนฮัตตัน\\nแมริแลนด์\\nแมรีแลนด์\\nแมสซาชูเซตส์\\nยะไข่\\nย่างกุ้ง\\nยูทาห์\\nยูนนาน\\nเยรูซาเล็ม\\nโยโกฮามา\\nริยาด\\nรีโอเดจาเนโร\\nโรดไอแลนด์\\nลอนดอน\\nลอสแองเจลิส\\nลาปาซ\\nลาสเวกัส\\nลิสบอน\\nลุยเซียนา\\nโลซาน\\nโลซานน์\\nวอชิงตัน\\nวอร์ซอ\\nวิสคอนซิน\\nเวนิส\\nเวลส์\\nเวอร์จิเนีย\\nเวอร์มอนต์\\nเวียงจันทน์\\nเวียนนา\\nแวนคูเวอร์\\nไวโอมิง\\nสกอตแลนด์\\nสก็อตแลนด์\\nสตอกโฮล์ม\\nสลังงอร์\\nเสฉวน\\nเสียมราฐ\\nเสียมเรียบ\\nหงสา\\nหงสาวดี\\nหนานไห่\\nหลวงพระบาง\\nหูเป่ย\\nหูเป่ย์\\nหูหนาน\\nเหอเป่ย\\nเหอเป่ย์\\nเหอหนาน\\nอชันตา\\nอลาสกา\\nอวันตี\\nออริกอน\\nออสโล\\nอะแลสกา\\nอัตตะปือ\\nอัมมาน\\nอัมสเตอร์ดัม\\nอัสสัม\\nอาบูดาบี\\nอาร์คันซอ\\nอินเดียนา\\nอิบารากิ\\nอิลลินอยส์\\nอิสตันบูล\\nอิสลามาบัด\\nอุรุมชี\\nอูลานบาตอร์\\nเอดินบะระ\\nเอเธนส์\\nแอตแลนตา\\nแอริโซนา\\nแอลเจียร์\\nโอคลาโฮมา\\nโอค็อตสค์\\nโอกินาวา\\nโอซากา\\nโอริสสา\\nโอเรกอน\\nโอไฮโอ\\nไอดาโฮ\\nไอโอวา\\nฮอนโนลูลู\\nฮานอย\\nฮาเนดะ\\nฮาราเร\\nฮาวาย\\nฮิโรชิมา\\nฮุสตัน\\nเฮลซิงกิ\\n\\nมกรา\\nกุมภา\\nมีนา\\nเมษา\\nพฤษภา\\nมิถุนา\\nกรกฎา\\nสิงหา\\nกันยา\\nตุลา\\nพฤศจิกา\\nธันวา\\nเอ\\nบี\\nซี\\nดี\\nอี\\nเอฟ\\nจี\\nเอช\\nไอ\\nเจ\\nเค\\nแอล\\nเอ็ม\\nเอ็น\\nโอ\\nพี\\nคิว\\nอาร์\\nเอส\\nที\\nยู\\nวี\\nดับเบิล\\nดับบลิว\\nเอ็กซ์\\nเอ๊กซ์\\nวาย\\nแซด\\nแอลฟา\\nแอลฟ่า\\nเบตา\\nเบต้า\\nแกมมา\\nแกมม่า\\nเดลตา\\nเดลต้า\\nโอเมกา\\nโอเมก้า\\nเมกะ\\nกิกะ\\nนาโน\\nไมโคร\\n\\nกรรมาชน\\nกรอบรูป\\nกระดี๊กระด๊า\\nกระบับ\\nกราวนด์\\nกรีน\\nกรุ๊ป\\nกฤษณ์\\nกลาส\\nก๊วน\\nกษัตริยา\\nกษัตริยาธิราช\\nก่อนหน้า\\nกะบับ\\nกับดัก\\nกัมมันตะ\\nก๊าก\\nก๋ากั่น\\nกาญจน์\\nกาญจนาภิเษก\\nกามิกาเซ่\\nการันตี\\nกาหลิบ\\nกิฟท์\\nกิมจิ\\nกีวี\\nกึ๊ก\\nกึ๋ย\\nกุนซือ\\nกุมภาพันธ์\\nกู๋\\nเกจิ\\nเกมส์\\nเกย์\\nเกรด\\nเกรย์\\nเกสต์เฮาส์\\nเก๊ะ\\nเก๋ากี้\\nเกิร์ล\\nแกงค์\\nแกรนด์\\nแกสโซฮอล์\\nแก๊สโซฮอล์\\nโกเต็กซ์\\nโกลด์\\nโกะ\\nโก๊ะ\\nไกด์\\nขั้นตอน\\nเขวี้ยง\\nคณาญาติ\\nครัวซอง\\nครัวซองต์\\nคร่ำครวญ\\nครีเอทีฟ\\nครูเสด\\nคลับ\\nคลาสสิก\\nคลิตอริส\\nคลิป\\nความหมาย\\nควิก\\nควีน\\nคองเกรส\\nคอนซูเมอร์\\nคอนเซปต์\\nคอนเซ็ปต์\\nคอนโด\\nคอนโดมิเนียม\\nคอนเทนเนอร์\\nคอนแทค\\nคอนแท็ค\\nคอนโทรล\\nคอนเฟิร์ม\\nคอปเตอร์\\nคอมพ์\\nคอมเพล็กซ์\\nคอมมอนส์\\nคอมเมนท์\\nคอมเมนต์\\nคอร์ป\\nคอร์ปอเรชั่น\\nคอร์รัปชัน\\nคอร์รัปชั่น\\nคอรัปชัน\\nคอรัปชั่น\\nคอร์ส\\nคอลเล็กชั่น\\nคอลัมน์\\nคอลัมนิสต์\\nคัตเอาต์\\nคันคาก\\nคันถธุระ\\nคันธาระ\\nคันยิ\\nคัสตาร์ด\\nคาราโอเกะ\\nคีตกวี\\nคีตปฏิภาณ\\nคีตราชัน\\nคาปูชิโน\\nคามิคาเซ่\\nคาเฟ่\\nคาร์\\nคาร์โก้\\nคาราเมล\\nคาแรกเตอร์\\nคาแร็กเตอร์\\nคาแรคเตอร์\\nคาแร็คเตอร์\\nคาวบอย\\nคาสิโน\\nคิกขุ\\nคิวบิก\\nคูลเลอร์\\nเคบับ\\nเครป\\nเคลม\\nเคลียร์\\nเคลื่อนย้าย\\nเคส\\nเคอร์ฟิว\\nแคชเชียร์\\nแคทวอล์ค\\nแคนดิเดต\\nแคนตาลูป\\nแคนยอน\\nแคนู\\nแคป\\nแคมป์\\nแคมปัส\\nแคมเปญ\\nแคร์\\nแครกเกอร์\\nแคร็กเกอร์\\nแครอท\\nแคสต์\\nแคสติง\\nแคสติ้ง\\nโค้ก\\nโค้ช\\nโคโยตี\\nโคโยตี้\\nโครนา\\nโคอะล่า\\nโคอาลา\\nโคอาล่า\\nไคลแมกซ์\\nไคลแม็กซ์\\nงั้น\\nง่าว\\nงี้\\nเง็ง\\nโง่เขลา\\nไง\\nจตุคาม\\nจ๊อกกี้\\nจอหงวน\\nจังโก้\\nจัมโบ้\\nจ๊าบ\\nจารกรรม\\nจารชน\\nจิ๊ก\\nจิ๊กโก๋\\nจิ๊กซอว์\\nจิตพิสัย\\nจิตเภท\\nจีดีพี\\nจึ๊ก\\nจุ๊ย\\nจูน\\nจูเนียร์\\nเจ๊\\nเจได\\nเจ็ต\\nเจล\\nเจ๊าะแจ๊ะ\\nเจี๊ยว\\nแจ็กเก็ต\\nแจ๊กเก็ต\\nแจ็กพอต\\nแจ็กพ็อต\\nแจ๊กพอต\\nแจ๊กพ็อต\\nแจม\\nแจ๊ส\\nโจ๋\\nฉลุย\\nเฉิ่ม\\nชนะเลิศ\\nช็อค\\nช็อต\\nช็อป\\nช็อปปิ้ง\\nช็อปเปอร์\\nชะโนด\\nชัตเตอร์\\nชัวร์\\nชาร์จ\\nชาร์ต\\nชาร์ป\\nชินบัญชร\\nชิฟฟอน\\nชีส\\nชีอะห์\\nเช็ก\\nเช็งเม้ง\\nเชฟ\\nเชลียร์\\nเชอร์รี่\\nแชเชือน\\nแช่แข็ง\\nแชมป์\\nแชมปิยอง\\nแชมเปญ\\nแชมเปี้ยน\\nแชมพู\\nโชว์รูม\\nโชห่วย\\nใช้งาน\\nไชน่า\\nซ้อ\\nซอมบี้\\nซะ\\nซังเต\\nซันตาคลอส\\nซัพพลาย\\nซัพพลายเออร์\\nซัมเมอร์\\nซากุระ\\nซาดิสต์\\nซาดิสม์\\nซาตาน\\nซานตาคลอส\\nซาฟารี\\nซาบะ\\nซามูไร\\nซาร์\\nซาร์ดีน\\nซาเล้ง\\nซิง\\nซิ่ง\\nซิงเกิล\\nซิตี\\nซิตี้\\nซินโดรม\\nซิม\\nซิ้ม\\nซิมโฟนี\\nซิมโฟนี่\\nซิลเวอร์\\nซี้\\nซี้ซั้ว\\nซีดาน\\nซีน\\nซีนีเพล็กซ์\\nซีเนียร์\\nซีร็อกซ์\\nซีรีส์\\nซีเรียส\\nซีอีโอ\\nซื่อบื้อ\\nซุนหนี่\\nซุปเปอร์\\nซูชิ\\nซูเปอร์\\nซูม\\nซูโม่\\nซูเอี๋ย\\nซูฮก\\nเซ็กซ์\\nเซ็กซี่\\nเซ็กส์\\nเซนเซอร์\\nเซ็นเซอร์\\nเซนเตอร์\\nเซ็นเตอร์\\nเซ็นทรัล\\nเซนส์\\nเซ่นไหว้\\nเซฟตี้\\nเซรามิก\\nเซลส์\\nเซลส์แมน\\nเซอร์\\nเซอร์ไพรส์\\nเซอร์วิส\\nเซาท์\\nเซี้ยว\\nแซ็ก\\nแซกโซโฟน\\nแซ็กโซโฟน\\nแซนด์วิช\\nแซมบ้า\\nแซลมอน\\nแซว\\nโซเชียล\\nโซน\\nโซนี่\\nโซลาร์\\nโซโล\\nโซโล่\\nญาณทัสสนะ\\nดยุก\\nดยุค\\nดร็อป\\nดรัมเมเยอร์\\nดรามา\\nดราม่า\\nดอกเตอร์\\nด็อกเตอร์\\nดัมพ์\\nดั๊มพ์\\nดาวน์\\nดิกชันนารี\\nดิสเครดิต\\nดีกรี\\nดีเจ\\nดีไซน์\\nดีไซน์เนอร์\\nดีไซเนอร์\\nดีเบต\\nดีพาร์ตเมนต์\\nดีพาร์ตเมนท์\\nดีพาร์ทเมนต์\\nดีพาร์ทเมนท์\\nดีมานด์\\nดีล\\nดีลเลอร์\\nดีเลย์\\nเดชานุภาพ\\nเดบิต\\nเดโม\\nเดย์\\nเด้อ\\nเดอะ\\nเด๊ะ\\nเดี้ยง\\nเดี๊ยะ\\nแดนซ์\\nแดนเซอร์\\nแดรี่\\nโดนัท\\nโดมิโน\\nโดรายากิ\\nไดเอ็ต\\nตถตา\\nตนเอง\\nตรวจทาน\\nตรวจสอบ\\nตอกย้ำ\\nต๊อง\\nต่อยอด\\nต่อรอง\\nตะหงิด\\nตังค์\\nตันเถียน\\nตัวตน\\nตัวเอง\\nตาปรือ\\nต้าอ่วย\\nติงต๊อง\\nติ๋ม\\nติ่มซำ\\nติว\\nติวเตอร์\\nตี๋\\nตื้บ\\nตุ๊ก\\nตุ๊กตุ๊ก\\nตุ๊ด\\nตุ๋ย\\nตู้เซฟ\\nเต๊ะ\\nเตี๊ยม\\nแตงกวา\\nแตงโม\\nแต๋ว\\nโต๋เต๋\\nโต๊ะจีน\\nไตรมาส\\nถ่ายทำ\\nถูกต้อง\\nทงคัตสึ\\nทริป\\nทรู\\nทอม\\nท็อป\\nทอร์นาโด\\nทอล์ค\\nทักซิโด\\nทันตกรรม\\nทันตแพทยศาสตร์\\nทับซ้อน\\nทัวร์\\nทัวร์นาเมนต์\\nทัวร์นาเมนท์\\nทัวริสต์\\nทาเลนต์\\nทาวน์\\nทาวน์เฮาส์\\nทำงาน\\nทิป\\nทิพยสมบัติ\\nทิวลิป\\nทีรามิสุ\\nทีวี\\nทูน่า\\nเท็กซ์\\nเทค\\nเทคโน\\nเทคโนแครต\\nเทควันโด\\nเทป\\nเทรด\\nเทรนด์\\nเทรนเนอร์\\nเทรลเลอร์\\nเทรลเล่อร์\\nเทเลกราฟ\\nเทวบัญชา\\nเทวบุตร\\nเทวา\\nเทวาธิราช\\nเทโวโรหนะ\\nเทอร์โบ\\nเที่ยงคืน\\nเที่ยงวัน\\nเทียมทาน\\nแทกติค\\nแทคติค\\nแทงกั๊ก\\nแทงโก้\\nโทมาฮอก\\nโทมาฮอว์ก\\nโทมาฮอว์ค\\nโทร\\nโทรโข่ง\\nไทม์\\nไทยแลนด์\\nไทเฮา\\nธรรมา\\nธรรมาภิบาล\\nธัมโม\\nธีม\\nธุรกรรม\\nธุหร่ำ\\nเธค\\nนพมาศ\\nนรีแพทย์\\nน็อก\\nน็อค\\nน้องใหม่\\nนอมินี\\nนอร์ท\\nน่ะ\\nนางแบบ\\nนาฏยศาลา\\nนายแบบ\\nนายพราน\\nนินจา\\nนิรันดร์\\nนิว\\nนิวส์\\nนู้ด\\nเนอะ\\nเนิร์สเซอรี\\nเนิร์สเซอรี่\\nเนี้ยบ\\nโนติส\\nไนท์\\nไนน์\\nบรรพชน\\nบร็อกโคลี\\nบร็อคโคลี\\nบรา\\nบริกร\\nบริวเวอรี่ส์\\nบลอนด์\\nบลูเบอร์รี\\nบลูเบอร์รี่\\nบ๊วย\\nบอกซ์\\nบ็อกซ์\\nบ๊อกซ์\\nบอดี้\\nบอนด์\\nบ๊อบ\\nบอมบ์\\nบ๋อย\\nบอยคอต\\nบอยคอตต์\\nบอร์ด\\nบังเกอร์\\nบัตเตอร์\\nบัลลาสต์\\nบัส\\nบาบูน\\nบาร์บีคิว\\nบาร์บี้\\nบาลานซ์\\nบิ๊ก\\nบิล\\nบึม\\nบึ้ม\\nบุญคุณ\\nบุ๋น\\nบุปผา\\nบู๊\\nบูชิโด\\nบูติก\\nบูติค\\nบูม\\nเบเกอรี่\\nเบญจมบพิตร\\nเบตาดีน\\nเบนโตะ\\nเบนโล\\nเบบี้\\nเบลอ\\nเบอร์เกอร์\\nเบอร์รี\\nเบิร์ด\\nเบิร์น\\nแบ็กโฮ\\nแบคโฮ\\nแบด\\nแบต\\nแบนเนอร์\\nแบรนด์\\nแบล็ก\\nแบล็ค\\nไบโอ\\nโบกี้\\nโบตั๋น\\nโบ้ย\\nโบรกเกอร์\\nโบรชัวร์\\nโบว์\\nโบว์ลิ่ง\\nไบเบิล\\nปฏิสัมพันธ์\\nป๊อก\\nปอดแหก\\nป๊อป\\nป๋อหลอ\\nปักขคณนา\\nปัจเจกชน\\nปัจฉิมนิเทศ\\nป๊า\\nป๋า\\nป่าไม้\\nปาร์ตี้\\nปาสกาล\\nปาสคาล\\nปาสเตอร์\\nปิกอัพ\\nปิ๊ง\\nปิโตรเคมี\\nปิยมิตร\\nปึ้ก\\nปูอัด\\nเปโซ\\nเป็นไง\\nเปปเปอร์มินต์\\nเปเปอร์\\nเปราะบาง\\nเป๊ะ\\nเป่ายิงฉุบ\\nเป่ายิ้งฉุบ\\nเปียโน\\nแป้ก\\nแป๋ว\\nแป๊ะเจี๊ยะ\\nโปร\\nโปรเจกต์\\nโปรเจ็กต์\\nโปรเจกเตอร์\\nโปรเจ็กเตอร์\\nโปรเจคท์\\nโปรเจ็คท์\\nโปรดักชั่น\\nโปรดิวเซอร์\\nโปรโมชั่น\\nโปรโมต\\nโปรโมเตอร์\\nโปรโมท\\nโปลิศ\\nโปสเตอร์\\nผลไม้\\nผลักดัน\\nผ้าห่ม\\nผิดพลาด\\nผู้นำ\\nแผดเผา\\nเฝอ\\nพงษ์\\nพริตตี้\\nพรีเซนต์\\nพรีเซ็นเตอร์\\nพรีเมียม\\nพรีเมียร์\\nพฤหัส\\nพล็อต\\nพลาซ่า\\nพลานุภาพ\\nพ่อค้า\\nพอเพียง\\nพะเรอ\\nพันธกิจ\\nพันธุวิศวกรรม\\nพาร์\\nพาร์ตเนอร์\\nพาร์ทเนอร์\\nพาวเวอร์\\nพาสเจอร์ไรส์\\nพาสตา\\nพาสต้า\\nพาสปอร์ต\\nพาเหรด\\nพิซซ่า\\nพีเรียด\\nพุดดิ้ง\\nพุทธภูมิ\\nพุทธศตวรรษ\\nพุทโธ\\nพูล\\nเพทนาการ\\nเพนกวิน\\nเพนตากอน\\nเพรส\\nเพรียวบาง\\nเพลซ\\nเพลท\\nเพลย์บอย\\nเพียบแปร้\\nเพียว\\nเพาเวอร์\\nแพกเกจ\\nแพ็ค\\nแพตเทิร์น\\nแพทเทิร์น\\nแพทยสภา\\nแพนงเชิญ\\nแพนดา\\nแพนด้า\\nแพลน\\nโพลล์\\nโพลารอยด์\\nโพสต์\\nไพลิน\\nฟยอร์ด\\nฟรังก์\\nฟรุต\\nฟลอร์\\nฟลุก\\nฟลุค\\nฟลุต\\nฟลุท\\nฟอยล์\\nฟอร์ม\\nฟันด์\\nฟาวล์\\nฟาสต์ฟู้ด\\nฟินิกซ์\\nฟิวเจอร์\\nฟีด\\nฟีเวอร์\\nฟุตบาท\\nเฟรช\\nเฟรชชี่\\nเฟรม\\nเฟมินิสต์\\nเฟส\\nเฟอร์นิเจอร์\\nเฟอร์รี่\\nเฟิร์ม\\nเฟี้ยวฟ้าว\\nแฟกซ์\\nแฟ็กซ์\\nแฟนซี\\nแฟนตาซี\\nแฟ้บ\\nแฟร์\\nแฟรนไชส์\\nแฟรี\\nแฟรี่\\nแฟลช\\nแฟล็ต\\nโฟน\\nโฟม\\nโฟล์ค\\nไฟต์\\nไฟแนนซ์\\nไฟลต์\\nไฟลท์\\nภควัทคีตา\\nภควัมบดี\\nภควัมปติ\\nภคันทลาพาธ\\nภววิสัย\\nภารตะ\\nภูมิทัศน์\\nม้ง\\nมวลชน\\nมยุราภิรมย์\\nมลภาวะ\\nมหภาค\\nมหาอุปราชา\\nมอคคา\\nมอคค่า\\nมอนสเตอร์\\nม็อบ\\nมอบตัว\\nมอยส์เจอไรเซอร์\\nมอลล์\\nมะกัน\\nมั้ง\\nมัฟฟิน\\nมั้ย\\nม้านั่ง\\nมาเฟีย\\nมาม่า\\nมายองเนส\\nมายาคติ\\nมาร์ก\\nมาร์เก็ต\\nมาร์เก็ตติ้ง\\nมาร์ค\\nมาร์จิน\\nมาร์ช\\nมาร์ต\\nมาร์ท\\nมาราธอน\\nม้าหินอ่อน\\nมินต์\\nมินท์\\nมินิ\\nมิลค์\\nมิวสิค\\nมิสซัง\\nมิสไซล์\\nมิสเตอร์\\nมือถือ\\nมุมมอง\\nเมคอัพ\\nเมจิก\\nเมจิค\\nเมทัล\\nเมเปิล\\nเมาท์\\nเมี่ยงคำ\\nแมกกาซีน\\nแม็กกาซีน\\nแมคเคอเรล\\nแม่ค้า\\nแมชชีน\\nแมชีน\\nแมนชั่น\\nแมมบ้า\\nแมมโบ้\\nโมจิ\\nโมเดล\\nโมเดิร์น\\nโมเต็ล\\nโมโนเรล\\nโมหจริต\\nไมค์\\nไมเกรน\\nยนตรกรรม\\nยอมรับ\\nยะเยือก\\nยังไง\\nยากูซ่า\\nยาวี\\nยิม\\nยิว\\nยุวทูต\\nยูโทเปีย\\nยูโร\\nยูวี\\nเยน\\nเยลลี่\\nเย้ว\\nเยอบีรา\\nเยอบีร่า\\nเยอร์บีรา\\nเยอร์บีร่า\\nแยมโรล\\nโยเกิร์ต\\nโยโย่\\nรวมมิตร\\nร็อค\\nร็อคเก็ต\\nรองรับ\\nรอมฎอน\\nรอยัลตี้\\nระโงก\\nรันเวย์\\nรัม\\nรากหญ้า\\nราชบัณฑิตยสถาน\\nราชานุญาต\\nราชานุสาวรีย์\\nรามเทพ\\nรามาธิบดี\\nรามายณะ\\nราเม็ง\\nราเมน\\nรายชื่อ\\nราสเบอร์รี\\nริกเตอร์\\nริคเตอร์\\nรีไซเคิล\\nรีดไถ\\nรีทัช\\nรีเทิร์น\\nรีไทร์\\nรีแบรนด์\\nรีพอร์ท\\nรีโมต\\nรีโมท\\nรีวิว\\nรีสอร์ต\\nรีสอร์ท\\nรีเสิร์ช\\nรุมบ้า\\nรุสโซ\\nรูบิก\\nรูบิค\\nเรซิน\\nเรซิ่น\\nเรดิโอ\\nเรต\\nเรตติ้ง\\nแรงใจ\\nแรงดูด\\nแรงผลัก\\nแรลลี\\nแรลลี่\\nโรดแมป\\nโรเนียว\\nโรแมนติก\\nโรแมนติค\\nโรล\\nโรลออน\\nไรเฟิล\\nล็อกเกอร์\\nลอจิสติกส์\\nล็อต\\nล็อบบี้\\nลอร์ด\\nล้มเหลว\\nละติน\\nละอ่อน\\nลาซานญ่า\\nลาติน\\nลาเต้\\nลานีญา\\nลามะ\\nลิมิต\\nลิมูซีน\\nลิสต์\\nลีก\\nลีด\\nลีดเดอร์\\nลีเมอร์\\nลีลาวดี\\nลุค\\nลูกชาย\\nลูกสาว\\nเลกเชอร์\\nเลคเชอร์\\nเลดี้\\nเลสเบี้ยน\\nเลิฟ\\nแลนด์\\nแล็บ\\nโลโก้\\nโลชั่น\\nไลท์\\nไลน์\\nไลฟ์\\nวนาราม\\nวราราม\\nวโรกาส\\nว้อดก้า\\nวอเตอร์\\nวอฟเฟิล\\nว้อย\\nวอร์ม\\nวอร์มอัพ\\nวอร์รูม\\nวอล์ก\\nวอล์ค\\nวอลซ์\\nวอลนัต\\nวอลนัท\\nวอลล์\\nว่ะ\\nวันเวย์\\nวัสสา\\nวาซาบิ\\nวาทกรรม\\nวาทะ\\nวานิลลา\\nวานิลา\\nวาฟเฟิล\\nวาริชศาสตร์\\nว้าว\\nวัคค์\\nวัจนะ\\nวาไรตี้\\nวิก\\nวิดีโอ\\nวิทย์\\nวิน\\nวิป\\nวิปปิ้ง\\nวิภัชภาค\\nวิว\\nวิลล์\\nวิลเลจ\\nวีเจ\\nวีซ่า\\nวีดิทัศน์\\nวีน\\nวีไอพี\\nวืด\\nเวณิกา\\nเวเฟอร์\\nเวสต์\\nเวอร์\\nเวิร์ก\\nเวิร์กช็อป\\nเวิร์ค\\nเวิร์ลด์\\nเวิลด์\\nแวมไพร์\\nไวกิ้ง\\nไวเบรเตอร์\\nไวอะกร้า\\nไวอากร้า\\nศากยบุตร\\nศิรินทร์\\nศิลปวัฒนธรรม\\nศิลปากร\\nศิวิไลซ์\\nศึกษาศาสตร์\\nสกรัม\\nสกาย\\nสกู๊ป\\nสเกตช์\\nสเก็ตช์\\nสคริปต์\\nสแควร์\\nสงบสุข\\nสจ๊วต\\nสตรอเบอร์รี\\nสตรอเบอรี\\nสตรอว์เบอร์รี\\nสตริง\\nสต็อก\\nสต๊อก\\nสต็อค\\nสต๊อค\\nสตอรี\\nสตาร์\\nสตาร์ท\\nสติกเกอร์\\nสติ๊กเกอร์\\nสตีล\\nสตูดิโอ\\nสเตชัน\\nสเตชั่น\\nสเตเดียม\\nสเตนเลส\\nสเต็ป\\nสเตย์\\nสเตริโอ\\nสเตอริโอ\\nสแตนดาร์ด\\nสแตนเลส\\nสโตน\\nสโตร์\\nสไตรค์\\nสไตล์\\nสถาปัตย์\\nสไนเปอร์\\nสปอต\\nสป็อต\\nสปอนเซอร์\\nสปอร์ต\\nสปา\\nสปาย\\nสปิริต\\nสเปก\\nสเปค\\nสไปเดอร์\\nสมณพราหมณ์\\nสมาพันธ์\\nสมิติเวช\\nสโรชา\\nสลัม\\nสแล็ก\\nสโลแกน\\nสโลว์\\nสไลด์\\nสวีท\\nสหรัฐ\\nสหัชญาณ\\nสหัสวรรษ\\nสะกอม\\nสะเด่า\\nสะบึม\\nสะบึมส์\\nสะออน\\nสังโฆ\\nสะโหลสะเหล\\nสันทนาการ\\nสัมนา\\nสามช่า\\nสามแยก\\nสารขัณฑ์\\nสี่แยก\\nสึนามิ\\nสุนทรีย์\\nสุริยยาตร\\nสุริยยาตร์\\nสุหนี่\\nเสกสรรค์\\nเสพติด\\nเสือโคร่ง\\nหงวน\\nหน่อมแน้ม\\nหมวย\\nหมั่นโถว\\nหม่านโถว\\nหมายปอง\\nหมิง\\nหยวน\\nหลวงตา\\nหลวงปู่\\nหลวงพี่\\nหล่อฮังก้วย\\nหลินจือ\\nห่วย\\nเห็นด้วย\\nเหมย\\nเห่ย\\nเหี่ยวย่น\\nแหม็บ\\nแหวว\\nโหงว\\nโหงวเฮ้ง\\nโหลน\\nโหลยโท่ย\\nไหง\\nไหร่\\nอพาร์ตเมนต์\\nอพาร์ตเมนท์\\nอพาร์ทเมนต์\\nอพาร์ทเมนท์\\nอมาตยาธิปไตย\\nอยุติธรรม\\nอริยสงฆ์\\nอ่วม\\nอวอร์ด\\nออกแบบ\\nออดิชั่น\\nออดิทอเรียม\\nออเดอร์\\nออโต้\\nออทิสติก\\nอ่อนด้อย\\nออฟ\\nออยล์\\nออร์แกน\\nออร์แกนิก\\nออร์แกนิค\\nออร์เดอร์\\nออรัล\\nออสซี่\\nอะ\\nอัตลักษณ์\\nอัตวิสัย\\nอันเดอร์\\nอันตรกิริยา\\nอัลตรา\\nอัลไซเมอร์\\nอัลบัม\\nอัลบั้ม\\nอัลมอนด์\\nอาข่า\\nอาโนเนะ\\nอาฟเตอร์\\nอาร์ติสต์\\nอาร์พีจี\\nอาว์\\nอาสวะ\\nอิกัวนา\\nอินดอร์\\nอินดัสตรีส์\\nอินเตอร์\\nอิ่มแปร้\\nอิมพีเรียล\\nอิเล็กทริก\\nอิเล็กทริค\\nอิเลียด\\nอิสรชน\\nอิเหนา\\nอิออน\\nอีแต๋น\\nอีโรติก\\nอีเวนท์\\nอีสต์\\nอีสเตอร์\\nอึ๊บ\\nอึ้ม\\nอึ๋ม\\nอึมครึม\\nอุด้ง\\nอุตสาหการ\\nอุเทน\\nอุปการคุณ\\nอุปทาน\\nอุปนายก\\nอุปนายิกา\\nอุปสงค์\\nอุปัทวเหตุ\\nอุรังคธาตุ\\nอูคูเลเล่\\nอู้ฟู่\\nเอ๋\\nเอ็กซ์โป\\nเอ็กซ์เพรส\\nเอ็กโซเซต์\\nเอ็กโซเซ่ต์\\nเอเซีย\\nเอ็นจีโอ\\nเอ็นเตอร์เทน\\nเอนทรานซ์\\nเอ็นทรานซ์\\nเอฟเฟ็กต์\\nเอเยนต์\\nเอลนีโญ\\nเอสเปรสโซ\\nเอสเพรสโซ\\nเอ๋อ\\nเอาต์\\nเอาท์\\nเอาท์ดอร์\\nเอ๊าะ\\nแอ็กชั่น\\nแอ็คชั่น\\nแอคทีฟ\\nแอดมิชชั่น\\nแอดมิสชัน\\nแอนด์\\nแอ๊บแบ๊ว\\nแอปเปิล\\nแอปเปิ้ล\\nแอปพริคอท\\nแอพพริคอท\\nแอพริคอต\\nแอร์\\nแอโรบิก\\nแอโรบิค\\nแอลมอนด์\\nแอสเตอร์\\nโอเค\\nโอเปอเรเตอร์\\nโอเปร่า\\nโอเพ่น\\nโอ้ย\\nโอยัวะ\\nโอรสาธิราช\\nโอเลี้ยง\\nโอวัลติน\\nโอเวอร์\\nไอซ์\\nไอซียู\\nไอดอล\\nไอเดีย\\nไอติม\\nฮวงจุ้ย\\nฮ่องเต้\\nฮองเฮา\\nฮอต\\nฮ็อต\\nฮอตดอก\\nฮ็อตด็อก\\nฮันนีมูน\\nฮัม\\nฮัลโลวีน\\nฮัลโหล\\nฮากกา\\nฮาร์ด\\nฮาราคีรี\\nฮาลาล\\nฮาโลวีน\\nฮิ\\nฮิต\\nฮิบรู\\nฮิปโป\\nฮิปฮอป\\nฮีโร่\\nฮูลาฮูป\\nฮูล่าฮูป\\nเฮฟวี\\nเฮฟวี่\\nเฮอร์ริเคน\\nเฮีย\\nแฮนด์\\nแฮปปี้\\nแฮมเบอร์เกอร์\\nโฮป\\nโฮม\\nโฮลดิงส์\\nโฮลวีต\\nโฮสเตส\\nไฮกุ\\nไฮแจ็ค\\nไฮโซ\\nไฮเทค\\nไฮบริด\\nไฮเปอร์\\nไฮไลต์\\nไฮไลท์\\nไฮเวย์\\nไฮสคูล\\nไฮเอนด์\\n\\nกรีซ\\nกัมพูชา\\nกัวเตมาลา\\nกาตาร์\\nกานา\\nกาบอง\\nกายอานา\\nกินี\\nเกรนาดีนส์\\nเกรเนดา\\nเกาหลี\\nแกมเบีย\\nโกตดิวัวร์\\nคองโก\\nคอโมโรส\\nคอสตาริกา\\nคาซัคสถาน\\nคิตส์\\nคิริบาตี\\nคิริบาส\\nคิวบา\\nคีร์กีซสถาน\\nคูเวต\\nเคนยา\\nเคปเวิร์ด\\nเคย์แมน\\nแคนาดา\\nแคเมอรูน\\nโครเอเชีย\\nโคลอมเบีย\\nจอร์เจีย\\nจอร์แดน\\nจาเมกา\\nจิบูตี\\nจีน\\nชาด\\nชิลี\\nเช็ก\\nซามัว\\nซาอุ\\nซิมบับเว\\nซีเรีย\\nซูดาน\\nซูรินาเม\\nเซนต์\\nเซเนกัล\\nเซอร์เบีย\\nเซาตูเม\\nเซียร์รา\\nแซมเบีย\\nโซมาเลีย\\nโซเวียต\\nไซปรัส\\nญี่ปุ่น\\nดารุสซาลาม\\nเดนมาร์ก\\nโดมินิกัน\\nโดมินิกา\\nตรินิแดด\\nตองกา\\nติมอร์\\nตุรกี\\nตูนิเซีย\\nเติร์กเมนิสถาน\\nโตโก\\nโตเบโก\\nไต้หวัน\\nทาจิกิสถาน\\nแทนซาเนีย\\nนอร์เวย์\\nนามิเบีย\\nนาอูรู\\nนิการากัว\\nนิวซีแลนด์\\nเนเธอร์แลนด์\\nเนปาล\\nเนวิส\\nไนจีเรีย\\nไนเจอร์\\nบราซิล\\nบริติช\\nบริเตน\\nบรูไน\\nบอตสวานา\\nบอสเนีย\\nบังกลาเทศ\\nบังคลาเทศ\\nบัลแกเรีย\\nบาร์บูดา\\nบาร์เบโดส\\nบาห์เรน\\nบาฮามาส\\nบิสเซา\\nบุรุนดี\\nบูร์กินาฟาโซ\\nเบนิน\\nเบลเยียม\\nเบลารุส\\nเบลีซ\\nเบอร์มิวดา\\nโบลิเวีย\\nปรินซิปี\\nปากีสถาน\\nปานามา\\nปาปัวนิวกินี\\nปารากวัย\\nปาเลสไตน์\\nปาเลา\\nเปรู\\nเปอร์เซีย\\nเปอร์โตริโก\\nโปรตุเกส\\nโปแลนด์\\nฝรั่งเศส\\nพม่า\\nฟิจิ\\nฟินแลนด์\\nฟิลิปปินส์\\nเฟรนช์\\nภูฏาน\\nภูฐาน\\nมองโกเลีย\\nมอนเตเนโกร\\nมอนแทนา\\nมอริเชียส\\nมอริเตเนีย\\nมอลโดวา\\nมอลตา\\nมัลดีฟส์\\nมาเก๊า\\nมาซิโดเนีย\\nมาดากัสการ์\\nมาร์แชลล์\\nมาลาวี\\nมาลี\\nมาเลเซีย\\nเม็กซิโก\\nเมียนมาร์\\nโมซัมบิก\\nโมนาโก\\nโมนาโค\\nโมร็อกโก\\nไมโครนีเซีย\\nยูกันดา\\nยูโกสลาเวีย\\nยูเครน\\nเยเมน\\nเยอรมนี\\nรวันดา\\nรัสเซีย\\nโรมาเนีย\\nลักเซมเบิร์ก\\nลัตเวีย\\nลาว\\nลิกเตนสไตน์\\nลิทัวเนีย\\nลิเบีย\\nลีโอน\\nลูเซีย\\nเลโซโท\\nเลบานอน\\nเลสเต\\nไลบีเรีย\\nวาติกัน\\nวานูอาตู\\nวินเซนต์\\nเวเนซุเอลา\\nเวียดนาม\\nศรีลังกา\\nสเปน\\nสโลวะเกีย\\nสโลวัก\\nสโลวีเนีย\\nสวาซิแลนด์\\nสวิตเซอร์แลนด์\\nสวีเดน\\nสหรัฐ\\nสหราชอาณาจักร\\nสิกขิม\\nสิงคโปร์\\nอเมริกา\\nออสเตรเลีย\\nออสเตรีย\\nอันดอร์รา\\nอัฟกานิสถาน\\nอาเซอร์ไบจาน\\nอาร์เจนตินา\\nอาร์เมเนีย\\nอาระเบีย\\nอิเควทอเรียล\\nอิตาลี\\nอินเดีย\\nอินโดนีเซีย\\nอิรัก\\nอิสราเอล\\nอิหร่าน\\nอียิปต์\\nอุซเบกิสถาน\\nอุรุกวัย\\nเอกวาดอร์\\nเอธิโอเปีย\\nเอมิเรตส์\\nเอริเทรีย\\nเอลซัลวาดอร์\\nเอสโตเนีย\\nแองโกลา\\nแอนติกา\\nแอลจีเรีย\\nแอลเบเนีย\\nโอมาน\\nไอซ์แลนด์\\nไอร์แลนด์\\nฮ่องกง\\nฮอนดูรัส\\nฮังการี\\nเฮติ\\nเฮอร์เซโกวีนา\\n\\nกระบี่\\nกรุงเทพ\\nกาญจนบุรี\\nกาฬสินธุ์\\nกำแพงเพชร\\nขอนแก่น\\nจันทบุรี\\nฉะเชิงเทรา\\nชลบุรี\\nชัยนาท\\nชัยภูมิ\\nชุมพร\\nเชียงราย\\nเชียงใหม่\\nตรัง\\nตราด\\nตาก\\nนครนายก\\nนครปฐม\\nนครพนม\\nนครราชสีมา\\nนครศรีธรรมราช\\nนครสวรรค์\\nนนทบุรี\\nนราธิวาส\\nน่าน\\nบึงกาฬ\\nบุรีรัมย์\\nปทุมธานี\\nประจวบคีรีขันธ์\\nปราจีนบุรี\\nปัตตานี\\nพะเยา\\nพังงา\\nพัทลุง\\nพิจิตร\\nพิษณุโลก\\nเพชรบุรี\\nเพชรบูรณ์\\nแพร่\\nภูเก็ต\\nมหาสารคาม\\nมุกดาหาร\\nแม่ฮ่องสอน\\nยโสธร\\nยะลา\\nร้อยเอ็ด\\nระนอง\\nระยอง\\nราชบุรี\\nลพบุรี\\nลำปาง\\nลำพูน\\nเลย\\nศรีสะเกษ\\nสกลนคร\\nสงขลา\\nสตูล\\nสมุทรปราการ\\nสมุทรสงคราม\\nสมุทรสาคร\\nสระแก้ว\\nสระบุรี\\nสิงห์บุรี\\nสุโขทัย\\nสุพรรณบุรี\\nสุราษฎร์\\nสุราษฎร์ธานี\\nสุรินทร์\\nหนองคาย\\nหนองบัวลำภู\\nอยุธยา\\nอ่างทอง\\nอำนาจเจริญ\\nอุดรธานี\\nอุตรดิตถ์\\nอุทัยธานี\\nอุบลราชธานี\\nกันทรลักษ์\\nจตุจักร\\nไชยา\\nซีคอน\\nดอนเมือง\\nถลาง\\nไทรโยค\\nธนบุรี\\nธัญบุรี\\nบางกอก\\nบางปะกง\\nบางระจัน\\nปะทิว\\nปาย\\nพญาไท\\nพัฒน์พงษ์\\nพัทยา\\nพารากอน\\nภูมิซรอล\\nรัตนาธิเบศร์\\nรังสิต\\nลันตา\\nลาดพร้าว\\nวโรรส\\nวิภาวดี\\nสตึก\\nสมุย\\nสัตหีบ\\nสิมิลัน\\nสุขุมวิท\\nสุไหง\\nเสลภูมิ\\nอังรีดูนังต์\\nอ่างขาง\\nอินทนนท์\\nเอ็มโพเรียม\\n\\nคิวชู\\nแคริบเบียน\\nแคสเปียน\\nดานูบ\\nตะนาวศรี\\nนอร์วีเจียน\\nนิโคบาร์\\nเนรัญชรา\\nไนล์\\nบอร์เนียว\\nบอลติก\\nเบงกอล\\nปิง\\nแปซิฟิก\\nมะละกา\\nมินดาเนา\\nมิสซิสซิปปี\\nเมดิเตอร์เรเนียน\\nเมโสโปเตเมีย\\nยมุนา\\nยุโรป\\nยูเรเชีย\\nยูเรเซีย\\nแยงซี\\nแยงซีเกียง\\nสแกนดิเนเวีย\\nสะโตง\\nสาละวิน\\nสุมาตรา\\nสุเอซ\\nอะเมซอน\\nอันดามัน\\nอัลไต\\nอาร์กติก\\nอาหรับ\\nอินโดจีน\\nอิรวดี\\nอิระวดี\\nอีเจียน\\nอุษาคเณย์\\nอูราล\\nเอเชีย\\nเอเดรียติก\\nเอเวอเรสต์\\nแอตแลนติก\\nแอนตาร์กติก\\nแอนตาร์กติกา\\nแอฟริกา\\nโอลิมปัส\\nไอโอเนียน\\nฮวงโห\\nฮอกไกโด\\nฮอนชู\\n\\nกบิลพัสดุ์\\nกุสินารา\\nโกลิยะ\\nโกสัมพี\\nโคตรบอง\\nโคตรบูรณ์\\nตองอู\\nทรอย\\nทวารวดี\\nทวาราวดี\\nเทวทหะ\\nไทรบุรี\\nนาลันทา\\nไบแซนไทน์\\nปรัสเซีย\\nปัลลวะ\\nปาฏลีบุตร\\nพุทธคยา\\nมถุรา\\nมายัน\\nมิถิลา\\nราชคฤห์\\nล้านช้าง\\nล้านนา\\nลุมพินี\\nวัชชี\\nเวสาลี\\nสารนาถ\\nสาวัตถี\\nหริภุญชัย\\nอโยธยา\\nออตโตมัน\\nอังวะ\\nอินทปัตถ์\\nอุชเชนี\\n\\nกราฟิก\\nกราฟิกส์\\nกราฟิค\\nกริด\\nกิกะไบต์\\nกูเกิล\\nกูเกิ้ล\\nเกตเวย์\\nโกลบอล\\nคลัสเตอร์\\nคลาส\\nคลิก\\nคลิปอาร์ต\\nคอนโซล\\nคอนเทนต์\\nคอมพิวติ้ง\\nคอมไพล์\\nคอมไพเลอร์\\nคอมมูนิเคชั่น\\nคอร์\\nคีย์\\nคีย์บอร์ด\\nเครือข่าย\\nเคอร์เซอร์\\nเคอร์เนล\\nแคช\\nแคมฟรอก\\nแคมฟร็อก\\nแคร็ก\\nโค้ด\\nจาวา\\nจีพีเอส\\nชิป\\nชิพ\\nเชลล์\\nแช็ต\\nแชนเนล\\nแชนแนล\\nซ็อกเก็ต\\nซอฟต์แวร์\\nซอฟท์แวร์\\nซอร์ส\\nซัพพอร์ต\\nซัพพอร์ท\\nซีดี\\nซีดีรอม\\nซีเนอร์\\nเซิร์ฟเวอร์\\nโซลูชัน\\nโซลูชั่น\\nไซต์\\nไซเบอร์\\nทรานแซกชัน\\nทรานแซกชั่น\\nทรานแซ็กชัน\\nทรานแซ็กชั่น\\nทรานแซคชัน\\nทรานแซคชั่น\\nทรานแซ็คชัน\\nทรานแซ็คชั่น\\nทวิตเตอร์\\nทวีต\\nทัชแพด\\nเทมเพลต\\nเทอร์มินัล\\nแท็ก\\nแท็บ\\nแทบเล็ต\\nโทรจัน\\nเน็ต\\nเน็ตบุ๊ก\\nเน็ตบุค\\nเน็ตบุ๊ค\\nเน็ตเวิร์ก\\nเน็ตเวิร์ค\\nโน้ตบุ๊ก\\nโน้ตบุค\\nโน้ตบุ๊ค\\nดอส\\nดาวน์เกรด\\nดาวน์โหลด\\nดิจิตอล\\nดิจิทัล\\nดีบั๊ก\\nดีวีดี\\nดีไวซ์\\nเดเบียน\\nเดลไฟ\\nเดสก์ท็อป\\nโดเมน\\nไดรว์\\nไดรเวอร์\\nไดเรกทอรี\\nไดโอด\\nเทเลคอม\\nบล็อกเกอร์\\nบรอดแบนด์\\nบราวเซอร์\\nบลูทูท\\nบลูทูธ\\nบลูเรย์\\nบั๊ก\\nบัฟเฟอร์\\nบิต\\nบิท\\nบูต\\nเบราว์เซอร์\\nแบนด์วิดท์\\nไบต์\\nไบนารี\\nโปรแกรมเมอร์\\nโปรเซส\\nโปรเซสเซอร์\\nโปรโตคอล\\nพร็อกซี\\nพอร์ต\\nพอร์ท\\nพาเนล\\nพาร์ทิชัน\\nพารามิเตอร์\\nพาสเวิร์ด\\nพิกเซล\\nเพจ\\nเพจเจอร์\\nแพกเก็ต\\nแพตช์\\nแพลตฟอร์ม\\nโพรเซส\\nโพรเซสเซอร์\\nโพรโทคอล\\nไพธอน\\nฟล็อปส์\\nฟอนต์\\nฟอร์แมต\\nฟอร์เวิร์ด\\nฟอรัม\\nฟีเจอร์\\nเฟซบุ๊ก\\nเฟิร์มแวร์\\nแฟล็ก\\nโฟลเดอร์\\nไฟร์ฟอกซ์\\nไฟร์วอลล์\\nไฟล์\\nมอดูล\\nมอนิเตอร์\\nมัลติ\\nมัลติทัช\\nมัลติเพล็กซ์\\nมัลแวร์\\nมาสเตอร์\\nมีเดีย\\nเมนู\\nเมมโมรี\\nเมล\\nเมาส์\\nแมค\\nโมดูล\\nโมเด็ม\\nโมบาย\\nโมบายล์\\nโมไบล์\\nไมโครซอฟท์\\nยูนิกซ์\\nยูนิโคด\\nยูนิโค้ด\\nริงโทน\\nรีเฟรช\\nรีเลย์\\nเราเตอร์\\nเรียลไทม์\\nลิงก์\\nลินุกซ์\\nลีนุกซ์\\nลูป\\nเลเยอร์\\nแล็ปท็อป\\nไลเซนส์\\nไลบรารี\\nวิกิ\\nวิกิพีเดีย\\nวินโดวส์\\nวินโดว์ส\\nเว็บ\\nเวอร์ชวล\\nเวอร์ชัน\\nเวอร์ชั่น\\nเวิร์กสเตชัน\\nเวิร์กสเตชั่น\\nเวิร์คสเตชัน\\nเวิร์คสเตชั่น\\nเวิร์ด\\nเวิร์ม\\nไวแมกซ์\\nสกรีน\\nสแกน\\nสแกนเนอร์\\nสแต็ก\\nสนิฟเฟอร์\\nสปายแวร์\\nสเปซ\\nสแปม\\nสมาร์ท\\nสล็อต\\nเสิร์ช\\nโหลด\\nออนไลน์\\nออปติก\\nออปติคอล\\nออปติคัล\\nออฟไลน์\\nออราเคิล\\nอัพเกรด\\nอัพเดต\\nอัพโหลด\\nอัปเกรด\\nอัปเดต\\nอัปโหลด\\nอัลกอริทึม\\nอาร์กิวเมนต์\\nอินเตอร์เน็ต\\nอินทิเกรเตอร์\\nอินเทอร์เน็ต\\nอินเทอร์เฟซ\\nอินเทล\\nอินพุต\\nอินพุท\\nอีเมล\\nอีเมล์\\nอูบุนตู\\nอูบันตู\\nเอนจิน\\nเอ็นจิน\\nเอาต์พุต\\nเอาต์พุท\\nเอาท์พุต\\nเอาท์พุท\\nแอนะล็อก\\nแอนิเมชัน\\nแอนิเมชั่น\\nแอปพลิเคชัน\\nแอปพลิเคชั่น\\nแอพพลิเคชัน\\nแอพพลิเคชั่น\\nแอสเซมบลี\\nแอสเซมเบลอร์\\nโอเพน\\nไอคอน\\nไอซี\\nไอพอด\\nไอพ็อด\\nไอแพด\\nไอโฟน\\nฮับ\\nฮาร์ดดิสก์\\nฮาร์ดแวร์\\nแฮกเกอร์\\nแฮ็กเกอร์\\nแฮนด์เฮลด์\\nโฮสต์\\n\\nกรีก\\nกัณณาฑ\\nกัศมีรี\\nคันจิ\\nคาตาคานะ\\nคุชราตี\\nคุรุมุขี\\nซีริลลิก\\nซูลู\\nเซลติก\\nเซิร์บ\\nตากาล็อก\\nเตลุคู\\nเติร์ก\\nทราวิฑ\\nเบงกาลี\\nปัญจาบี\\nพินอิน\\nมลยาฬัม\\nมองโกล\\nมาราฐี\\nมาเลย์\\nเม็กซิกัน\\nแมนจู\\nแมนดาริน\\nไมถิลี\\nเยอรมัน\\nรัสเซียน\\nสวาฮิลี\\nสวิส\\nสินธี\\nอูรดู\\nอัสสมี\\nอารบิก\\nอิตาเลียน\\nอุยกูร์\\nแอฟริกัน\\nโอริยา\\nไอริช\\nฮันกึล\\nฮินดี\\nฮิรางานะ\\nฮีบรู\\n\\nกรีนพีซ\\nกรือเซะ\\nกวนอิม\\nกวนอู\\nกัดดาฟี\\nกัลยาณวัตร\\nกัสสปะ\\nกาลิเลโอ\\nกินเนส\\nกุมภกรรณ\\nกูเตนเบิร์ก\\nเกตส์\\nเกษมณี\\nโกณฑัญญะ\\nขงเบ้ง\\nคริสโตเฟอร์\\nคองคอร์ด\\nคอลเกต\\nคานธี\\nคาเบรียล\\nคาร์ฟูร์\\nคาร์สัน\\nคาราบาว\\nคาสิโอ\\nคิริน\\nคุนลุ้น\\nคูโบต้า\\nเครมลิน\\nแคทรีนา\\nโคตมะ\\nโคตมี\\nโคลัมบัส\\nไคฟง\\nไครสเลอร์\\nง้อไบ๊\\nจตุพร\\nจ็อบส์\\nจอห์น\\nจิ้น\\nจิม\\nจิ๋ม\\nจิว\\nจุฬาภรณ์\\nจุฬาลงกรณ์\\nเจมส์\\nแจ็กสัน\\nโจเซฟ\\nโจว\\nชมัยมรุเชฐ\\nชมัยมรุเชษฐ์\\nชเวดากอง\\nชาร์ลส์\\nชินราช\\nชินวัตร\\nชุนชิว\\nเช็ง\\nเชตวัน\\nเชฟรอน\\nเชฟโรเลต\\nเชลซี\\nไชยานุชิต\\nซ่ง\\nซังฮี้\\nซัดดัม\\nซันซิล\\nซัมซุง\\nซัวเจ๋ง\\nซินหัว\\nซีซาร์\\nซีแพค\\nซูซาน\\nซูซูกิ\\nซูบารุ\\nเซ็นทารา\\nเซเวน\\nเซเว่น\\nโซฟิเทล\\nโซยุซ\\nโซยูซ\\nณัฐวุฒิ\\nดาร์ลี่\\nดาวโจนส์\\nดิสนีย์\\nดีแทค\\nดูปองท์\\nเดโมแครต\\nเดลล์\\nเดลินิวส์\\nเดวิด\\nแดวู\\nโดนัลด์\\nโดราเอมอน\\nโดเรมอน\\nต๋อง\\nตั๊กม้อ\\nตากสิน\\nตาเมือน\\nตาลีบัน\\nตูน\\nเตมีย์\\nโต๋\\nโตชิบา\\nโตโยต้า\\nถังซัมจั๋ง\\nถังซำจั๋ง\\nทรพา\\nทราเวล\\nทรูมูฟ\\nทีปังกร\\nเทปโก\\nเทพรัตน\\nเทวทัต\\nเทสโก้\\nโทมัส\\nไททานิก\\nไททานิค\\nไทยรัฐ\\nธีออส\\nนครินทรา\\nนโปเลียน\\nนพดล\\nนราดูร\\nนเรนทร\\nนอสตราดามุส\\nนาซา\\nนาซ่า\\nนาซี\\nนาโต\\nนาโต้\\nนาลแก\\nนิคอน\\nนิโคลัส\\nนิด้า\\nนินเทนโด\\nนิปปอน\\nนิวตัน\\nนิสสัน\\nเนคเทค\\nเนชั่น\\nเนชันแนล\\nเนชั่นแนล\\nเนวิน\\nเนสเล่\\nเนสาด\\nแนท\\nแนสแดค\\nโนเกีย\\nโนเบล\\nโนเวลล์\\nโนโวเทล\\nไนเม็กซ์\\nบรอดเวย์\\nบรัดเลย์\\nบรู๊ซ\\nบัลเมอร์\\nบารัก\\nบารัค\\nบู๊ตึ๊ง\\nเบญกาย\\nเบนซ์\\nเบ็นซ์\\nเบนจามิน\\nโบตัน\\nไบโอเทค\\nประชาธิปัตย์\\nปวีณา\\nปอเต็กตึ๊ง\\nปอเต๊กตึ๊ง\\nป่อเต็กตึ๊ง\\nปัตตะโชติ\\nปารุสก์\\nปีเตอร์\\nปูติน\\nเป๊ปซี่\\nเป้ย\\nเปอร์โยต์\\nเปาบุ้นจิ้น\\nโปเกมอน\\nโป๊ยก่าย\\nพรหมทัต\\nพลาโต\\nพอลล่า\\nพานาโซนิค\\nพานาโซนิก\\nพิทยานุกูล\\nพิมพิสาร\\nเพนแทกซ์\\nเพลโต\\nไพโอเนียร์\\nฟรอยด์\\nฟรังซิส\\nฟรานซิส\\nฟลอเรนซ์\\nฟอร์ด\\nฟิลิปส์\\nฟูจิ\\nแฟซ่า\\nโฟร์โมสต์\\nภูมิพล\\nภูริทัต\\nมงฟอร์ต\\nมณโฑ\\nมติชน\\nมหิตลาธิเบศร\\nมโหสถ\\nมัจฉานุ\\nมาร์กาเร็ต\\nมาร์ติน\\nมาสด้า\\nมิตซูบิชิ\\nมิราเคิล\\nมุสโสลินี\\nเม้ง\\nเมจิ\\nเมอร์ซีเดส\\nเมอร์เซเดส\\nแมกซ์เวลล์\\nแมกไซไซ\\nแมคอินทอช\\nแมชีนเนอรี่\\nโมคคัลลานะ\\nโมโตโรลา\\nโมโตโรล่า\\nโมเนีย\\nไมเคิล\\nไมยราพณ์\\nยโสธรา\\nยะโฮวา\\nยะโฮวาห์\\nยามาฮ่า\\nยาเวห์\\nยาฮู\\nยูนิเซฟ\\nยูเนสโก\\nยูไล\\nเยโฮวาห์\\nรอยเตอร์\\nรอยัล\\nรัชดา\\nรัสปูติน\\nราฟาเอล\\nรามาวตาร\\nราเมศวร\\nราหุล\\nริชาร์ด\\nรีพับลิกัน\\nรูนีย์\\nเรนโบว์\\nแรมโบ้\\nโรตารี\\nโรนัลโด\\nโรนัลโด้\\nโรบินสัน\\nโรเบิร์ต\\nล็อกซเล่ย์\\nลิงคอล์น\\nลิจฉวี\\nลิไท\\nลิไทย\\nลินคอล์น\\nลิเวอร์พูล\\nเลโนโว\\nเลียดก๊ก\\nโลตัส\\nวชิราลงกรณ์\\nวลาดิเมียร์\\nวอลล์สตรีท\\nวาเลนไทน์\\nวิกตอเรีย\\nวิทยานุสรณ์\\nวิทยายน\\nวิมเบิลดัน\\nวิลเลียม\\nวีระ\\nวุฒิชัย\\nเวียดกง\\nไวตามิลค์\\nศกุนตลา\\nศรีวิชัย\\nศิริพงษ์\\nศิริราช\\nศุภชลาศัย\\nสดกก๊อกธม\\nสดายุ\\nสตาลิน\\nสตีฟ\\nสแตนฟอร์ด\\nสวรินทิรา\\nสังกัจจายน์\\nสาทิตย์\\nสารีบุตร\\nสิริกิติ์\\nสิรินธร\\nสิหิงค์\\nสีวลี\\nสีหนุ\\nสีหมุนี\\nสีหโมนี\\nสุครีพ\\nสุทโธทนะ\\nสุเทพ\\nสุนทราภรณ์\\nสุนีย์\\nสุรนารี\\nสุรยุทธ์\\nสุริยาสน์\\nเส้าหลิน\\nโสกราตีส\\nโสภิต\\nหนุมาน\\nหลินฮุ่ย\\nหลุยส์\\nเห้งเจีย\\nไหหม่า\\nองคต\\nองคุลิมาล\\nอชาตศัตรู\\nอดุลยเดช\\nอพอลโล\\nอริสโตเติล\\nอริสมันต์\\nอลิซาเบธ\\nอ๋อม\\nออร์คิด\\nออสการ์\\nอะพอลโล\\nอับราฮัม\\nอั้ม\\nอัลกออิดะห์\\nอัลคาเทล\\nอัลจาซีราห์\\nอัลเฟรด\\nอัลเลาะห์\\nอัสซุส\\nอัสสชิ\\nอัสสัมชัญ\\nอาเซม\\nอาเซ็ม\\nอาเซียน\\nอาฟต้า\\nอาร์เซนอล\\nอินทรชิต\\nอินทราทิตย์\\nอีซูซุ\\nอีเลฟเวน\\nอีเลฟเว่น\\nอุณรุท\\nอุบลรัตน์\\nอุบาลี\\nอุ๋ย\\nเอกทัศน์\\nเอเซอร์\\nเอ็ดเวิร์ด\\nเอดิสัน\\nเอแบค\\nเอลิซาเบธ\\nเอสพลานาด\\nเอสพลานาร์ด\\nแอคคอร์\\nแอคคอร์ด\\nแองเจลิน่า\\nแอตแลนติส\\nแอน\\nแอ๋ม\\nแอมบาสซาเดอร์\\nแอมบาสเดอร์\\nแอมเวย์\\nแอ๋ว\\nโอดีสซีย์\\nโอเดียน\\nโอบามา\\nโอรสาราม\\nโอลิมเปีย\\nโออิชิ\\nไอน์สไตน์\\nฮอนด้า\\nฮอปกินส์\\nฮอลลีวูด\\nฮอลลีวู้ด\\nฮานามิ\\nฮามาส\\nฮิตเลอร์\\nฮิตาชิ\\nฮุนเซน\\nฮุนเซ็น\\nฮุนได\\nฮุสเซ็น\\nเฮนรี\\nเฮนรี่\\nเฮเลน\\nโฮจิมินห์\\nโฮปเวลล์\\nโฮเมอร์\\n\\nกลีเซอรีน\\nกำทอน\\nแกนีมีด\\nครอส\\nคริสตัล\\nคลอโรพลาสต์\\nคลอไรด์\\nควอนตัม\\nคอนดักเตอร์\\nคอปเปอร์\\nคอลลาเจน\\nคอเลสเตอรอล\\nคอสมิก\\nคูลอมบ์\\nเคอราติน\\nแคโรทีน\\nแคสสินี\\nโครมาโทกราฟี\\nไคโตซาน\\nจีโนม\\nจุลชีววิทยา\\nชิคุนกุนยา\\nซัลฟิวริก\\nซัลเฟต\\nซัลไฟด์\\nซิงค์\\nซิริอุส\\nซิลิกา\\nซิลิเกต\\nซิลิโคน\\nซีเทน\\nซีเวิร์ต\\nเซ็กเตอร์\\nเซ็กเมนต์\\nเซมิ\\nโซนาร์\\nไซบอร์ก\\nดอปเปลอร์\\nดอปเพลอร์\\nไดนามิก\\nไดนามิกส์\\nไดนามิค\\nไดนามิคส์\\nไดออกไซด์\\nทรานส์\\nทามิฟลู\\nเทฟลอน\\nเทสโทสเตอโรน\\nเทอร์โม\\nแทนนิน\\nไททัน\\nไทฟอยด์\\nไทรอยด์\\nธาลัสซีเมีย\\nเนกาตีฟ\\nโนวา\\nบอแรกซ์\\nโบทอกซ์\\nโบท็อกซ์\\nไบโอติน\\nปฏิยานุพันธ์\\nโปรเจสเตอโรน\\nพอลิเมอร์\\nพันธุศาสตร์\\nพัลซาร์\\nพาร์กินสัน\\nพาราเซตามอล\\nพาราโบลา\\nเพอร์ออกไซด์\\nโพรเจสเทอโรน\\nโพลาไรซ์\\nโพลิเมอร์\\nโพลีเอทิลีน\\nไพรเมต\\nฟลาโวนอยด์\\nฟลูออเรสเซนซ์\\nฟลูออไรด์\\nฟอสซิล\\nฟิชชัน\\nฟิวชัน\\nฟีโรโมน\\nไฟเบอร์\\nมอนอกไซด์\\nมิราจ\\nเมตริกซ์\\nเมทริกซ์\\nเมลานิน\\nเมลามีน\\nโมเมนตัม\\nไมโตคอนเดรีย\\nไมโทคอนเดรีย\\nยีสต์\\nยูริก\\nยูเรีย\\nรูมาตอยด์\\nวีก้า\\nเวกเตอร์\\nเวก้า\\nเวสิเคิล\\nโวลต์\\nสเกล\\nสเกลาร์\\nสเต็ม\\nสเตียรอยด์\\nสปีชีส์\\nสเปิร์ม\\nสัมพัทธภาพ\\nสุริยจักรวาล\\nออกเทน\\nออโรรา\\nออโรร่า\\nอะคริลิก\\nอะครีลิก\\nอะซีติก\\nอะซีโตน\\nอะมิโน\\nอะลูมินา\\nอันโดรเมดา\\nอัลคาไลน์\\nอัลตราซาวด์\\nอัลตราซาวนด์\\nอัลลอยด์\\nอินทิกรัล\\nอินทิเกรต\\nอีโบลา\\nอีโบล่า\\nเอ็กซ์โพเนนเชียล\\nเอทานอล\\nเอทิลีน\\nเอนโทรปี\\nเอสเตอร์\\nเอสโตรเจน\\nเอสโทรเจน\\nแอนดรอยด์\\nแอนแทร็กซ์\\nแอมพลิจูด\\nแอมโมเนียม\\nแอลกอฮอลิซึม\\nแอสพาร์แตม\\nโอเซลทามิเวียร์\\nฮับเบิล\\nฮิวมัส\\nไฮดรอกไซด์\\nไฮดรอลิก\\nไฮโดรลิก\\nไฮเพอร์โบลา\\n\\nกงเต็ก\\nกฎุมพี\\nกฏ\\nกฏหมาย\\nกบฎ\\nกราไฟต์\\nก๊อปปี้\\nกะทะ\\nกังวาล\\nกุฎฐัง\\nกุฏุมพี\\nฃวด\\nคฑา\\nคลินิค\\nคลีนิก\\nคลีนิค\\nคาทอลิค\\nคึ่นฉ่าย\\nแคตตาล็อก\\nโควต้า\\nฅน\\nจุมพฎ\\nช็อคโกแลต\\nแซ่ด\\nดัทช์\\nทนง\\nทรมาณ\\nทราก\\nทะแยง\\nทิฏฐิ\\nบล็อค\\nบ๊องแบ๊ว\\nบัลเล่ต์\\nเบรค\\nแบงค์\\nปรากฎ\\nปัคคหะ\\nปาฏิโมกข์\\nปิติ\\nปิรามิด\\nโปรเตสแตนท์\\nพนิช\\nพยักเพยิด\\nพริ้ว\\nพลูโตเนียม\\nพากษ์\\nเฟิร์น\\nยากี้\\nเยภุยยสิกา\\nรุสเซีย\\nฤาษี\\nล็อค\\nล็อคเกอร์\\nวันทยาหัตถ์\\nวานิช\\nวิญญาน\\nวิศิษฐ์\\nศรีษะ\\nสเปกโทรสโคป\\nสฤษฎ์\\nสลิ่ม\\nสัตตสดก\\nสาราณียากร\\nสุกี้\\nสุกี้ยากี้\\nสูญญากาศ\\nหยอมแหยม\\nหยอย\\nหล่ะ\\nอะดรีนาลีน\\nอะหลั่ย\\nอัตคัต\\nอัฟริกา\\nอานิสงค์\\nอาฟริกา\\nอิริยาบท\\nอิเลคโทรนิคส์\\nอีรุงตุงนัง\\nอุตรายัน\\nอุลตรา\\nอุลตร้า\\nโอกาศ\\n\\nกกหู\\nกงการ\\nกงจักร\\nกฎเกณฑ์\\nกฎบัตร\\nกฎหมาย\\nกฎหมู่\\nกดขี่\\nกดดัน\\nก้นกบ\\nก้นบึ้ง\\nก้นปล่อง\\nกนิษฐภคินี\\nกนิษฐภาดา\\nกรงเล็บ\\nกรมการ\\nกรมท่า\\nกรมธรรม์\\nกรมนา\\nกรมวัง\\nกรรมกร\\nกรรมการ\\nกรรมฐาน\\nกรรมบถ\\nกรรมพันธุ์\\nกรรมวิธี\\nกรรมสิทธิ์\\nกระจกเงา\\nกระจกตา\\nกระจกนูน\\nกระจกเว้า\\nกระจอกชวา\\nกระจอกเทศ\\nกระจ้อยร่อย\\nกระจับบก\\nกระจับปิ้ง\\nกระจับปี่\\nกระโชกโฮกฮาก\\nกระดานดำ\\nกระดานหก\\nกระดาษแก้ว\\nกระดาษไข\\nกระดาษทราย\\nกระดาษสา\\nกระดูกงู\\nกระทาชาย\\nกระเท่เร่\\nกระบวนการ\\nกระบองเพชร\\nกระผีกริ้น\\nกระยาทิพย์\\nกระยาสารท\\nกระยาหาร\\nกระสอบทราย\\nกระสุนปืน\\nกระแสจิต\\nกระแสน้ำ\\nกระแสลม\\nกรับคู่\\nกรับพวง\\nกรับเสภา\\nกราดเกรี้ยว\\nกราวรูด\\nกริ่งเกรง\\nกรีฑาสถาน\\nกรีดกราย\\nกรี๊ดกร๊าด\\nกลไก\\nกลบท\\nกลเม็ด\\nกลยุทธ์\\nกลวิธี\\nกลศาสตร์\\nกลอักษร\\nกลบเกลื่อน\\nกลมกล่อม\\nกลมกลืน\\nกลมเกลียว\\nกล้วยแขก\\nกล้วยไม้\\nกล่องเสียง\\nกล่อมเกลา\\nกล่อมเกลี้ยง\\nกลัดกลุ้ม\\nกลัดมัน\\nกลั่นกรอง\\nกลั่นแกล้ง\\nกลับกลอก\\nกลางคน\\nกลางคัน\\nกลางค่ำ\\nกลางคืน\\nกลางแจ้ง\\nกลางแปลง\\nกลางวัน\\nกลาดเกลื่อน\\nกล่าวขวัญ\\nกล่าวโทษ\\nกล่าวหา\\nกล้ำกราย\\nกล้ำกลืน\\nกลิ้งกลอก\\nกลิ้งเกลือก\\nกลิ่นอาย\\nกลียุค\\nกวดขัน\\nกวัดแกว่ง\\nกวัดไกว\\nกวีนิพนธ์\\nก่อกวน\\nก่อการ\\nก่อตั้ง\\nก่อสร้าง\\nก่อหวอด\\nก้อร่อก้อติก\\nกองกลาง\\nกองเกิน\\nกองโจร\\nกองทัพ\\nกองทุน\\nกองพล\\nกองพัน\\nกองฟอน\\nกองร้อย\\nกองหนุน\\nกอบโกย\\nกะเกณฑ์\\nกะบังลม\\nกักกัน\\nกักขัง\\nกักตัว\\nกักตุน\\nกัณฑ์เทศน์\\nกัดฟัน\\nกันชน\\nกันท่า\\nกันสาด\\nกันเอง\\nกับแกล้ม\\nกับข้าว\\nกับระเบิด\\nกากเพชร\\nกากหมู\\nกาชาด\\nกาญจนาภิเษก\\nก้านคอ\\nกาฝาก\\nก้ามกราม\\nกามกิจ\\nกามคุณ\\nกามเทพ\\nกามโรค\\nก้ามปู\\nกายกรรม\\nกายบริหาร\\nกายภาพ\\nกายวิภาค\\nกายสิทธิ์\\nก่ายกอง\\nการคลัง\\nการเงิน\\nการบ้าน\\nการเปรียญ\\nการเมือง\\nการเรือน\\nการละเล่น\\nกาลกิริยา\\nกาลเทศะ\\nก้าวก่าย\\nก้าวร้าว\\nก้าวหน้า\\nกาสาวพัสตร์\\nกาฬพฤกษ์\\nกาฬโรค\\nกำปั้น\\nกำมือ\\nกำแพงขาว\\nกำลังใจ\\nกำลังม้า\\nกี่งอำเภอ\\nกิจกรรม\\nกิจการ\\nกิจวัตร\\nกิจจะลักษณะ\\nกิตติคุณ\\nกิตติศัพท์\\nกินขาด\\nกินใจ\\nกินดอง\\nกินโต๊ะ\\nกินแบ่ง\\nกินเปล่า\\nกินเลี้ยง\\nกินเส้น\\nกินแหนง\\nกิโลกรัม\\nกิโลเมตร\\nกิโลลิตร\\nกิโลเฮิรตซ์\\nกีดกัน\\nกีดกั้น\\nกีดขวาง\\nกึกก้อง\\nกึกกัก\\nกึกกือ\\nกึ่งกลาง\\nกุกกัก\\nกุ๊กกิ๊ก\\nกุ้งฝอย\\nกุ้งมังกร\\nกุ้งแห้ง\\nกุ้งเต้น\\nกุ้งยิง\\nกุญแจผี\\nกุญแจมือ\\nกุญแจเลื่อน\\nกุญแจเสียง\\nกุลธิดา\\nกุลบุตร\\nกุลสตรี\\nกู้ยืม\\nเก้งก้าง\\nเก็บกวาด\\nเก็บเกี่ยว\\nเก็บงำ\\nเก็บตก\\nเกรงกลัว\\nเกรงใจ\\nเกรงขาม\\nเกรียงไกร\\nเกรียมกรม\\nเกรี้ยวกราด\\nเกล็ดเลือด\\nเกลี้ยกล่อม\\nเกลี้ยงเกลา\\nเกลือกกลั้ว\\nเกลือกกลิ้ง\\nเกลื่อนกล่น\\nเกลื่อนกลาด\\nเกศธาตุ\\nเกษตรกร\\nเกษตรกรรม\\nเกษตรศาสตร์\\nเกษมสันต์\\nเกษียรสมุทร\\nเก้อเขิน\\nเกาะแกะ\\nเกี่ยงงอน\\nเกียจคร้าน\\nเกียรติคุณ\\nเกียรตินิยม\\nเกียรติประวัติ\\nเกียรติภูมิ\\nเกียรติยศ\\nเกียรติศักดิ์\\nเกียรติมุข\\nเกี่ยวข้อง\\nเกี่ยวดอง\\nเกี่ยวพัน\\nเกี่ยวโยง\\nเกี้ยวพาน\\nเกี้ยวพาราสี\\nแก่แดด\\nแก้ขัด\\nแก้ไข\\nแก้ตัว\\nแก้เผ็ด\\nแก้ลำ\\nแกงคั่ว\\nแกงจืด\\nแกงบวด\\nแกงป่า\\nแกงเผ็ด\\nแกงส้ม\\nแก่งแย่ง\\nแก่นแก้ว\\nแก่นสาร\\nแก้วตา\\nแก้วหู\\nแกว่งกวัด\\nแกว่งไกว\\nแกะรอย\\nโก้เก๋\\nโกรธเกรี้ยว\\nโกรธขึ้ง\\nไก่เขี่ย\\nไก่ชน\\nไก่บ้าน\\nไก่ป่า\\nไก่ฟ้า\\nไกล่เกลี่ย\\nขจัดขจาย\\nขนเพชร\\nขนสัตว์\\nขนหนู\\nขนส่ง\\nขนมจีน\\nขบขัน\\nขบวนการ\\nข่มขี่\\nข่มขู่\\nข่มขืน\\nข่มเหง\\nขมหิน\\nขมิ้นชัน\\nขมุบขมิบ\\nขยะแขยง\\nขยักขย่อน\\nขยักขย้อน\\nขยับขยาย\\nขยับเขยื้อน\\nขวดโหล\\nขวยเขิน\\nขวัญใจ\\nขวัญตา\\nขวัญอ่อน\\nขวากหนาม\\nขวางโลก\\nของ้าว\\nขอสับ\\nขอขมา\\nขอทาน\\nขอโทษ\\nขอร้อง\\nขออภัย\\nข้อเขียน\\nข้อความ\\nข้อเท็จจริง\\nของกลาง\\nของขวัญ\\nของแข็ง\\nของชำ\\nของลับ\\nของเล่น\\nของว่าง\\nของเหลว\\nของไหล\\nของไหว้\\nข้องใจ\\nข้องแวะ\\nขอบข่าย\\nขอบเขต\\nขอบคุณ\\nขอบใจ\\nขอบพระคุณ\\nข้อมูล\\nข้อแม้\\nข้อหา\\nข้อสังเกต\\nขัดข้อง\\nขัดขืน\\nขัดเขิน\\nขัดจังหวะ\\nขัดดอก\\nขัดแตะ\\nขัดยอก\\nขัดแย้ง\\nขัดสมาธิ\\nขันหมาก\\nขันอาสา\\nขับขี่\\nขับเคี่ยว\\nขั้วโลก\\nขาจร\\nขาประจำ\\nข้าราชการ\\nข้าศึก\\nข้าหลวง\\nขาดแคลน\\nขาดใจ\\nขาดตอน\\nขาดตัว\\nขาดทุน\\nขาดเหลือ\\nขายหน้า\\nข่าวกรอง\\nข่าวคราว\\nข่าวล่า\\nข่าวลือ\\nข่าวสาร\\nข้าวเกรียบ\\nข้าวแกง\\nข้าวของ\\nข้าวจี่\\nข้าวเจ้า\\nข้าวซอย\\nข้าวต้ม\\nข้าวตอก\\nข้าวตัง\\nข้าวแตน\\nข้าวทิพย์\\nข้าวบิณฑ์\\nข้าวเปลือก\\nข้าวโพด\\nข้าวฟ่าง\\nข้าวเม่า\\nข้าวสวย\\nข้าวสาร\\nข้าวเหนียว\\nข้าวหมาก\\nข้าวหลาม\\nขี้เกียจ\\nขี้ข้า\\nขี้ครอก\\nขี้คร้าน\\nขี้คุก\\nขี้ไคล\\nขี้เซา\\nขีดขั้น\\nขีดคร่อม\\nขีดคั่น\\nขีดฆ่า\\nขี้ตา\\nขี้ตืด\\nขี้เถ้า\\nขี้ทูด\\nขี้ปะติ๋ว\\nขี้ผึ้ง\\nขี้มูก\\nขี้ยา\\nขี้แย\\nขี้ริ้ว\\nขี้เรื้อน\\nขี้เล็บ\\nขี้หู\\nขี้หน้า\\nขี้เหนียว\\nขี้เหล็ก\\nขี้เหร่\\nขึงขัง\\nขึงพืด\\nขึ้งโกรธ\\nขึ้นใจ\\nขึ้นชื่อ\\nขึ้นมือ\\nขืนใจ\\nขื่นขม\\nขุดคุ้ย\\nขุนทอง\\nขุนนาง\\nขุนพล\\nขุนศึก\\nขุนหลวง\\nขูดรีด\\nเข็มกลัด\\nเข็มขัด\\nเข้มข้น\\nเข้มแข็ง\\nเข้มงวด\\nเข็มทิศ\\nเข็มหมุด\\nเข้าขา\\nเข้าเค้า\\nเข้าใจ\\nเข้าชื่อ\\nเข้าตัว\\nเข้าถึง\\nเข้าทรง\\nเข้าท่า\\nเข้าที\\nเข้าเนื้อ\\nเข้าเล่ม\\nเขียวเสวย\\nเขียวหวาน\\nแขกเต้า\\nแข็งกร้าว\\nแข็งกล้า\\nแข็งแกร่ง\\nแข็งข้อ\\nแข็งขัน\\nแข่งขัน\\nแข็งใจ\\nแข็งตัว\\nแข็งเมือง\\nแข็งแรง\\nแขวนลอย\\nโขกสับ\\nโขยกเขยก\\nไขข้อ\\nไขควง\\nไขมัน\\nไข่มุก\\nไขว่ห้าง\\nไขสันหลัง\\nไขสือ\\nไข่เค็ม\\nไข่เยี่ยวม้า\\nไข่หงส์\\nไข่เหี้ย\\nคงกระพัน\\nคงตัว\\nคงทน\\nคงที่\\nคชลักษณ์\\nคชสาร\\nคชสีห์\\nคชราช\\nคณิตศาสตร์\\nคดเคี้ยว\\nคติธรรม\\nคติพจน์\\nคนกลาง\\nคนไข้\\nคนใช้\\nคนทรง\\nคบไฟ\\nคบเพลิง\\nคบค้า\\nคบคิด\\nคบหา\\nคมคาย\\nครบครัน\\nครบถ้วน\\nครอบครอง\\nครอบคลุม\\nครอบครัว\\nครอบงำ\\nครอบจักรวาล\\nคริสตกาล\\nคริสตจักร\\nคริสต์มาส\\nคริสต์ศตวรรษ\\nคริสต์ศักราช\\nคริสตัง\\nคริสเตียน\\nครุกรรม\\nครุภัณฑ์\\nครุศาสตร์\\nครุฑพ่าห์\\nครุ่นคิด\\nคลอเคลีย\\nคล่องแคล่ว\\nคล่องตัว\\nคล่องมือ\\nคลั่งไคล้\\nคลาคล่ำ\\nคลาไคล\\nคลาดเคลื่อน\\nคลาดแคล้ว\\nคลี่คลาย\\nคลึงเคล้น\\nคลึงเคล้า\\nคลื่นไส้\\nคลื่นเหียน\\nคลุกคลี\\nคลุกคลาน\\nคลุมเครือ\\nคลุมโปง\\nคลุ้มคลั่ง\\nควงสว่าน\\nควบคุม\\nควบคู่\\nควบแน่น\\nควันหลง\\nความคิด\\nความหลัง\\nความเห็น\\nคอหอย\\nคอห่าน\\nคอแห้ง\\nค่อนขอด\\nค่อนแคะ\\nค้อนควัก\\nคั่งค้าง\\nคั่งแค้น\\nคัดค้าน\\nคัดง้าง\\nคัดท้าย\\nคัดเลือก\\nคันจาม\\nคันฉ่อง\\nคันฉาย\\nคันชัก\\nคันชั่ง\\nคันไถ\\nคันนา\\nคันเร่ง\\nคับขัน\\nคับคั่ง\\nคับแค้น\\nคับแคบ\\nคางทูม\\nคางหมู\\nค้างคืน\\nค้างปี\\nคาดคั้น\\nคาดเชือก\\nคาดโทษ\\nคาดหมาย\\nคานหาม\\nคาบเกี่ยว\\nคาบศิลา\\nคาบสมุทร\\nคำขาด\\nคำนำ\\nคิดค้น\\nคืนดี\\nคืนตัว\\nคุกเข่า\\nคุณค่า\\nคุณชาย\\nคุณธรรม\\nคุณนาย\\nคุณภาพ\\nคุณลักษณะ\\nคุณวุฒิ\\nคุณศัพท์\\nคุณสมบัติ\\nคุณหญิง\\nคุณากร\\nคุณูปการ\\nคุโณปการ\\nคุมเชิง\\nคุ้มกัน\\nคุยเขื่อง\\nคุยโต\\nคุ้ยเขี่ย\\nคุ้มครอง\\nคู่กรณี\\nคู่กัด\\nคู่ขา\\nคู่แข่ง\\nคู่ครอง\\nคู่ควร\\nคู่คิด\\nคู่คี่\\nคู่ใจ\\nคู่ชีพ\\nคู่ชีวิต\\nคู่บารมี\\nคู่บุญ\\nคู่ปรปักษ์\\nคู่ปรับ\\nคู่ผสม\\nคู่มือ\\nคู่รัก\\nคู่ลำดับ\\nคู่สาย\\nคู่หมั้น\\nคู่หู\\nคู่อริ\\nคู่อาฆาต\\nเคมีภัณฑ์\\nเคยตัว\\nเคร่งขรึม\\nเคร่งครัด\\nเคร่งเครียด\\nเครดิตฟองซิเอร์\\nเครื่องกล\\nเครื่องกัณฑ์\\nเครื่องแกง\\nเครื่องเขิน\\nเครื่องครัว\\nเครื่องเคียง\\nเครื่องเงิน\\nเครื่องจักร\\nเครื่องเซ่น\\nเครื่องดนตรี\\nเครื่องต้น\\nเครื่องทุ่นแรง\\nเครื่องเทศ\\nเครื่องใน\\nเครื่องบิน\\nเครื่องบูชา\\nเครื่องแบบ\\nเครื่องประดับ\\nเครื่องปรุง\\nเครื่องปรุงรส\\nเครื่องมือ\\nเครื่องยนต์\\nเครื่องร่อน\\nเครื่องราง\\nเครื่องเรือน\\nเครื่องล่าง\\nเครื่องเล่น\\nเครื่องสาย\\nเครื่องสำอาง\\nเครื่องสุกำศพ\\nเครื่องหมาย\\nเครือรัฐ\\nเคลียคลอ\\nเคลื่อนที่\\nเคลื่อนไหว\\nเคลือบแคลง\\nเคลือบแฝง\\nเคลือบฟัน\\nเคว้งคว้าง\\nเคหสถาน\\nเค้าโครง\\nเคียดแค้น\\nเคี่ยวเข็ญ\\nเคี้ยวเอื้อง\\nเคืองขุ่น\\nโคนม\\nโคบาล\\nโคมูตร\\nโคมลอย\\nโครงการ\\nโครงเรื่อง\\nโครงงาน\\nโครงสร้าง\\nโครมคราม\\nโคลงเคลง\\nฆ้องกระแต\\nฆ้องชัย\\nฆ้องวง\\nฆ้องหุ่ย\\nฆ้องเหม่ง\\nฆ้องโหม่ง\\nฆาตกร\\nฆาตกรรม\\nฆานประสาท\\nงงงวย\\nงงงัน\\nงดเว้น\\nงบดุล\\nงบประมาณ\\nงมโข่ง\\nงมงาย\\nง่วงงุน\\nง่วงเหงา\\nงอหาย\\nง้องอน\\nงอนง้อ\\nงอมแงม\\nงาช้าง\\nง่าเงย\\nงานการ\\nง่ายดาย\\nงึมงำ\\nเงินเดือน\\nเงินตรา\\nเงินยวง\\nเงียบกริบ\\nเงียบเชียบ\\nเงียบเหงา\\nเงื่องหงอย\\nเงื่อนไข\\nเงื่อนงำ\\nเงื่อนเวลา\\nเงื้อมมือ\\nแง่งอน\\nจงใจ\\nจงรัก\\nจดจ่อ\\nจดจำ\\nจดหมาย\\nจดหมายเหตุ\\nจรจัด\\nจรรยาบรรณ\\nจริงจัง\\nจริงใจ\\nจอมขวัญ\\nจอมใจ\\nจอมทัพ\\nจอมปลวก\\nจอมพล\\nจ๊ะเอ๋\\nจักสาน\\nจักรพรรดิ\\nจักรภพ\\nจักรยาน\\nจักรยานยนต์\\nจักรราศี\\nจักรวรรดิ\\nจักรวรรดินิยม\\nจักรวาล\\nจังหนับ\\nจัดการ\\nจัดจ้าน\\nจัดเจน\\nจัดแจง\\nจัดตั้ง\\nจัดสรร\\nจับกุม\\nจับจด\\nจับเจ่า\\nจ่าหน้า\\nจาตุทสี\\nจาตุมหาราช\\nจาตุมหาราชิก\\nจาตุมหาราชิกา\\nจาตุรงคสันนิบาต\\nจาตุรราชการ\\nจานเชิง\\nจานบิน\\nจานผี\\nจานเสียง\\nจาบจ้วง\\nจำเป็น\\nจำพรรษา\\nจำวัด\\nจ้ำจี้จ้ำไช\\nจำเลาะตา\\nจิงโจ้น้ำ\\nจิตใจ\\nจิตตภาวนา\\nจิตตัง\\nจิตตานุปัสสนา\\nจิตนิยม\\nจิตบำบัด\\nจิตแพทย์\\nจิตวิสัย\\nจิตรกร\\nจิตรกรรม\\nจิตรลดา\\nจิตวิทยา\\nจิตเวช\\nจิตเวชศาสตร์\\nจินตกวี\\nจินตนา\\nจินตนาการ\\nจินตภาพ\\nจุฑามณี\\nจุฑามาศ\\nจุฑารัตน์\\nจุนเจือ\\nจุ้นจ้าน\\nจุลชีพ\\nจุลชีวัน\\nจุลชีวิน\\nจุลทรรศน์\\nจุลภาค\\nจุลวรรค\\nจุลศักราช\\nจุลสาร\\nจุลินทรีย์\\nจุฬามณี\\nจุฬาลักษณ์\\nเจตคติ\\nเจตจำนง\\nเจตนารมณ์\\nเจตภูต\\nเจริญพร\\nเจ้ากรม\\nเจ้ากรรม\\nเจ้าของ\\nเจ้าขา\\nเจ้าข้า\\nเจ้าคณะ\\nเจ้าค่ะ\\nเจ้าจอม\\nเจ้าชู้\\nเจ้าตัว\\nเจ้าถิ่น\\nเจ้าท่า\\nเจ้าที่\\nเจ้าทุกข์\\nเจ้านาย\\nเจ้าเนื้อ\\nเจ้าบ้าน\\nเจ้าบ่าว\\nเจ้าประคุณ\\nเจ้าประคู้น\\nเจ้าพนักงาน\\nเจ้าพระคุณ\\nเจ้าพระยา\\nเจ้าพ่อ\\nเจ้าพายุ\\nเจ้าฟ้า\\nเจ้าภาพ\\nเจ้ามือ\\nเจ้าแม่\\nเจ้าเรือน\\nเจ้าสังกัด\\nเจ้าสัว\\nเจ้าสาว\\nเจ้าหน้าที่\\nเจ้าหนี้\\nเจ้าอาวาส\\nเจาะจง\\nเจือจาง\\nเจือจาน\\nเจือปน\\nเจื้อยแจ้ว\\nแจกจ่าย\\nแจ่มแจ้ง\\nแจ่มใส\\nโจงกระเบน\\nโจมตี\\nโจรกรรม\\nโจรสลัด\\nใจความ\\nใจคอ\\nฉกฉวย\\nฉกชิง\\nฉลองได\\nฉ้อฉล\\nฉัตรมงคล\\nฉันทลักษณ์\\nฉายาลักษณ์\\nฉิบหาย\\nฉุกเฉิน\\nฉุกละหุก\\nฉุนเฉียว\\nฉุปศาสตร์\\nเฉไฉ\\nเฉยเมย\\nเฉาโฉด\\nเฉิดฉัน\\nเฉิดฉาย\\nเฉิดฉิน\\nเฉียบขาด\\nเฉียบพลัน\\nเฉียบแหลม\\nเฉื่อยชา\\nแฉะแบะ\\nโฉดเฉา\\nโฉมงาม\\nโฉมฉาย\\nโฉมเฉลา\\nโฉมตรู\\nโฉมยง\\nโฉมศรี\\nโฉมหน้า\\nชดช้อย\\nชดเชย\\nชดใช้\\nชนบท\\nชนินทร์\\nชนกกรรม\\nชนมพรรษา\\nชนมายุ\\nชมเชย\\nชมพูทวีป\\nชมพูนท\\nชมพูนุท\\nชราธรรม\\nชราภาพ\\nชลจร\\nชลธาร\\nชลธี\\nชลนัยน์\\nชลนา\\nชลเนตร\\nชลประทาน\\nชลมารค\\nชลาธาร\\nชลาลัย\\nชลาศัย\\nชลาสินธุ์\\nชโลทร\\nช่วงชิง\\nช่วงใช้\\nชวนชม\\nชวนหัว\\nช่วยเหลือ\\nช่อฟ้า\\nช่อม่วง\\nชอกช้ำ\\nช่องเขา\\nช่องแคบ\\nช่องไฟ\\nช่องว่าง\\nช้องนาง\\nชอบกล\\nชอบใจ\\nชอบธรรม\\nชอบพอ\\nชักโครก\\nชักเงา\\nชักจูง\\nชักชวน\\nชักนำ\\nชักเนื้อ\\nชักพระ\\nชักเย่อ\\nชักใย\\nชั่งใจ\\nชังฆวิหาร\\nชัดเจน\\nชั้นเชิง\\nชั่วคน\\nชั่วคราว\\nชั่วช้า\\nชั่วโมง\\nชั่วแล่น\\nชาเย็น\\nช้านาน\\nช่างเครื่อง\\nช่างฝีมือ\\nช่างฟิต\\nช่างไฟ\\nช้างน้ำ\\nช้างเผือก\\nช้างพลาย\\nช้างพัง\\nช้างสาร\\nช้างสีดอ\\nชาติธรรม\\nชาตินิยม\\nชาติพันธุ์\\nชาติพันธุ์วิทยา\\nชาติภูมิ\\nชานชาลา\\nชายชาตรี\\nชายคา\\nชายฝั่ง\\nชายทะเล\\nชาวเล\\nชาววัง\\nช้ำใจ\\nช้ำชอก\\nชิงชัง\\nชิงพลบ\\nชินชา\\nชินบุตร\\nชิ้นเอก\\nชิมลาง\\nชีเปลือย\\nชี้ขาด\\nชี้แจง\\nชี้นำ\\nชี้แนะ\\nชี้ฟ้า\\nชีพจร\\nชีพิตักษัย\\nชื่นชม\\nชื่นบาน\\nชื่นมื่น\\nชื่อย่อ\\nชื่อรอง\\nชื่อเล่น\\nชื่อเสียง\\nชุกชุม\\nชุติมา\\nชุบตัว\\nชุบเลี้ยง\\nชุมชน\\nชุมทาง\\nชุมสาย\\nชุ่มใจ\\nชุ่มชื่น\\nชุ่มชื้น\\nชุมนุมชน\\nชูชีพ\\nชูโรง\\nชู้สาว\\nเชยชม\\nเชลยศักดิ์\\nเชลยศึก\\nเช่าซื้อ\\nเช้าตรู่\\nเช้ามืด\\nเชิงกราน\\nเชิงกล\\nเชิงชั้น\\nเชิงชาย\\nเชิงซ้อน\\nเชิงเดียว\\nเชิงเดี่ยว\\nเชิงตะกอน\\nเชิงเทิน\\nเชิงมุม\\nเชิดชู\\nเชิงอรรถ\\nเชี่ยนหมาก\\nเชี่ยวชาญ\\nเชื่องช้า\\nเชื่อใจ\\nเชื่อถือ\\nเชื่อฟัง\\nเชื่อมือ\\nเชื้อชาติ\\nเชื้อเพลิง\\nเชื้อไฟ\\nเชื้อโรค\\nเชื้อสาย\\nเชื้อเชิญ\\nเชื่องช้า\\nเชือนแช\\nเชื่อวัน\\nแช่เย็น\\nแช่อิ่ม\\nแช่มช้อย\\nแช่มชื่น\\nโชกโชน\\nโชติช่วง\\nโชติรส\\nใช้สอย\\nซบเซา\\nซมซาน\\nซวนเซ\\nซอกซอน\\nซอกแซก\\nซ่องสุม\\nซ่องเสพ\\nซ่องแซ่ง\\nซ่อนรูป\\nซ่อนเร้น\\nซ่อนหา\\nซ่อนกลิ่น\\nซ่อนทราย\\nซ่อมแซม\\nซักค้าน\\nซักซ้อม\\nซักไซ้\\nซักฟอก\\nซักแห้ง\\nซังกะตาย\\nซังตาย\\nซัดเซ\\nซัดทอด\\nซับซ้อน\\nซับใน\\nซับพระพักตร์\\nซากศพ\\nซ่านเซ็น\\nซ้ำซ้อน\\nซ้ำซาก\\nซ้ำเติม\\nซ้ำร้าย\\nซี่โครง\\nซีดเซียว\\nซึมกะทือ\\nซึมซาบ\\nซึมเซา\\nซึมทราบ\\nซึมเศร้า\\nซื่อตรง\\nซื่อสัตย์\\nซื้อขาย\\nซุกซน\\nซุกซ่อน\\nซุบซิบ\\nซู่ซ่า\\nเซซัง\\nเซ่อซ่า\\nแซ่ซ้อง\\nโซดาไฟ\\nญาณทัสนะ\\nญาณวิทยา\\nญาณศาสตร์\\nญาติกา\\nฐานราก\\nดกดื่น\\nดงดิบ\\nดลใจ\\nดลบันดาล\\nดวงแก้ว\\nดวงใจ\\nดวงเดือน\\nดวงตรา\\nดวงตา\\nดวงสมร\\nดอกจัน\\nดอกจิก\\nดอกบัว\\nดอกเบี้ย\\nดอกฟ้า\\nดอกไม้\\nดอกยาง\\nดอกเล็บ\\nดอกทอง\\nดอกสร้อย\\nดองยา\\nดักคอ\\nดักฟัง\\nดังนั้น\\nดังนี้\\nดังหนึ่ง\\nดั้งเดิม\\nดัดจริต\\nดัดแปลง\\nดันทุรัง\\nดับขันธ์\\nดับจิต\\nดับชีพ\\nด่าทอ\\nด่างทับทิม\\nด่างพร้อย\\nดาดฟ้า\\nดาราศาสตร์\\nดาลเดือด\\nดาวกระจาย\\nดาวเคราะห์\\nดาวตก\\nดาวเทียม\\nดาวรุ่ง\\nดาวเรือง\\nดาวฤกษ์\\nดาวหาง\\nดาวเหนือ\\nดาษดื่น\\nดินขาว\\nดินดาน\\nดินดำ\\nดินประสิว\\nดินปืน\\nดินระเบิด\\nดินสอ\\nดินสอพอง\\nดิ้นรน\\nดิบดี\\nดีเกลือ\\nดีใจ\\nดีซ่าน\\nดีดัก\\nดีเดือด\\nดีฝ่อ\\nดีดดิ้น\\nดึกดำบรรพ์\\nดึกดื่น\\nดึงดัน\\nดึงดูด\\nดื่มด่ำ\\nดื้อด้าน\\nดื้อดึง\\nดื้อแพ่ง\\nดื้อยา\\nดื้อรั้น\\nดุดัน\\nดุเดือด\\nดุร้าย\\nดุลการค้า\\nดุลพินิจ\\nดุลภาค\\nดุลยพินิจ\\nดุลยภาพ\\nดุษฎีนิพนธ์\\nดุษฎีบัณฑิต\\nดุษณีภาพ\\nดูแคลน\\nดูถูก\\nดูดาย\\nดูเบา\\nดูแล\\nดูหมิ่น\\nดูเหมือน\\nดูดดื่ม\\nเด็ดขาด\\nเด็ดดวง\\nเด็ดเดี่ยว\\nเดนตาย\\nเดาสวด\\nเดาสุ่ม\\nเดินทาง\\nเดินสะพัด\\nเดินสาย\\nเดินเหิน\\nเดิมพัน\\nเดียงสา\\nเดียดฉันท์\\nเดียวกัน\\nเดียวดาย\\nเดี๋ยวเดียว\\nเดี๋ยวนี้\\nเดือดดาล\\nเดือดร้อน\\nเดือนมืด\\nเดือนหงาย\\nแดดาล\\nแดดิ้น\\nแดกดัน\\nโด่เด่\\nโด่งดัง\\nโดดเดี่ยว\\nโดยสาร\\nได้การ\\nได้แก่\\nได้ใจ\\nได้ที\\nได้ยิน\\nได้เสีย\\nตกเขียว\\nตกค้าง\\nตกใจ\\nตกต่ำ\\nตกแต่ง\\nตกทอด\\nตกฟาก\\nตกมัน\\nตกยาก\\nตกลง\\nตกหล่น\\nต้นขั้ว\\nต้นคิด\\nต้นฉบับ\\nต้นตอ\\nต้นตำรับ\\nต้นทุน\\nต้นแบบ\\nต้นเพลิง\\nต้นมือ\\nต้นไม้\\nต้นร่าง\\nต้นเรื่อง\\nต้นสังกัด\\nต้นหน\\nต้นเหตุ\\nตบตา\\nตบแต่ง\\nตบแผละ\\nตบมือ\\nต้มข่า\\nต้มโคล้ง\\nต้มยำ\\nต้มส้ม\\nตรมตรอม\\nตรรกวิทยา\\nตรรกศาสตร์\\nตรวจการ\\nตรวจการณ์\\nตรวจตรา\\nตระบัดสัตย์\\nตรัสรู้\\nตราตั้ง\\nตราบาป\\nตรายาง\\nตราสาร\\nตริตรอง\\nตรีกฏุก\\nตรีกาย\\nตรีโกณ\\nตรีโกณมิติ\\nตรีคูณ\\nตรีทูต\\nตรีปิฎก\\nตรีภพ\\nตรีมูรติ\\nตรึกตรอง\\nตรึงตรา\\nตรุษจีน\\nตฤณชาติ\\nตฤณมัย\\nตลกบาตร\\nตลบตะแลง\\nตลบหลัง\\nตลาดนัด\\nตลาดน้ำ\\nตลาดมืด\\nตลาดสด\\nต่อตี\\nต่อเติม\\nต่อว่า\\nต่อสู้\\nต่อกร\\nต่อต้าน\\nต่อแย้ง\\nต้องการ\\nต้องโทษ\\nต้องหา\\nต้อนรับ\\nตอบโต้\\nตอบแทน\\nต่อยหอย\\nตะพาบน้ำ\\nตักตวง\\nตักบาตร\\nตั้งเข็ม\\nตั้งไข่\\nตั้งเค้า\\nตั้งแง่\\nตั้งใจ\\nตั้งต้น\\nตั้งแต่\\nตั้งท้อง\\nตัดขาด\\nตัดใจ\\nตัดเชือก\\nตัดตอน\\nตัดทอน\\nตัดบท\\nตัดพ้อ\\nตัดรอน\\nตัดสิน\\nตับเต่า\\nตับแลบ\\nตับอ่อน\\nตัวกลาง\\nตัวการ\\nตัวเก็ง\\nตัวดี\\nตัวตั้ง\\nตัวเต็ง\\nตัวถัง\\nตัวแทน\\nตัวประกอบ\\nตัวประกัน\\nตัวแปร\\nตัวผู้\\nตัวพิมพ์\\nตัวเมีย\\nตัวยืน\\nตัวเลข\\nตัวอย่าง\\nตั๋วเงิน\\nตั๋วแลกเงิน\\nตากล้อง\\nตาไก่\\nตาข่าย\\nตาชั่ง\\nตาตุ่ม\\nตาทวด\\nตาปลา\\nตาราง\\nต่างหาก\\nต้านทาน\\nตามใจ\\nตายใจ\\nตายซาก\\nตายด้าน\\nตายตัว\\nตายทั้งกลม\\nตายห่า\\nตายโหง\\nตาลปัตร\\nต่ำช้า\\nต่ำต้อย\\nตำส้ม\\nติเตียน\\nติณชาติ\\nติดขัด\\nติดใจ\\nติดต่อ\\nติดตั้ง\\nติดตาม\\nติดตื้น\\nติดพัน\\nติดลม\\nติดอ่าง\\nตีเกลียว\\nตีขลุม\\nตีความ\\nตีคู่\\nตีจาก\\nตีตื้น\\nตีแผ่\\nตีรวน\\nตีลังกา\\nตีวง\\nตีเสมอ\\nตีนกา\\nตีนคู้\\nตีนจก\\nตีนตะขาบ\\nตีนผี\\nตีนเหยียด\\nตึกแถว\\nตึกระฟ้า\\nตึงเครียด\\nตึงตัง\\nตื้นตัน\\nตื่นตัว\\nตื่นตูม\\nตื่นเต้น\\nตุ๊ต๊ะ\\nตุ้บตั้บ\\nตุ้มหู\\nตุลาการ\\nตุลาคม\\nตู้นิรภัย\\nตูมตาม\\nตู้เสบียง\\nเตโชธาตุ\\nเตร็ดเตร่\\nเต้นรำ\\nเตาแก๊ส\\nเตาผิง\\nเตาฟู่\\nเตาไฟ\\nเตารีด\\nเตาสูบ\\nเต่าทอง\\nเต้ารับ\\nเต้าส่วน\\nเต้าเสียบ\\nเต้าหู้ยี้\\nแต่ละ\\nแตกคอ\\nแตกคอก\\nแตกฉาน\\nแตกดับ\\nแตกตื่น\\nแตกพาน\\nแตกแยก\\nแตกร้าว\\nแตกหัก\\nแต่งงาน\\nแต่งตั้ง\\nแต้มคู\\nแต้มต่อ\\nแตรงอน\\nแตรเดี่ยว\\nแตรฝรั่ง\\nแตรฟันฟาร์\\nแตรวง\\nโต้ตอบ\\nโต้เถียง\\nโต้แย้ง\\nโต๊ะหมู่\\nโต๊ะอิหม่าม\\nใต้ถุน\\nไต้ก๋ง\\nไต่คู้\\nไต่เต้า\\nไต่ถาม\\nไต้ฝุ่น\\nไตรจักร\\nไตรจีวร\\nไตรตรึงษ์\\nไตรทวาร\\nไตรปิฎก\\nไตรเพท\\nไตรภพ\\nไตรภูมิ\\nไตรภาคี\\nไตรยางศ์\\nไตรรงค์\\nไตรรัตน์\\nไตรลักษณ์\\nไตรโลก\\nไตรสรณคมน์\\nไตรสิกขา\\nไต่สวน\\nถกเถียง\\nถดถอย\\nถนัดถนี่\\nถนิมสร้อย\\nถมถืด\\nถมเถ\\nถมไป\\nถลากไถล\\nถ้วนถี่\\nถ้วยฟู\\nถ่องแท้\\nถอดถอน\\nถ้อยคำ\\nถ้อยแถลง\\nถากถาง\\nถ่านไฟฉาย\\nถ่านหิน\\nถามไถ่\\nถ่ายทอด\\nถ่ายทุกข์\\nถ่ายเท\\nถาวรวัตถุ\\nถ้ำมอง\\nถี่ถ้วน\\nถึงใจ\\nถูกใจ\\nถูกชะตา\\nเถรวาท\\nเถ้าแก่\\nเถ้าแก่เนี้ย\\nแถมพก\\nแถลงการณ์\\nไถ่ถอน\\nไถ่ถาม\\nทดแทน\\nทดรอง\\nทดลอง\\nทดสอบ\\nทนทาน\\nทนายความ\\nทบทวน\\nทแยงมุม\\nทรงกลด\\nทรงเครื่อง\\nทรงเจ้า\\nทรัพย์สิน\\nทรามชม\\nทรามเชย\\nทรามวัย\\nทรามสงวน\\nทรามสวาท\\nทรุดโทรม\\nทฤษฎีบท\\nท้วงติง\\nท่วมท้น\\nทวาทศ\\nทวาทศมาส\\nทวาบรยุค\\nทวารบาล\\nทวิบถ\\nทวิบท\\nทวิบาท\\nทวิภาค\\nทวิภาคี\\nทวีคูณ\\nทศกัณฐ์\\nทศชาติ\\nทศทิศ\\nทศนิยม\\nทศพร\\nทศพล\\nทศพิธราชธรรม\\nทศมาส\\nทศวรรษ\\nท่อไอเสีย\\nท้อถอย\\nท้อแท้\\nทองขาว\\nทองคำ\\nทองคำขาว\\nทองคำเปลว\\nทองเค\\nทองแดง\\nทองบรอนซ์\\nทองม้วน\\nทองย้อย\\nทองสัมฤทธิ์\\nทองหยอด\\nทองหยิบ\\nทองเหลือง\\nทองเอก\\nท่องเที่ยว\\nท้องตรา\\nท้องถิ่น\\nท้องที่\\nท้องน้อย\\nท้องร่อง\\nท้องเรื่อง\\nทอดมัน\\nทอดทิ้ง\\nทอดน่อง\\nทอดยอด\\nทอดหุ่ย\\nทอยกอง\\nทะเบียนบ้าน\\nทะเลทราย\\nทะเลสาบ\\nทะเลหลวง\\nทักขิณาวัฏ\\nทักท้วง\\nทักทาย\\nทักษิณาวรรต\\nทักษิณาทาน\\nทักษิณานุประทาน\\nทั้งกลม\\nทั้งคน\\nทั้งดุ้น\\nทั้งที\\nทั้งนั้น\\nทั้งนี้\\nทั้งปวง\\nทั้งผอง\\nทั้งเพ\\nทั้งมวล\\nทั้งสิ้น\\nทั้งหมด\\nทั้งหลาย\\nทัณฑ์บน\\nทัดทาน\\nทัดเทียม\\nทันควัน\\nทันใจ\\nทันใด\\nทันตา\\nทันสมัย\\nทันที\\nทับถม\\nทับทรวง\\nทับศัพท์\\nทั่วถึง\\nทั่วไป\\nท่าทาง\\nท่าที\\nท้าทาย\\nทางการ\\nทางข้าม\\nทางด่วน\\nทางเท้า\\nทางโท\\nทางใน\\nทางผ่าน\\nทางม้าลาย\\nทางหลวง\\nทางออก\\nทางเอก\\nทานกัณฑ์\\nทานตะวัน\\nท่านชาย\\nทานบารมี\\nท่านผู้หญิง\\nท่านหญิง\\nทาบทาม\\nท้ายทอย\\nทารุณกรรม\\nทำคลอด\\nทำใจ\\nทำซ้ำ\\nทำท่า\\nทำที\\nทำแท้ง\\nทำโทษ\\nทำบาป\\nทำบุญ\\nทำพิษ\\nทำฟัน\\nทำร้าย\\nทำวัตร\\nทำสาว\\nทำเสน่ห์\\nทำหมัน\\nทำให้\\nทิ้งขว้าง\\nทิ้งทวน\\nทิ้งท้าย\\nทินกร\\nทิพจักขุ\\nทิพโสต\\nทิพยจักษุ\\nทิพยญาณ\\nทิพยเนตร\\nทิพยรส\\nทิพากร\\nทิ่มตำ\\nทิ่มแทง\\nทิวากร\\nทิวากาล\\nทิศทาง\\nทีเด็ด\\nทีท่า\\nทีนี้\\nทีหลัง\\nทีฆนิกาย\\nทีฆสระ\\nที่ดิน\\nที่นอน\\nที่นั่ง\\nที่ปรึกษา\\nที่พึ่ง\\nที่มั่น\\nที่ราบ\\nที่ว่าการ\\nที่สุด\\nที่หมาย\\nที่ไหน\\nทุกที\\nทุกเมื่อ\\nทุกข์สุข\\nทุนทรัพย์\\nทุนนิยม\\nทุนรอน\\nทุนสำรอง\\nทุ่มเถียง\\nทุ่มเท\\nทูนหัว\\nทูลกระหม่อม\\nเทกระจาด\\nเทครัว\\nเทพเจ้า\\nเทพดา\\nเทพธิดา\\nเทพนม\\nเทพนิยม\\nเทพนิยาย\\nเทพบุตร\\nเทพสังหรณ์\\nเทศกาล\\nเทศนาโวหาร\\nเทศบัญญัติ\\nเทศบาล\\nเทศมนตรี\\nเทห์ฟากฟ้า\\nเท่ากับ\\nเท่าใด\\nเท่าตัว\\nเท่าทัน\\nเท่าทุน\\nเท่าเทียม\\nเท่านั้น\\nเท่าไร\\nเท้าช้าง\\nเทิดทูน\\nเที่ยงตรง\\nเที่ยงแท้\\nเที่ยงธรรม\\nเทียนชนวน\\nเทียนพรรษา\\nเทียบเคียง\\nเทียบเท่า\\nเทือกเขา\\nเทือกเถา\\nแท็งก์น้ำ\\nแท่นพิมพ์\\nแท่นมณฑล\\nแท่นหมึก\\nแทรกซอน\\nแทรกซ้อน\\nแทรกซึม\\nแทรกแซง\\nแทะโลม\\nไทยดำ\\nไทยทาน\\nไทยธรรม\\nไทยน้อย\\nไทยใหญ่\\nธงชัย\\nธงชาติ\\nธงทิว\\nธรณีวิทยา\\nธรณีสงฆ์\\nธรรมกาย\\nธรรมการ\\nธรรมเกษตร\\nธรรมขันธ์\\nธรรมคุณ\\nธรรมจรรยา\\nธรรมจริยา\\nธรรมจักร\\nธรรมจักษุ\\nธรรมจาคะ\\nธรรมจารี\\nธรรมชาติ\\nธรรมดา\\nธรรมเนียม\\nธรรมราชา\\nธรรมศาสตร์\\nธรรมสภา\\nธรรมสังเวช\\nธัญพืช\\nธารพระกร\\nธีรภาพ\\nธีรราช\\nนกเขา\\nนกต่อ\\nนกยูง\\nนกรู้\\nนกหวีด\\nนครบาล\\nนครรัฐ\\nนงคราญ\\nนงนุช\\nนงพะงา\\nนงเยาว์\\nนงราม\\nนงลักษณ์\\nนบนอบ\\nนพเก้า\\nนพคุณ\\nนพเคราะห์\\nนพปฎล\\nนพพล\\nนพรัตน์\\nนพศก\\nนพศูล\\nนมข้น\\nนมผง\\nนมไม้\\nนมนาน\\nนมหนู\\nนมแมว\\nนรีเวช\\nนรีเวชวิทยา\\nนวดฟั้น\\nนวยนาด\\nนวลระหง\\nนวลลออ\\nนวลละออง\\nนวลจันทร์\\nนอกครู\\nนอกคอก\\nนอกจาก\\nนอกใจ\\nนอกชาน\\nนอกรีต\\nนอกเหนือ\\nนองเนือง\\nนองเลือด\\nนอนก้น\\nนอนใจ\\nนอบนบ\\nนอนเล่น\\nนอบน้อม\\nน้อมนำ\\nน้อยใจ\\nน้อยหน้า\\nนักการ\\nนักการเมือง\\nนักกีฬา\\nนักข่าว\\nนักท่องเที่ยว\\nนักเทศน์\\nนักโทษ\\nนักธรรม\\nนักบวช\\nนักบิน\\nนักบุญ\\nนักปราชญ์\\nนักพรต\\nนักรบ\\nนักเรียน\\nนักเลง\\nนักวิชาการ\\nนักศึกษา\\nนักสิทธิ์\\nนักสืบ\\nนักหนา\\nนั่งเทียน\\nนั่งร้าน\\nนัดแนะ\\nนัดหมาย\\nนั่นแหละ\\nนั่นเอง\\nนับถือ\\nนับประสา\\nนัยน์ตา\\nนาดำ\\nนาปรัง\\nนาปี\\nนาสวน\\nนาหว่าน\\nนาคบาศ\\nนาคปรก\\nนาคราช\\nนางกวัก\\nนางกำนัล\\nนางงาม\\nนางใน\\nนางบำเรอ\\nนางแบบ\\nนางพญา\\nนางฟ้า\\nนางไม้\\nนางโลม\\nนางสาว\\nนางห้าม\\nนางเอก\\nนาฏกรรม\\nนาฏดนตรี\\nนาฏศิลป์\\nนานนม\\nน่านน้ำ\\nน่านฟ้า\\nนามกร\\nนามธรรม\\nนามไธย\\nนามบัตร\\nนามปากกา\\nนามแฝง\\nนามสกุล\\nนามสงเคราะห์\\nนามสมญา\\nนายทะเบียน\\nนายท่า\\nนายท้าย\\nนายทุน\\nนายประกัน\\nนายหน้า\\nนายอำเภอ\\nนารายณ์หัตถ์\\nนารีผล\\nนาวิกโยธิน\\nนำจับ\\nนำพา\\nนำทาง\\nนำร่อง\\nนำสืบ\\nนำแสดง\\nน้ำกรด\\nน้ำกาม\\nน้ำเกลือ\\nน้ำข้าว\\nน้ำแข็ง\\nน้ำแข็งไส\\nน้ำแข็งแห้ง\\nน้ำครำ\\nน้ำคร่ำ\\nน้ำค้าง\\nน้ำค้างแข็ง\\nน้ำคาวปลา\\nน้ำคำ\\nน้ำเค็ม\\nน้ำเคย\\nน้ำเงิน\\nน้ำเงี้ยว\\nน้ำจัณฑ์\\nน้ำจิ้ม\\nน้ำใจ\\nน้ำเชื้อ\\nน้ำเชื่อม\\nน้ำซาวข้าว\\nน้ำดอกไม้\\nน้ำดี\\nน้ำตก\\nน้ำตา\\nน้ำตาล\\nน้ำท่า\\nน้ำนม\\nน้ำนวล\\nน้ำบาดาล\\nน้ำประสานทอง\\nน้ำประปา\\nน้ำปลา\\nน้ำป่า\\nน้ำผึ้ง\\nน้ำพริก\\nน้ำพริกเผา\\nน้ำพี้\\nน้ำพุ\\nน้ำมนต์\\nน้ำมนตร์\\nน้ำมัน\\nน้ำมือ\\nน้ำมูก\\nน้ำเมา\\nน้ำย่อย\\nน้ำยา\\nน้ำรัก\\nน้ำแร่\\nน้ำลาย\\nน้ำเลี้ยง\\nน้ำสต๊อก\\nน้ำส้ม\\nน้ำส้มสายชู\\nน้ำสังข์\\nน้ำสาบาน\\nน้ำเสียง\\nน้ำหนวก\\nน้ำหนอง\\nน้ำหนัก\\nน้ำหน้า\\nน้ำหนึ่ง\\nน้ำหมึก\\nน้ำหอม\\nน้ำเหลือง\\nน้ำอบ\\nน้ำอ้อย\\nน้ำอัดลม\\nนิ่งเฉย\\nนิจศีล\\nนิดเดียว\\nนิดหน่อย\\nนิติกร\\nนิติกรรม\\nนิติธรรม\\nนิตินัย\\nนิติบัญญัติ\\nนิติบุคคล\\nนิติภาวะ\\nนิติวิทยาศาสตร์\\nนิติเวช\\nนิติเวชศาสตร์\\nนิติศาสตร์\\nนิเทศศาสตร์\\nนิ่มนวล\\nนิรุกติศาสตร์\\nนิเวศวิทยา\\nนิศากร\\nนิศากาล\\nนิศาชล\\nนิศารัตน์\\nนี่แน่ะ\\nนี่แหละ\\nนี่เอง\\nนึกคิด\\nนุงถุง\\nนุ่งห่ม\\nนุ่มนวล\\nนุ่มนิ่ม\\nเนตรนารี\\nเนติบัณฑิต\\nเนยเทียม\\nเนยใส\\nเนิ่นนาน\\nเนิบนาบ\\nเนื้อความ\\nเนื้อคู่\\nเนื้อเค็ม\\nเนื้องอก\\nเนื้อตัว\\nเนื้อตาย\\nเนื้อที่\\nเนื้อแท้\\nเนื้อเปื่อย\\nเนื้อผ้า\\nเนื้อเพลง\\nเนื้อไม้\\nเนื้อเยื่อ\\nเนื้อร้อง\\nเนื้อร้าย\\nเนื้อเรื่อง\\nเนื้อหา\\nเนืองนอง\\nเนืองนิตย์\\nเนืองแน่น\\nแน่ใจ\\nแน่ชัด\\nแน่แท้\\nแน่นอน\\nแน่นิ่ง\\nแน่แน่ว\\nแน่นแฟ้น\\nแน่นหนา\\nแนบเนียน\\nแนบแน่น\\nแนวคิด\\nแนวทาง\\nแนวโน้ม\\nแนวป่า\\nแนวรบ\\nแนวร่วม\\nแนวหน้า\\nแนวหลัง\\nแน่วแน่\\nแนะนำ\\nแนะแนว\\nโน้มน้าว\\nในหลวง\\nบกพร่อง\\nบงกช\\nบงการ\\nบดบัง\\nบทกลอน\\nบทกวี\\nบทความ\\nบทคัดย่อ\\nบทเฉพาะกาล\\nบทนำ\\nบทบัญญัติ\\nบทบาท\\nบทประพันธ์\\nบทเพลง\\nบทร้อง\\nบทเรียน\\nบทลงโทษ\\nบทสนทนา\\nบทอัศจรรย์\\nบทจร\\nบทบงสุ์\\nบทมาลย์\\nบทรัช\\nบทเรศ\\nบทวลัญช์\\nบนบาน\\nบรมครู\\nบรมธาตุ\\nบรมบพิตร\\nบรมวงศานุวงศ์\\nบรมอัฐิ\\nบรรณพิภพ\\nบรรณศาลา\\nบรรณาการ\\nบรรณาธิการ\\nบรรณานุกรม\\nบรรณารักษ์\\nบรรณารักษศาสตร์\\nบรรดามี\\nบรรดาศักดิ์\\nบรรทัดฐาน\\nบรรพบุรุษ\\nบรรลัยกัลป์\\nบรรลัยจักร\\nบริคณห์สนธิ\\nบวงสรวง\\nบ่วงบาศ\\nบ้วนพระโอษฐ์\\nบ่อเกิด\\nบอกกล่าว\\nบอกบท\\nบอกบุญ\\nบอกใบ้\\nบอกปัด\\nบ้องกัญชา\\nบ้องตื้น\\nบ้องไฟ\\nบ้องหู\\nบอดสี\\nบ่อนทำลาย\\nบอบช้ำ\\nบอบบาง\\nบอบแบบ\\nบังโกลน\\nบังโคลน\\nบังใบ\\nบั้งไฟ\\nบังคับการ\\nบังคับบัญชา\\nบัญชาการ\\nบัณฑุกัมพล\\nบัดดล\\nบัดเดี๋ยว\\nบัดนั้น\\nบัดนี้\\nบัดสีบัดเถลิง\\nบัตรเครดิต\\nบัตรพลี\\nบัตรสนเท่ห์\\nบัตรสินเชื่อ\\nบั่นทอน\\nบั้นท้าย\\nบั้นปลาย\\nบั้นพระองค์\\nบั้นเอว\\nบันไดลิง\\nบันไดเลื่อน\\nบันเทิงคดี\\nบัวลอย\\nบัวบก\\nบ้าจี้\\nบ้าดีเดือด\\nบ้าน้ำลาย\\nบ้าบิ่น\\nบ้าระห่ำ\\nบ้าเลือด\\nบ้าหอบฟาง\\nบากบั่น\\nบากหน้า\\nบางตา\\nบางเบา\\nบางที\\nบาดเจ็บ\\nบาดแผล\\nบาดหมาง\\nบาตรใหญ่\\nบาทบงกช\\nบาทบงสุ์\\nบาทบริจาริกา\\nบาทวิถี\\nบานเกล็ด\\nบานตะเกียง\\nบานตะไท\\nบานเบอะ\\nบานปลาย\\nบานแผละ\\nบานพับ\\nบ้านจัดสรร\\nบ้านช่อง\\nบ้านนอก\\nบ้านพัก\\nบ้านเมือง\\nบ้านรับรอง\\nบ้านเรือน\\nบาปกรรม\\nบายศรี\\nบ่ายเบี่ยง\\nบ่ายหน้า\\nบ่าวไพร่\\nบิดเบี้ยว\\nบิดเบือน\\nบิดพลิ้ว\\nบี้แบน\\nบีบคั้น\\nบีบรัด\\nบึ้งตึง\\nบึ้งบูด\\nบุกบั่น\\nบุกเบิก\\nบุกรุก\\nบุคลิกภาพ\\nบุคลิกลักษณะ\\nบุญธรรม\\nบุญนิธิ\\nบุญฤทธิ์\\nบุบสลาย\\nบุ้ยใบ้\\nบุรุษเพศ\\nบุหงารำไป\\nบู้บี้\\nบูชายัญ\\nบูดบึ้ง\\nบูดเบี้ยว\\nเบาความ\\nเบาใจ\\nเบาบาง\\nเบาปัญญา\\nเบามือ\\nเบาแรง\\nเบาสมอง\\nเบาหวาน\\nเบาโหวง\\nเบ้าตา\\nเบาะแส\\nเบิกความ\\nเบิกบาน\\nเบี้ยล่าง\\nเบี้ยเลี้ยง\\nเบี้ยหวัด\\nเบี่ยงบ่าย\\nเบียดบัง\\nเบียดเบียน\\nเบียดเสียด\\nเบื้องต้น\\nเบื้องบน\\nเบื้องหน้า\\nเบื้องหลัง\\nแบกะดิน\\nแบเบาะ\\nแบ่งเบา\\nแบ่งปัน\\nแบ่งแยก\\nแบบฉบับ\\nแบบแปลน\\nแบบแผน\\nแบบฝึกหัด\\nแบบพิมพ์\\nแบบสอบถาม\\nแบบอย่าง\\nแบะแฉะ\\nแบะท่า\\nโบแดง\\nโบราณคดี\\nโบราณวัตถุ\\nโบราณสถาน\\nใบขับขี่\\nใบจอง\\nใบตอง\\nใบแทรก\\nใบบอก\\nใบบุญ\\nใบเบิกทาง\\nใบปลิว\\nใบพัด\\nใบโพ\\nใบไม้\\nใบระกา\\nใบรับรอง\\nใบลา\\nใบเลี้ยง\\nใบสั่ง\\nใบสำคัญ\\nใบสุทธิ\\nใบเสร็จ\\nใบหน้า\\nใบอนุญาต\\nใบระกา\\nปกครอง\\nปกคลุม\\nปกป้อง\\nปกปิด\\nปฏิบัติการ\\nปฏิบัติบูชา\\nปฐพีวิทยา\\nปฐมฌาน\\nปฐมทัศน์\\nปฐมเทศนา\\nปฐมนิเทศ\\nปฐมพยาบาล\\nปฐมยาม\\nปฐมฤกษ์\\nปฐมวัย\\nปฐมสมโพธิ\\nปนเป\\nป่นปี้\\nปมเขื่อง\\nปมเด่น\\nปมด้อย\\nปรนเปรอ\\nปรบไก่\\nปรบมือ\\nปรสิตวิทยา\\nประโปรย\\nประพรม\\nประกันชีวิต\\nประกันภัย\\nประจักษ์พยาน\\nประจัญบาน\\nประจันหน้า\\nประจำการ\\nประจำเดือน\\nประจำเมือง\\nประจำยาม\\nประชดประชัน\\nประชากร\\nประชากรศาสตร์\\nประชาคม\\nประชาชน\\nประชาราษฎร์\\nประชาชาติ\\nประชาชี\\nประชาทัณฑ์\\nประชาบาล\\nประชาพิจารณ์\\nประชาภิบาล\\nประชามติ\\nประชาสงเคราะห์\\nประชาสัมพันธ์\\nประดับประดา\\nประดามี\\nประดาน้ำ\\nประเดี๋ยวเดียว\\nประเดี๋ยวนี้\\nประทับใจ\\nประทุษร้าย\\nประเทศราช\\nประพาสต้น\\nประเพณีนิยม\\nประลัยกัลป์\\nประวัติการณ์\\nประวัติศาสตร์\\nประสบการณ์\\nประสบการณ์นิยม\\nประสาทการ\\nประสูติการ\\nประสูติกาล\\nประเส\\nปรับทุกข์\\nปรับโทษ\\nปรับปรุง\\nปรากฏการณ์\\nปราดเปรียว\\nปราดเปรื่อง\\nปราบปราม\\nปริญญาบัตร\\nปรัยัติธรรม\\nปรุโปร่ง\\nปลงใจ\\nปลงตก\\nปลดทุกข์\\nปลดปลง\\nปลดปล่อย\\nปลดเปลื้อง\\nปลดระวาง\\nปลดแอก\\nปล้นสะดม\\nปลอกกระสุน\\nปลอกคอ\\nปลอดโปร่ง\\nปลอดภัย\\nปลอมปน\\nปลอมแปลง\\nปลอบโยน\\nปล่อยใจ\\nปล่อยตัว\\nปล่อยปละ\\nปลั๊กไฟ\\nปลากริม\\nปลาเค็ม\\nปลาจ่อม\\nปลาเจ่า\\nปลาแดก\\nปลาตู้\\nปลาทอง\\nปลาร้า\\nปลาส้ม\\nปลาดาว\\nปลาบิน\\nปลาฝา\\nปลาวาฬ\\nปลาหมึก\\nปลาบปลื้ม\\nปลายข้าว\\nปลายแถว\\nปลายทาง\\nปลิ้นปลอก\\nปลิ้นปล้อน\\nปลีกตัว\\nปลีกย่อย\\nปลุกใจ\\nปลุกปล้ำ\\nปลุกปั่น\\nปลุกระดม\\nปลุกเสก\\nปลูกฝัง\\nปลูกสร้าง\\nปวดถ่วง\\nปวดมวน\\nปวดร้าว\\nป่วนปั่น\\nป่วยการ\\nปอกลอก\\nป้องกัน\\nปักใจ\\nปักดำ\\nปักหลัก\\nปัจเจกบุคคล\\nปัจเจกพุทธะ\\nปัจเจกโพธิ\\nปัจฉิมชน\\nปัจฉิมทิศ\\nปัจฉิมภาค\\nปัจฉิมยาม\\nปัจฉิมลิขิต\\nปัจฉิมวัย\\nปัจฉิมวาจา\\nปัญญาชน\\nปัญญาวิมุติ\\nปัญญาอ่อน\\nปัดเป่า\\nปันส่วน\\nปั่นป่วน\\nปั่นแปะ\\nปั่นหัว\\nปั้นจิ้ม\\nปั้นเจ๋อ\\nปั้นปึ่ง\\nปั้นสิบ\\nปั๊มน้ำมัน\\nป่าช้า\\nป่าชายเลน\\nป่าดง\\nป่าดงดิบ\\nป่าดิบ\\nป่าเถื่อน\\nป่าเบญจพรรณ\\nป่าละเมาะ\\nปากกา\\nปากขอ\\nปากแข็ง\\nปากคอ\\nปากคำ\\nปากคีบ\\nปากจัด\\nปากน้ำ\\nปากเปล่า\\nปากเสียง\\nปานกลาง\\nป่านนี้\\nป้านลม\\nป้ายสี\\nป่าวร้อง\\nปิดฉาก\\nปิดบัง\\nปิตุฆาต\\nปิตุภูมิ\\nปีมะโว้\\nปีแสง\\nปี่กลาง\\nปี่ไฉน\\nปี่ชวา\\nปี่นอก\\nปี่ใน\\nปี่พาทย์\\nปี่อ้อ\\nปีกกา\\nปีนเกลียว\\nปีนป่าย\\nปึกแผ่น\\nปึงปัง\\nปืนกล\\nปืนครก\\nปืนพก\\nปืนยา\\nปืนยาว\\nปืนลม\\nปืนเล็ก\\nปืนเล็กยาว\\nปืนสั้น\\nปืนใหญ่\\nปุบปับ\\nปุ๊บปั๊บ\\nปุ่มเปือก\\nปุยฝ้าย\\nปุ๋ยคอก\\nปุ๋ยเคมี\\nปุ๋ยวิทยาศาสตร์\\nปุ๋ยหมัก\\nปุ๋ยอินทรีย์\\nปูจ๋า\\nปูเสฉวน\\nปู่เจ้า\\nปู่ทวด\\nปูนขาว\\nปูนซีเมนต์\\nปูนดิบ\\nปูนแดง\\nปูนปลาสเตอร์\\nปูนปั้น\\nเป็ดเทศ\\nเป็ดน้ำ\\nเป็นกลาง\\nเป็นใจ\\nเป็นต้น\\nเป็นต่อ\\nเป็นรอง\\nเป็นไร\\nเป็นลม\\nเป็นห่วง\\nเป็นอยู่\\nเปรมปรีดิ์\\nเปรอะเปื้อน\\nเปรียบเทียบ\\nเปรียบเปรย\\nเปรี้ยวปาก\\nเปรี้ยวหวาน\\nเปรื่องปราด\\nเปลญวน\\nเปล่งปลั่ง\\nเปล่าดาย\\nเปล่าเปลี่ยว\\nเปลี่ยนใจ\\nเปลี่ยนตัว\\nเปลี่ยนแปลง\\nเปลี่ยนมือ\\nเปลี่ยนหน้า\\nเป๋อเหลอ\\nเปะปะ\\nเป่ากบ\\nเป้านิ่ง\\nเป้าหมาย\\nเปิดฉาก\\nเปิดเปิง\\nเปิดโปง\\nเปิดผนึก\\nเปิดเผย\\nเปียกปูน\\nแป้งสาลี\\nแป้งนวล\\nแป้งเปียก\\nแป้งมัน\\nแป้งฝุ่น\\nแป้งร่ำ\\nแป้งสิงคโปร์\\nแป้งหมี่\\nแปดปน\\nแปดเปื้อน\\nแปรปรวน\\nแปรผัน\\nแปรพักตร์\\nแปรรูป\\nแปรอักษร\\nแปลกปลอม\\nแปะโป้ง\\nโป้ปด\\nโปร่งแสง\\nโปร่งใส\\nโปรดปราน\\nโปรยทาน\\nโปรยปราย\\nโปโลน้ำ\\nผกผัน\\nผกากรอง\\nผงขาว\\nผงชูรส\\nผงซักฟอก\\nผงฟู\\nผดุงครรภ์\\nผมไฟ\\nผลพลอยได้\\nผลลัพธ์\\nผลัดเปลี่ยน\\nผลิตผล\\nผลิตภัณฑ์\\nผลุบโผล่\\nผสมเทียม\\nผสมผสาน\\nผสมผเส\\nผสมพันธุ์\\nผสมโรง\\nผสมเสร็จ\\nผ่องแผ้ว\\nผ่องใส\\nผ่อนคลาย\\nผ่อนชำระ\\nผ่อนปรน\\nผ่อนผัน\\nผ่อนส่ง\\nผอมโซ\\nผอมแห้ง\\nผักชี\\nผักตบชวา\\nผักบุ้ง\\nผังเมือง\\nผัดผ่อน\\nผันแปร\\nผันผวน\\nผ่าตัด\\nผ่าเผย\\nผ่าหมาก\\nผ่าเหล่า\\nผ้าขนหนู\\nผ้าขาวม้า\\nผ้าขี้ริ้ว\\nผ้าเช็ดตัว\\nผ้าเช็ดปาก\\nผ้าเช็ดมือ\\nผ้าเช็ดหน้า\\nผ้าดิบ\\nผ้าต่วน\\nผ้าไตร\\nผ้าถุง\\nผ้าแถบ\\nผ้านวม\\nผ้านุ่ง\\nผ้าใบ\\nผ้าป่า\\nผ้าป่าน\\nผ้าผ่อน\\nผ้าพันคอ\\nผ้าพันแผล\\nผ้าแพร\\nผ้าโพกหัว\\nผ้ามัดหมี่\\nผ้ายาง\\nผ้าลูกไม้\\nผ้าเหลือง\\nผ้าอนามัย\\nผ้าอ้อม\\nผาดโผน\\nผาติกรรม\\nผิดหวัง\\nผิวเผิน\\nผิวพรรณ\\nผิวหนัง\\nผีกระสือ\\nผีกระหัง\\nผีกองกอย\\nผีโขมด\\nผีดิบ\\nผีตองเหลือง\\nผีถ้วยแก้ว\\nผีแถน\\nผีทะเล\\nผีบุญ\\nผีปอบ\\nผีพุ่งไต้\\nผีฟ้า\\nผีเรือน\\nผีสาง\\nผีเสื้อ\\nผีห่า\\nผึ่งผาย\\nผุดผ่อง\\nผุดผาด\\nผู้คน\\nผู้คุม\\nผู้จัดการ\\nผู้ชาย\\nผู้เชี่ยวชาญ\\nผู้ดี\\nผู้โดยสาร\\nผู้ต้องขัง\\nผู้ต้องหา\\nผู้แทน\\nผู้น้อย\\nผู้บริโภค\\nผู้บังคับบัญชา\\nผู้ปกครอง\\nผู้ประกอบการ\\nผู้ป่วย\\nผู้พิพากษา\\nผู้เยาว์\\nผู้ร้าย\\nผู้วิเศษ\\nผู้สื่อข่าว\\nผู้เสียหาย\\nผู้หญิง\\nผู้ใหญ่\\nผู้ใหญ่บ้าน\\nผูกขวัญ\\nผูกขาด\\nผูกพัน\\nผูกมัด\\nเผชิญหน้า\\nเผด็จการ\\nเผด็จศึก\\nเผยแผ่\\nเผยแพร่\\nเผละผละ\\nเผ่าพันธุ์\\nเผื่อแผ่\\nแผงลอย\\nแผนการ\\nแผนงาน\\nแผนที่\\nแผนผัง\\nแผนภาพ\\nแผนภูมิ\\nแผ่นดิน\\nแผ่นเสียง\\nแผ้วพาน\\nโผงผาง\\nฝนทอง\\nฝอยทอง\\nฝักแค\\nฝักบัว\\nฝักฝ่าย\\nฝักใฝ่\\nฝังใจ\\nฝังหัว\\nฝาชี\\nฝาแฝด\\nฝาละมี\\nฝ่าพระบาท\\nฝ่าฝืน\\nฝ่าฟัน\\nฝ้าฟาง\\nฝากตัว\\nฝากฝัง\\nฝีดาษ\\nฝีมะม่วง\\nฝีจักร\\nฝีเท้า\\nฝีปาก\\nฝีพาย\\nฝีมือ\\nฝีเย็บ\\nฝึกงาน\\nฝึกปรือ\\nฝึกฝน\\nฝึกสอน\\nฝึกหัด\\nฝืดเคือง\\nใฝ่ฝัน\\nพงพี\\nพงศ์พันธุ์\\nพญาโศก\\nพญาไฟ\\nพบปะ\\nพบพาน\\nพรสวรรค์\\nพรมคด\\nพรมแดน\\nพรมมิ\\nพรรคพวก\\nพรรณราย\\nพรวดพราด\\nพรหมชาติ\\nพรหมลิขิต\\nพรหมโลก\\nพรหมวิหาร\\nพร้อมใจ\\nพร้อมพรั่ง\\nพร้อมเพรียง\\nพร้อมมูล\\nพร้อมสรรพ\\nพร้อมหน้า\\nพระครู\\nพระคุณ\\nพระเคราะห์\\nพระเครื่อง\\nพระเจ้า\\nพระเจ้าอยู่หัว\\nพระชายา\\nพระทัย\\nพระนาง\\nพระนางเจ้า\\nพระเป็นเจ้า\\nพระผู้เป็นเจ้า\\nพระพิมพ์\\nพระพุทธเจ้า\\nพระพุทธองค์\\nพระภูมิ\\nพระยา\\nพระรอง\\nพระสนม\\nพระสนมเอก\\nพระองค์\\nพระองค์เจ้า\\nพระเอก\\nพรั่งพร้อม\\nพรั่งพรู\\nพรั่นพรึง\\nพร่างพราว\\nพรายน้ำ\\nพรายแพรว\\nพราวแพรว\\nพร่ำพลอด\\nพร่ำเพรื่อ\\nพร่ำเพ้อ\\nพริกไทย\\nพริ้งพราย\\nพริ้งเพรา\\nพริ้งเพริศ\\nพริบตา\\nพริ้มพราย\\nพริ้มเพรา\\nพรุ่งนี้\\nพฤติกรรม\\nพฤติการณ์\\nพฤตินัย\\nพลการ\\nพลขับ\\nพลความ\\nพลเมือง\\nพลรบ\\nพลร่ม\\nพลเรือน\\nพลโลก\\nพลศึกษา\\nพลบค่ำ\\nพลอดรัก\\nพลังงาน\\nพลังเงียบ\\nพลังจิต\\nพลั้งปาก\\nพลั้งเผลอ\\nพลั้งพลาด\\nพลัดถิ่น\\nพลัดพราก\\nพลาดท่า\\nพลาดพลั้ง\\nพลิกแพลง\\nพลีกรรม\\nพลุ่งพล่าน\\nพวกพ้อง\\nพวงมาลัย\\nพวงมาลา\\nพวงหรีด\\nพวงคราม\\nพวงชมพู\\nพวงแสด\\nพ่วงพี\\nพวยน้ำ\\nพวยพุ่ง\\nพสกนิกร\\nพหุคูณ\\nพหุภาคี\\nพหูพจน์\\nพหูสูต\\nพอควร\\nพอใจ\\nพอใช้\\nพอใช้ได้\\nพอดี\\nพอตัว\\nพอทำเนา\\nพอประมาณ\\nพอเพียง\\nพอแรง\\nพอสมควร\\nพอเหมาะ\\nพ่อขุน\\nพ่อครัว\\nพ่อตา\\nพ่อบ้าน\\nพ่อพันธุ์\\nพ่อม่าย\\nพ่อเมือง\\nพ่อเลี้ยง\\nพ่อสื่อ\\nพอกพูน\\nพ้องพาน\\nพักผ่อน\\nพักพิง\\nพักฟื้น\\nพักร้อน\\nพักแรม\\nพัดยศ\\nพัดลม\\nพันพัว\\nพับฐาน\\nพับเพียบ\\nพัวพัน\\nพาซื่อ\\nพาดพิง\\nพิณพาทย์\\nพิธีกร\\nพิธีกรรม\\nพิธีการ\\nพิธีรีตอง\\nพิธีสาร\\nพินัยกรรม\\nพิมพ์เขียว\\nพิมพ์ใจ\\nพิมพ์ดีด\\nพิษสง\\nพี่น้อง\\nพี่เบิ้ม\\nพี่เลี้ยง\\nพึงใจ\\nพึงพอใจ\\nพึ่งพา\\nพึ่งพิง\\nพืชพันธุ์\\nพืชมงคล\\nพื้นฐาน\\nพื้นที่\\nพื้นบ้าน\\nพื้นเพ\\nพื้นเมือง\\nพื้นเสีย\\nพุพอง\\nพุทธกาล\\nพุทธคุณ\\nพุทธจักร\\nพุทธเจดีย์\\nพุทธฎีกา\\nพุทธปฏิมา\\nพุทธปฏิมากร\\nพุทธมามกะ\\nพุทธศักราช\\nพุทธศาสนิกชน\\nพุทธองค์\\nพุทธชาด\\nพุทธรักษา\\nพุ่มพวง\\nพุ่มไม้\\nพู่กัน\\nพูดจา\\nเพ่งเล็ง\\nเพดานบิน\\nเพดานปาก\\nเพริศพราย\\nเพริศพริ้ง\\nเพริศแพร้ว\\nเพรียกพร้อง\\nเพรียวลม\\nเพลงเชิด\\nเพลงยาว\\nเพลิงกัลป์\\nเพลินใจ\\nเพลินตา\\nเพลี่ยงพล้ำ\\nเพ้อฝัน\\nเพาะกาย\\nเพาะชำ\\nเพาะปลูก\\nเพิกถอน\\nเพิกเฉย\\nเพิ่มเติม\\nเพิ่มพูน\\nเพียงตา\\nเพียงพอ\\nเพียบแประ\\nเพียบพร้อม\\nเพื่อนเกลอ\\nเพื่อนตาย\\nเพื่อนบ้าน\\nเพื่อนฝูง\\nเพื่อนยาก\\nแพ้ท้อง\\nแพร่หลาย\\nแพร่งพราย\\nแพรวพราว\\nโพธิญาณ\\nโพธิบัลลังก์\\nโพธิสมภาร\\nโพธิสัตว์\\nโพ้นทะเล\\nโพยภัย\\nไพ่ตาย\\nไพ่ป๊อก\\nไพรวัน\\nไพรสณฑ์\\nไพรสัณฑ์\\nไพร่พล\\nไพร่ฟ้า\\nไพร่สม\\nไพร่ส่วย\\nไพร่หลวง\\nฟกช้ำ\\nฟองเต้าหู้\\nฟองน้ำ\\nฟองมัน\\nฟ้องกลับ\\nฟ้องร้อง\\nฟอนเฟะ\\nฟักทอง\\nฟัดเฟียด\\nฟันดาบ\\nฟันฝ่า\\nฟันแท้\\nฟันน้ำนม\\nฟันปลา\\nฟันฟาง\\nฟันเฟือง\\nฟันม้า\\nฟันเลื่อย\\nฟันหนู\\nฟั่นเฝือ\\nฟั่นเฟือน\\nฟื้นตัว\\nฟื้นฝอย\\nฟื้นฟู\\nฟุ้งซ่าน\\nฟุ้งเฟ้อ\\nฟุ้งเฟื่อง\\nฟุตบอล\\nฟูฟ่อง\\nฟูเฟื่อง\\nฟูมฟัก\\nฟูมฟาย\\nเฟะฟะ\\nเฟื่องฟ้า\\nเฟื่องฟุ้ง\\nเฟื่องฟู\\nไฟฉาย\\nไฟแช็ก\\nไฟธาตุ\\nไฟฟ้า\\nภัตกิจ\\nภาคทัณฑ์\\nภาคพื้น\\nภาคเรียน\\nภาคภูมิ\\nภาพถ่าย\\nภาพนิ่ง\\nภาพประกอบ\\nภาพพจน์\\nภาพยนตร์\\nภาพลวงตา\\nภาพลักษณ์\\nภายนอก\\nภายใน\\nภายหน้า\\nภายหลัง\\nภารกิจ\\nภารธุระ\\nภารโรง\\nภารตวิทยา\\nภาษาศาสตร์\\nภาสกร\\nภิญโญภาพ\\nภินชาติ\\nภูธร\\nภูธเรศ\\nภูบาล\\nภูเบศ\\nภูเบศวร์\\nภูเขา\\nภูเขาไฟ\\nภูผา\\nภูตคาม\\nภูตบดี\\nภูตรูป\\nภูเตศวร\\nภูมินทร์\\nภูมิบาล\\nภูมิประเทศ\\nภูมิภาค\\nภูมิรัฐศาสตร์\\nภูมิลำเนา\\nภูมิศาสตร์\\nภูมิอากาศ\\nภูมิธรรม\\nภูมิปัญญา\\nภูมิรู้\\nภูมิใจ\\nภูมิฐาน\\nภูมิคุ้มกัน\\nภูมิแพ้\\nภูษาโยง\\nเภทภัย\\nเภสัชกร\\nเภสัชกรรม\\nเภสัชวิทยา\\nเภสัชศาสตร์\\nโภคทรัพย์\\nโภคภัณฑ์\\nโภชนากร\\nโภชนาการ\\nมกุฎราชกุมาร\\nมงคลแฝด\\nมงคลสูตร\\nมงคลหัตถี\\nมณเฑียรบาล\\nมดดำ\\nมดแดง\\nมดเท็จ\\nมดยอบ\\nมดลูก\\nมธุปายาส\\nมธุรส\\nมนเทียรบาล\\nมนุษย์กบ\\nมโนกรรม\\nมโนคติ\\nมโนทุจริต\\nมโนธรรม\\nมโนภาพ\\nมโนมัย\\nมโนรถ\\nมโนรมย์\\nมโนสุจริต\\nมรรคนายก\\nมรรคผล\\nมฤคชาติ\\nมฤคทายวัน\\nมฤคราช\\nมลทิน\\nมลพิษ\\nมลสาร\\nมวกเหล็ก\\nม้วนหน้า\\nมวยไทย\\nมวยปล้ำ\\nมวยล้ม\\nมวยวัด\\nมวยสากล\\nมวยหมู่\\nมวลสาร\\nมอคราม\\nมอซอ\\nมอหมึก\\nมองเมียง\\nมอบตัว\\nมอบหมาย\\nมอมเมา\\nมะขามเทศ\\nมะขามป้อม\\nมะขามเปียก\\nมะเขือเทศ\\nมะเขือพวง\\nมะพร้าวแก้ว\\nมักคุ้น\\nมักจี่\\nมักง่าย\\nมักน้อย\\nมักมาก\\nมักใหญ่\\nมั่งคั่ง\\nมั่งมี\\nมัจจุราช\\nมัชฌิมนิกาย\\nมัชฌิมประเทศ\\nมัชฌิมยาม\\nมัชฌิมวัย\\nมัดจำ\\nมัดหมี่\\nมัธยมกาล\\nมัธยมศึกษา\\nมันแกว\\nมันเทศ\\nมันฝรั่ง\\nมันเปลว\\nมันสมอง\\nมั่นคง\\nมั่นใจ\\nมั่นหมาย\\nมั่นเหมาะ\\nมัวเมา\\nมัวหมอง\\nมั่วสุม\\nม้าเทศ\\nม้าน้ำ\\nม้ามืด\\nม้าเร็ว\\nม้าล่อ\\nม้าลาย\\nมากมาย\\nมาตรการ\\nมาตรฐาน\\nมาตราส่วน\\nมาตุคาม\\nมาตุฆาต\\nมาตุภูมิ\\nม่านตา\\nม่านบังตา\\nมายากร\\nมายากล\\nมายาการ\\nมายาวี\\nมารผจญ\\nมารวิชัย\\nมารสังคม\\nมารหัวขน\\nมาลาการ\\nมิ่งขวัญ\\nมิ่งมิตร\\nมิจฉาจาร\\nมิจฉาชีพ\\nมิดชิด\\nมิดเมี้ยน\\nมิดหมี\\nมิตรจิต\\nมิตรภาพ\\nมิตรสหาย\\nมิน่า\\nมีหน้า\\nมีดโกน\\nมีดดาบ\\nมีดโต้\\nมีดพก\\nมีดพับ\\nมีดสั้น\\nมึนงง\\nมึนชา\\nมึนตึง\\nมึนเมา\\nมืดครึ้ม\\nมืดมน\\nมืดมัว\\nมือจับ\\nมือดี\\nมือเติบ\\nมือปืน\\nมือเปล่า\\nมือมืด\\nมือสอง\\nมือเสือ\\nมือหนึ่ง\\nมือใหม่\\nมุกตลก\\nมุขปาฐะ\\nมุขมนตรี\\nมุ่งมั่น\\nมุ่งมาด\\nมุ่งหน้า\\nมุ่งหมาย\\nมุ่งหวัง\\nมุ้งลวด\\nมุ้งสายบัว\\nมุมก้ม\\nมุมกลับ\\nมุมเงย\\nมุมฉาก\\nมุมตรง\\nมุมป้าน\\nมุมมืด\\nมุมแย้ง\\nมุมสะท้อน\\nมุมหักเห\\nมุมแหลม\\nมุสาวาท\\nมูกเลือด\\nมูกมัน\\nมูกหลวง\\nมูนดิน\\nมูลฐาน\\nมูลนาย\\nมูลนิธิ\\nมูลเหตุ\\nมูลค่า\\nมูลฝอย\\nเม็ดเงิน\\nเม็ดเลือด\\nเม็ดโลหิต\\nเม่นทะเล\\nเมรุมาศ\\nเมรุราช\\nเมล์อากาศ\\nเมาดิบ\\nเมามัน\\nเมามัว\\nเมามาย\\nเมินเฉย\\nเมียน้อย\\nเมียหลวง\\nเมียงมอง\\nเมี่ยงลาว\\nเมี่ยงส้ม\\nเมื่อกี้\\nเมื่อตะกี้\\nเมื่อใด\\nเมื่อไร\\nเมื่อไหร่\\nเมื่อนั้น\\nเมืองขึ้น\\nเมืองท่า\\nเมืองนอก\\nเมืองหลวง\\nเมื่อยขบ\\nเมื่อยล้า\\nแม่กอง\\nแม่กุญแจ\\nแม่คุณ\\nแม่งาน\\nแม่เจ้า\\nแม่ชี\\nแม่ทัพ\\nแม่นม\\nแม่น้ำ\\nแม่บท\\nแม่บ้าน\\nแม่เบี้ย\\nแม่พระ\\nแม่พิมพ์\\nแม่เพลง\\nแม่มด\\nแม่ม่าย\\nแม่ไม้\\nแม่ยก\\nแม่ยาย\\nแม่ร้าง\\nแม่เรือน\\nแม่แรง\\nแม่เล้า\\nแม่เลี้ยง\\nแม่สี\\nแม่สื่อ\\nแม่เหล็ก\\nแมงมุม\\nแม่นยำ\\nแมลงช้าง\\nแมลงวัน\\nแมลงปอ\\nแมลงภู่\\nแมลงเม่า\\nแมวเซา\\nแมวน้ำ\\nแมวป่า\\nแมวมอง\\nไม้กลัด\\nไม้กวาด\\nไม้กางเขน\\nไม้เกาหลัง\\nไม้ขีดไฟ\\nไม้จิ้มฟัน\\nไม้เด็ด\\nไม้ตาย\\nไม้ตีพริก\\nไม้ที\\nไม้เท้า\\nไม้บรรทัด\\nไม้เมตร\\nไม้ระแนง\\nไม้เรียว\\nไม้หมอน\\nไม้อัด\\nไม้จัตวา\\nไม้ตรี\\nไม้ไต่คู้\\nไม้โท\\nไม้ผัด\\nไม้มลาย\\nไม้ม้วน\\nไม้ยมก\\nไม้หน้า\\nไม้หันอากาศ\\nไม้เอก\\nยกกลีบ\\nยกครู\\nยกเครื่อง\\nยกเค้า\\nยกทรง\\nยกฟ้อง\\nยกเมฆ\\nยกยอ\\nยกย่อง\\nยกเลิก\\nยกเว้น\\nย่นย่อ\\nยมทูต\\nยมบาล\\nยมราช\\nยมโลก\\nยวดยิ่ง\\nยวดยาน\\nยวนยี\\nยวบยาบ\\nย่อท้อ\\nย่อส่วน\\nย่อหน้า\\nย่อหย่อน\\nยอกย้อน\\nยองใย\\nย่องเบา\\nย่องแย่ง\\nยอดเยี่ยม\\nยอดอก\\nย้อนยอก\\nย้อนรอย\\nย้อนศร\\nย้อนแสง\\nย้อนหลัง\\nยอบแยบ\\nยอมความ\\nย่อมเยา\\nย่อยยับ\\nยักยอก\\nยักย้าย\\nยักเยื้อง\\nยัญกรรม\\nยัญพิธี\\nยัดเยียด\\nยับเยิน\\nยับยั้ง\\nยั่วยวน\\nยั่วยุ\\nยั่วเย้า\\nยากวาด\\nยากันยุง\\nยาเขียว\\nยาใจ\\nยาฉุน\\nยาชา\\nยาซัด\\nยาดอง\\nยาแดง\\nยาถ่าย\\nยาธาตุ\\nยานัตถุ์\\nยาเบื่อ\\nยาโป๊\\nยาแฝด\\nยาพิษ\\nยาระบาย\\nยาสลบ\\nยาสั่ง\\nยาสีฟัน\\nยาสูบ\\nยาเส้น\\nยาเสพติด\\nยาหม่อง\\nยาเหลือง\\nย่าทวด\\nย่านาง\\nยากแค้น\\nยากจน\\nยากเย็น\\nยากไร้\\nยางนอก\\nยางใน\\nยางมะตอย\\nยางมะตูม\\nยางลบ\\nยางสน\\nยางอาย\\nย่างกราย\\nย่างเยื้อง\\nย่างสด\\nย่างสามขุม\\nย่างเหยียบ\\nยานเกราะ\\nยานพาหนะ\\nยานอวกาศ\\nยานคาง\\nยายทวด\\nยาวเฟื้อย\\nยาวยืด\\nยาวเหยียด\\nยำทวาย\\nยำใหญ่\\nยำเกรง\\nยำเยง\\nย่ำต๊อก\\nย่ำยี\\nย่ำแย่\\nยิงเป้า\\nยิ่งนัก\\nยิ่งยวด\\nยิ่งใหญ่\\nยินดี\\nยินยอม\\nยินร้าย\\nยิ้มกริ่ม\\nยิ้มแฉ่ง\\nยิ้มแต้\\nยิ้มแป้น\\nยิ้มเผล่\\nยิ้มเยาะ\\nยิ้มแย้ม\\nยียวน\\nยึดครอง\\nยึดถือ\\nยึดมั่น\\nยึดเหนี่ยว\\nยืดยาด\\nยืดยาว\\nยืดเยื้อ\\nยืดหยุ่น\\nยืดอก\\nยืนกราน\\nยืนต้น\\nยืนพื้น\\nยืนยง\\nยืนยัน\\nยืนหยัด\\nยื้อยุด\\nยุยง\\nยุแยง\\nยุแหย่\\nยุคลบาท\\nยุคเข็ญ\\nยุคทอง\\nยุคมืด\\nยุ่งขิง\\nยุ่งยาก\\nยุ่งเหยิง\\nยุติธรรม\\nยุทธการ\\nยุทธนาวี\\nยุทธปัจจัย\\nยุทธภัณฑ์\\nยุทธภูมิ\\nยุทธวิธี\\nยุทธศาสตร์\\nยุทธหัตถี\\nยุทธนาการ\\nยุทธนาธิการ\\nยุบยับ\\nยุบยิบ\\nยุพราช\\nยู่ยี่\\nเย็นเจี๊ยบ\\nเย็นใจ\\nเย็นฉ่ำ\\nเย็นเฉียบ\\nเย็นชา\\nเย็นชืด\\nเย็นตา\\nเย็นเยียบ\\nเย็นเยือก\\nเย็นวาบ\\nเย็นวูบ\\nเย็บกี่\\nเย็บจักร\\nเย็บด้าย\\nเย้ยหยัน\\nเย้าหยอก\\nเยาะเย้ย\\nเยี่ยมกราย\\nเยี่ยมเยียน\\nเยี่ยมเยือน\\nเยี่ยมยอด\\nเยื่อเคย\\nเยื่อใย\\nเยือกเย็น\\nเยื้องกราย\\nเยื้องยัก\\nเยื้องย่าง\\nแยกย้าย\\nแยกแยะ\\nแย่งชิง\\nแยบคาย\\nแยบยล\\nแย้มพราย\\nแย้มยิ้ม\\nแย้มสรวล\\nโยเย\\nโย้เย้\\nโยกโคลง\\nโยกย้าย\\nโยกโย้\\nโยนกลอง\\nใยหิน\\nรกชัฏ\\nรกร้าง\\nรกเรี้ยว\\nรกเรื้อ\\nรกราก\\nรงควัตถุ\\nรชนีกร\\nรถกระบะ\\nรถเก๋ง\\nรถเข็น\\nรถแข่ง\\nรถจักร\\nรถจี๊ป\\nรถตู้\\nรถทัวร์\\nรถบรรทุก\\nรถพ่วง\\nรถพยาบาล\\nรถไฟ\\nรถไฟฟ้า\\nรถม้า\\nรถเมล์\\nรถยนต์\\nรถราง\\nรถลาก\\nรถสปอร์ต\\nรถสิบล้อ\\nรบกวน\\nรบรา\\nรบเร้า\\nรมดำ\\nร่มเกล้า\\nร่มชูชีพ\\nร่มเย็น\\nร่มรื่น\\nร่วงโรย\\nรวงผึ้ง\\nรวงรัง\\nรวดเร็ว\\nรวนเร\\nรวบยอด\\nรวบรวม\\nรวบรัด\\nรวมพล\\nรวมหัว\\nร่วมใจ\\nร่วมเพศ\\nร่วมมือ\\nร่วมรัก\\nร่วมสมัย\\nรวยริน\\nรวยรื่น\\nรสชาติ\\nรสนิยม\\nรองท้อง\\nรองเท้า\\nรองพื้น\\nร่องน้ำ\\nร่องรอย\\nร้องขอ\\nร้องทุกข์\\nร้องเรียน\\nร้องห่ม\\nร้องไห้\\nรองช้ำ\\nรองทรง\\nรอดชีวิต\\nรอดตัว\\nรอดตาย\\nรอนแรม\\nร่อนเร่\\nร้อนใจ\\nร้อนตัว\\nร้อนรน\\nร้อนรุ่ม\\nร้อนวิชา\\nร้อนอาสน์\\nรอบจัด\\nรอบเดือน\\nรอบรู้\\nรอยร้าว\\nร่อยหรอ\\nร้อยละ\\nร้อยกรอง\\nร้อยแก้ว\\nร้อยหวาย\\nระนาดทุ้ม\\nระนาดเอก\\nระเบิดขวด\\nระเบิดมือ\\nระเบียบการ\\nรักใคร่\\nรักษาการ\\nรักษาการณ์\\nรังไข่\\nรังแตน\\nรังนก\\nรังผึ้ง\\nรังเพลิง\\nรังมด\\nรังสรรค์\\nรังสฤษฏ์\\nรั้งรอ\\nรังสีแพทย์\\nรังสีวิทยา\\nรัชกาล\\nรัชทายาท\\nรัชนีกร\\nรัฐธรรมนูญ\\nรัฐบาล\\nรัฐบุรุษ\\nรัฐประศาสน์\\nรัฐประหาร\\nรัฐพิธี\\nรัฐมนตรี\\nรัฐวิสาหกิจ\\nรัฐศาสตร์\\nรัฐสภา\\nรัดกุม\\nรัดเกล้า\\nรัดตัว\\nรัดประคด\\nรัดรึง\\nรัดรูป\\nรัตติกาล\\nรับขวัญ\\nรับจ้าง\\nรับช่วง\\nรับใช้\\nรับซื้อ\\nรับทราบ\\nรับประกัน\\nรับประทาน\\nรับปาก\\nรับผิด\\nรับผิดชอบ\\nรับฟ้อง\\nรับฟัง\\nรับมือ\\nรับรอง\\nรับรู้\\nรับสมัคร\\nรับสั่ง\\nรับหน้า\\nรับเหมา\\nรั่วไหล\\nรามือ\\nร่าเริง\\nรากแก้ว\\nรากขวัญ\\nรากฐาน\\nรากฟัน\\nรากศัพท์\\nรากเหง้า\\nร่างกาย\\nร่างแห\\nร้างรา\\nราชกรณียกิจ\\nราชการ\\nราชกิจ\\nราชครู\\nราชฐาน\\nราชทัณฑ์\\nราชทินนาม\\nราชทูต\\nราชธานี\\nราชนาวี\\nราชบัณฑิต\\nราชบัลลังก์\\nราชบาตร\\nราชบุตร\\nราชปะแตน\\nราชภัฏ\\nราชมัล\\nราชยาน\\nราชรถ\\nราชลัญจกร\\nราชเลขาธิการ\\nราชเลขานุการ\\nราชวงศ์\\nราชวัติ\\nราชสกุล\\nราชสมบัติ\\nราชสาส์น\\nราชหัตถเลขา\\nราชองครักษ์\\nราชโองการ\\nราชาคณะ\\nราชาศัพท์\\nราชินีนาถ\\nร้านชำ\\nร้านรวง\\nราบคาบ\\nราบรื่น\\nราบเรียบ\\nรายการ\\nรายงาน\\nรายจ่าย\\nรายได้\\nรายทาง\\nรายรับ\\nรายล้อม\\nรายละเอียด\\nรายวิชา\\nร่ายยาว\\nร่ายรำ\\nร้ายกาจ\\nร้ายแรง\\nราวนม\\nราวป่า\\nร้าวฉาน\\nร้าวราน\\nรำพัด\\nรำแพน\\nรำวง\\nร่ำไป\\nร่ำร้อง\\nร่ำเรียน\\nร่ำไร\\nร่ำลา\\nร่ำไห้\\nริเริ่ม\\nริอ่าน\\nริมฝีปาก\\nริ้วรอย\\nรีบร้อน\\nรีบรุด\\nรีบเร่ง\\nรื่นรมย์\\nรื่นเริง\\nรื้อถอน\\nรื้อฟื้น\\nรุกฆาต\\nรุกราน\\nรุกล้ำ\\nรุกไล่\\nรุ่งขึ้น\\nรุ่งแจ้ง\\nรุ่งเช้า\\nรุ่งเรือง\\nรุ่งโรจน์\\nรุ่งสว่าง\\nรุ่งสาง\\nรุ่งอรุณ\\nรุจิเรข\\nรุดหน้า\\nรุนแรง\\nรุมเร้า\\nรุมล้อม\\nรุ่มรวย\\nรุ่มร้อน\\nรุ่ยร่าย\\nรู้แกว\\nรู้ความ\\nรู้คุณ\\nรู้งาน\\nรู้จัก\\nรู้แจ้ง\\nรู้ใจ\\nรู้เชิง\\nรู้ตัว\\nรู้ทัน\\nรู้เท่า\\nรู้เรื่อง\\nรู้สำนึก\\nรู้สึก\\nรู้เห็น\\nรูปการณ์\\nรูปโฉม\\nรูปฌาน\\nรูปถ่าย\\nรูปทรง\\nรูปธรรม\\nรูปแบบ\\nรูปพรรณ\\nรูปพรหม\\nรูปภพ\\nรูปภาพ\\nรูปร่าง\\nรูปสมบัติ\\nเร่ร่อน\\nเร่งด่วน\\nเร่งมือ\\nเร่งรัด\\nเร่งรีบ\\nเร่งเร้า\\nเร้นลับ\\nเร่อร่า\\nเร่าร้อน\\nเราะราย\\nเราะร้าย\\nเริงใจ\\nเริงรมย์\\nเริดร้าง\\nเริ่มต้น\\nเริ่มแรก\\nเรี่ยราด\\nเรี่ยไร\\nเรียกคืน\\nเรียกตัว\\nเรียกร้อง\\nเรียกหา\\nเรียบร้อย\\nเรียงความ\\nเรียงตัว\\nเรียงเบอร์\\nเรียงพิมพ์\\nเรียงเม็ด\\nเรียงราย\\nเรียนรู้\\nเรียบร้อย\\nเรียบเรียง\\nเรียบวุธ\\nเรี่ยมเร้\\nเรี่ยวแรง\\nเรือกลไฟ\\nเรือกอและ\\nเรือกำปั่น\\nเรือจ้าง\\nเรือดำน้ำ\\nเรือโดยสาร\\nเรือตรวจการณ์\\nเรือตังเก\\nเรือธง\\nเรือนำร่อง\\nเรือบด\\nเรือบิน\\nเรือใบ\\nเรือประมง\\nเรือพ่วง\\nเรือพิฆาต\\nเรือยนต์\\nเรือยาว\\nเรือโยง\\nเรือรบ\\nเรือลากจูง\\nเรือสำปั้น\\nเรือสำเภา\\nเรือหลวง\\nเรือหางยาว\\nเรืออีโปง\\nเรือเอี้ยมจุ๊น\\nเรื้อรัง\\nเรือกสวน\\nเรืองนาม\\nเรืองรอง\\nเรืองแสง\\nเรื่องราว\\nเรื่องสั้น\\nเรือนแก้ว\\nเรือนจำ\\nเรือนเบี้ย\\nเรือนแพ\\nเรือนหอ\\nเรื่อยเจื้อย\\nเรื่อยเฉื่อย\\nเรื่อยเปื่อย\\nแรเงา\\nแรกนา\\nแรกนาขวัญ\\nแรงงาน\\nแรงดึงดูด\\nแรงเทียน\\nแรงม้า\\nแรงเหวี่ยง\\nแรมรอน\\nแรมรา\\nแรมโรย\\nโรคจิต\\nโรงครัว\\nโรงงาน\\nโรงเจ\\nโรงเตี๊ยม\\nโรงทาน\\nโรงนา\\nโรงพยาบาล\\nโรงพัก\\nโรงพิมพ์\\nโรงเรียน\\nโรงเรือน\\nโรงแรม\\nโรงเลี้ยง\\nโรงเลื่อย\\nโรงสี\\nโรงสีข้าว\\nโรงอาหาร\\nโรมรัน\\nโรยรา\\nฤชากร\\nฤดูกาล\\nลงขัน\\nลงแขก\\nลงคอ\\nลงตัว\\nลงท้าย\\nลงทุน\\nลงโทษ\\nลงพุง\\nลงมือ\\nลงรัก\\nลงรอย\\nลงแรง\\nลงโรง\\nลงเอย\\nลดตัว\\nลดละ\\nลดเลี้ยว\\nลดหย่อน\\nลดหลั่น\\nลนลาน\\nล้นพ้น\\nล้นหลาม\\nล้นเหลือ\\nลบล้าง\\nลบเลือน\\nลบหลู่\\nลมกรด\\nลมค้า\\nลมงวง\\nลมแดด\\nลมทะเล\\nลมบก\\nลมบน\\nลมบ้าหมู\\nลมปราณ\\nลมปาก\\nลมพิษ\\nลมว่าว\\nลมเสีย\\nลมหนาว\\nลมหายใจ\\nล่มจม\\nล่มสลาย\\nล้มละลาย\\nล้มลุก\\nล้มเลิก\\nล่วงเกิน\\nล่วงรู้\\nล่วงละเมิด\\nล่วงลับ\\nล่วงล้ำ\\nล่วงเลย\\nล่วงหน้า\\nลวดลาย\\nลวดสปริง\\nลวดหนาม\\nล้วนแล้ว\\nลหุโทษ\\nล่อลวง\\nล่อหลอก\\nล่อแหลม\\nล้อต๊อก\\nล้อเลื่อน\\nล้อเล่น\\nล้อเลียน\\nล้อหลอก\\nลองเชิง\\nลองดี\\nลองภูมิ\\nล่องหน\\nลอดช่อง\\nล่อนจ้อน\\nลอบกัด\\nล้อมวง\\nลอยแก้ว\\nลอยชาย\\nลอยตัว\\nลอยนวล\\nลอยแพ\\nลอยลำ\\nละทิ้ง\\nละเลย\\nละเว้น\\nละครนอก\\nละครใน\\nละครเพลง\\nละครร้อง\\nละครรำ\\nละครลิง\\nละครสัตว์\\nละเอียดอ่อน\\nลักไก่\\nลักพา\\nลักเพศ\\nลักยิ้ม\\nลักลอบ\\nลักลั่น\\nลักหลับ\\nลัดเลาะ\\nลับตา\\nลับแล\\nลับหลัง\\nลาออก\\nล่าช้า\\nล่าทัพ\\nล้าสมัย\\nล้าหลัง\\nลากข้าง\\nล้างบาง\\nล้างผลาญ\\nลาดเขา\\nลาดตระเวน\\nลาดเท\\nลาดยาง\\nลานบิน\\nลาภปาก\\nลาภลอย\\nลามปาม\\nลามเลีย\\nลายคราม\\nลายเซ็น\\nลายแทง\\nลายน้ำ\\nลายพร้อย\\nลายมือ\\nลายลักษณ์\\nลายเส้น\\nลำกล้อง\\nลำแข้ง\\nลำธาร\\nลำแสง\\nลำไส้\\nลำตัด\\nลำนำ\\nล่ำสัน\\nล้ำยุค\\nล้ำสมัย\\nล้ำลึก\\nล้ำเลิศ\\nล้ำเส้น\\nล้ำหน้า\\nลิงจุ่น\\nลิงลม\\nลิงโลด\\nลิดรอน\\nลิ้นไก่\\nลิ้นชัก\\nลิ้นปี่\\nลิ้นควาย\\nลิ้นงูเห่า\\nลิ้นหมา\\nลิบลับ\\nลิบลิ่ว\\nลิ่มเลือด\\nลี้ภัย\\nลี้ลับ\\nลึกซึ้ง\\nลึกลับ\\nลึกล้ำ\\nลืมตน\\nลืมต้น\\nลืมตัว\\nลืมตา\\nลืมเลือน\\nลือชา\\nลือชื่อ\\nลือลั่น\\nลุล่วง\\nลุกลน\\nลุกลาม\\nลุกลี้ลุกลน\\nลุกฮือ\\nลุ่มน้ำ\\nลุ่มลึก\\nลุ่มหลง\\nลุ่ทาง\\nลูกกรง\\nลูกกรอก\\nลูกกรุง\\nลูกกลอน\\nลูกกลิ้ง\\nลูกกวาด\\nลูกกะจ๊อก\\nลูกกุญแจ\\nลูกเกด\\nลูกแก้ว\\nลูกขนไก่\\nลูกข่าง\\nลูกขุน\\nลูกเขย\\nลูกครึ่ง\\nลูกคลื่น\\nลูกความ\\nลูกคอ\\nลูกค้า\\nลูกคิด\\nลูกคู่\\nลูกจ้าง\\nลูกช้าง\\nลูกชิด\\nลูกชิ้น\\nลูกชุบ\\nลูกซอง\\nลูกโซ่\\nลูกดอก\\nลูกดิ่ง\\nลูกตะกั่ว\\nลูกตุ้ม\\nลูกเต้า\\nลูกเต๋า\\nลูกถ้วย\\nลูกทุ่ง\\nลูกเธอ\\nลูกน้อง\\nลูกน้ำ\\nลูกนิมิต\\nลูกบอล\\nลูกบ้าน\\nลูกบาศก์\\nลูกบิด\\nลูกเบี้ยว\\nลูกประคบ\\nลูกประคำ\\nลูกปัด\\nลูกปืน\\nลูกโป่ง\\nลูกผสม\\nลูกผู้ชาย\\nลูกผู้หญิง\\nลูกพรรค\\nลูกพี่\\nลูกฟูก\\nลูกไฟ\\nลูกมือ\\nลูกโม่\\nลูกไม้\\nลูกยาเธอ\\nลูกรอก\\nลูกรัง\\nลูกเรือ\\nลูกล้อ\\nลูกลอย\\nลูกเล่น\\nลูกเลี้ยง\\nลูกโลก\\nลูกวัด\\nลูกศร\\nลูกศิษย์\\nลูกสมุน\\nลูกสะใภ้\\nลูกสูบ\\nลูกเสือ\\nลูกหนัง\\nลูกหนี้\\nลูกหนู\\nลูกหมาก\\nลูกหลง\\nลูกหลาน\\nลูกหาบ\\nลูกหิน\\nลูกเห็บ\\nลูกเหม็น\\nลูกแหง่\\nลูกอม\\nลูกหม้อ\\nลูบคม\\nลูบคลำ\\nลูบไล้\\nเล็กน้อย\\nเลขคณิต\\nเลขผา\\nเลขหมาย\\nเล็ดลอด\\nเล่นงาน\\nเล่นแง่\\nเล่นชู้\\nเล่นตัว\\nเล่นลิ้น\\nเล่นหัว\\nเลนส์นูน\\nเลนส์เว้า\\nเล็บครุฑ\\nเลยเถิด\\nเลศนัย\\nเล่ห์กล\\nเล่ห์เหลี่ยม\\nเลอโฉม\\nเลอมาน\\nเลอเลิศ\\nเลอสรวง\\nเล่อล่า\\nเลอะเลือน\\nเล่าเรียน\\nเล่าลือ\\nเลาะลัด\\nเลิกรา\\nเลิกร้าง\\nเลิกล้ม\\nเลิศเลอ\\nเลี้ยงชีพ\\nเลี้ยงดู\\nเลี้ยงต้อย\\nเลียบเคียง\\nเลี้ยวลด\\nเลือกตั้ง\\nเลือกเฟ้น\\nเลือกสรร\\nเลื่องลือ\\nเลือดกำเดา\\nเลือดเนื้อ\\nเลือดฝาด\\nเลือดเย็น\\nเลือดร้อน\\nเลือดหมู\\nเลือดอุ่น\\nเลือนราง\\nเลื่อนเปื้อน\\nเลื่อนลอย\\nเลื่อมพราย\\nเลื่อมใส\\nเลื่อยฉลุ\\nเลื่อยลันดา\\nเลื่อยวงเดือน\\nเลื้อยคลาน\\nแลเหลียว\\nแลกเปลี่ยน\\nแล้วกัน\\nและเล็ม\\nโล่งใจ\\nโล่งโถง\\nโล่งอก\\nโลดเต้น\\nโลดโผน\\nโลดลิ่ว\\nโลดแล่น\\nไล่ที่\\nไล่เบี้ย\\nไล่เลี่ย\\nไล่เลียง\\nไล่หลัง\\nไล่ออก\\nวกวน\\nวงกบ\\nวงกลม\\nวงการ\\nวงแขน\\nวงเงิน\\nวงจร\\nวงนอก\\nวงใน\\nวงรี\\nวงเล็บ\\nวงเวียน\\nวงแหวน\\nวงศ์วาน\\nวจีกรรม\\nวจีเภท\\nวจีภาค\\nวนเวียน\\nวอดวาย\\nว็อบแว็บ\\nวังวน\\nวังหน้า\\nวังหลวง\\nวังหลัง\\nวัดราษฎร์\\nวัดวา\\nวัดหลวง\\nวัดผล\\nวัดพื้น\\nวัตถุนิยม\\nวัตถุประสงค์\\nวัตรปฏิบัติ\\nวันโกน\\nวันพระ\\nวันเพ็ญ\\nวัยรุ่น\\nวัยวุฒิ\\nว่ากล่าว\\nว่าจ้าง\\nว่าด้วย\\nว่าที่\\nวางก้าม\\nวางใจ\\nวางตัว\\nวางตา\\nวางโต\\nวางท่า\\nวางมวย\\nวางมาด\\nวางมือ\\nวางวาย\\nว่างเปล่า\\nว่างเว้น\\nวาดเขียน\\nว่านเครือ\\nวาบหวาม\\nวายชนม์\\nวายปราณ\\nวายวาง\\nวายวอด\\nวายร้าย\\nวายุภักษ์\\nวาววับ\\nวาววาม\\nวาวแวว\\nวาวแสง\\nวิกฤตการณ์\\nวิกฤติการณ์\\nวิกฤตกาล\\nวิกฤติกาล\\nวิกลจริต\\nวิงเวียน\\nวิ่งเต้น\\nวิ่งผลัด\\nวิ่งรอก\\nวิ่งราว\\nวิจิตรศิลป์\\nวิชาการ\\nวิชาชีพ\\nวิชาธร\\nวิญญูชน\\nวิดพื้น\\nวิตกจริต\\nวิถีทาง\\nวิทยากร\\nวิทยากล\\nวิทยาการ\\nวิทยาเขต\\nวิทยาทาน\\nวิทยาธร\\nวิทยานิพนธ์\\nวิทยาศาสตร์\\nวิเทศสัมพันธ์\\nวิธีการ\\nวินัยธร\\nวินัยปิฎก\\nวินาศกรรม\\nวินาศภัย\\nวินาศสันตะโร\\nวิภัชพยากรณ์\\nวิภัชวาที\\nวิไลวรรณ\\nวิสัญญีแพทย์\\nวิสัญญีภาพ\\nวิสัญญีวิทยา\\nวุฒิบัตร\\nวุฒิสภา\\nวุฒิสมาชิก\\nวุ่นวาย\\nวุ้นเส้น\\nวูบวาบ\\nเวจกุฎี\\nเวจมรรค\\nเวชกรรม\\nเวชภัณฑ์\\nเวชศาสตร์\\nเวทมนตร์\\nเวนคืน\\nเวรกรรม\\nเวฬุการ\\nเวฬุวัน\\nเว้าวอน\\nเวิ้งว้าง\\nเวียงวัง\\nเวียนเทียน\\nแว้งกัด\\nแวดล้อม\\nแวดวง\\nแว่นขยาย\\nแว่นแคว้น\\nแว่นตา\\nแวบวับ\\nแววตา\\nแวววาม\\nแวววาว\\nแวะเวียน\\nโวยวาย\\nไวไฟ\\nไว้ใจ\\nไว้ชื่อ\\nไว้ตัว\\nไว้ทุกข์\\nไว้ลาย\\nไว้หน้า\\nไว้อาลัย\\nศนิวาร\\nศอกกลับ\\nศอกกำ\\nศอกกำมา\\nศักดิ์ศรี\\nศักดิ์สิทธิ์\\nศารทวิษุวัติ\\nศาลแขวง\\nศาลจังหวัด\\nศาลชั้นต้น\\nศาลฎีกา\\nศาลเตี้ย\\nศาลทหาร\\nศาลปกครอง\\nศาลพระภูมิ\\nศาลเพียงตา\\nศาลแพ่ง\\nศาลรัฐธรรมนูญ\\nศาลแรงงาน\\nศาลล้มละลาย\\nศาลโลก\\nศาลสูง\\nศาลสูงสุด\\nศาลอาญา\\nศาลอุทธรณ์\\nศาลากลาง\\nศาลาดิน\\nศาลาราย\\nศาลาวัด\\nศิลาฤกษ์\\nศิลาแลง\\nศิษย์เก่า\\nศิษย์เอก\\nศีลจุ่ม\\nศีลธรรม\\nศีลวัต\\nศีลอด\\nศูนย์กลาง\\nศูนย์การค้า\\nศูนย์ถ่วง\\nศูนย์สูตร\\nศูนย์หน้า\\nเศร้าใจ\\nเศร้าโศก\\nเศร้าสร้อย\\nเศร้าสลด\\nเศร้าหมอง\\nเศวตฉัตร\\nเศษเกิน\\nเศษซ้อน\\nเศษวรรค\\nเศษส่วน\\nเศษเหล็ก\\nโศกนาฏกรรม\\nโศกศัลย์\\nโศกเศร้า\\nโศกสลด\\nสกลโลก\\nส่งเดช\\nส่งท้าย\\nส่งเสริม\\nส่งเสีย\\nส่งเสียง\\nสงบเงียบ\\nสงบเสงี่ยม\\nสง่างาม\\nสง่าราศี\\nสดชื่น\\nสดใส\\nสตรีเพศ\\nสติปัญญา\\nสถลมารค\\nสถานกงสุล\\nสถานที่\\nสถานทูต\\nสถานการณ์\\nสถานภาพ\\nสถิติศาสตร์\\nสนตะพาย\\nสนใจ\\nส้นตีน\\nสนธิสัญญา\\nสนนราคา\\nสนับแข้ง\\nสนับเพลา\\nสนับมือ\\nสนามบิน\\nสนามเพลาะ\\nสนิทสนม\\nสนิมขุม\\nสนิมสร้อย\\nสนุกสนาน\\nสบประมาท\\nสบายใจ\\nสภาพธรรม\\nสมควร\\nสมจริง\\nสมใจ\\nสมนัย\\nสมน้ำหน้า\\nสมประกอบ\\nสมส่วน\\nสมหวัง\\nสมคบ\\nสมทบ\\nสมยอม\\nสมรัก\\nสมรู้\\nสมสู่\\nส้มฉุน\\nส้มตำ\\nส้มลิ้ม\\nส้มกุ้ง\\nส้มเช้า\\nสมญานาม\\nสมมติฐาน\\nสมมุติฐาน\\nสมมติเทพ\\nสมรภูมิ\\nสมัครใจ\\nสมัยนิยม\\nสมุทรศาสตร์\\nสมุทรเสนา\\nสยดสยอง\\nสยองขวัญ\\nสยามรัฐ\\nสรรหา\\nสรวมชีพ\\nสรวลเส\\nสร้อยเศร้า\\nสร้างสรรค์\\nสร้างเสริม\\nสลดใจ\\nสลบไสล\\nสละสลวย\\nสลาเหิน\\nสลากภัต\\nสวนครัว\\nสวนป่า\\nสวนสนุก\\nสวนหย่อม\\nส่วนกลาง\\nส่วนเกิน\\nส่วนตัว\\nส่วนบุญ\\nส่วนแบ่ง\\nส่วนประกอบ\\nส่วนพระองค์\\nส่วนผสม\\nส่วนรวม\\nส่วนร่วม\\nส่วนลด\\nส่วนสัด\\nสวมกอด\\nสวมเขา\\nสวมรอย\\nสวยมภู\\nสว่างไสว\\nสวามิภักดิ์\\nสวิงสวาย\\nสสารนิยม\\nส่อเสียด\\nสอดคล้อง\\nสอดแทรก\\nสอดแนม\\nสอบถาม\\nสอบทาน\\nสอบไล่\\nสอบสวน\\nส้อมเสียง\\nสะสวย\\nสะแกวัลย์\\nสะแกแสง\\nสะใจ\\nสะเด็ดยาด\\nสะเทือนใจ\\nสะบัดช่อ\\nสั่งสม\\nสั่งสอน\\nสั่งเสีย\\nสังเกตการณ์\\nสังคมนิยม\\nสังคมวิทยา\\nสังคมศาสตร์\\nสังคมศึกษา\\nสังคมสงเคราะห์\\nสัญญาบัตร\\nสัดส่วน\\nสัตการ\\nสัตบุรุษ\\nสัตบริภัณฑ์\\nสัตภัณฑ์\\nสัตมหาสถาน\\nสัตโลหะ\\nสันเขา\\nสันดอน\\nสันหลัง\\nสั่นเทา\\nสั่นเทิ้ม\\nสันติบาล\\nสันติภาพ\\nสันติวิธี\\nสันติสุข\\nสับเปลี่ยน\\nสับสน\\nสับหลีก\\nสับหว่าง\\nสัมมาคารวะ\\nสัมมาชีพ\\nส่าเหล้า\\nสากกะเบือ\\nสาทิสลักษณ์\\nสาธุการ\\nสาธุชน\\nสาบเสือ\\nสาปสรร\\nสาปแช่ง\\nสาปส่ง\\nสามง่าม\\nสามล้อ\\nสามเหลี่ยม\\nสามเวท\\nสามัญชน\\nสามัญสำนึก\\nสายดิ่ง\\nสายดิน\\nสายตรวจ\\nสายน้ำ\\nสายบัว\\nสายพาน\\nสายฟ้า\\nสายยาง\\nสายยู\\nสายใย\\nสายรก\\nสายรุ้ง\\nสายล่อฟ้า\\nสายลับ\\nสายเลือด\\nสายโลหิต\\nสายวัด\\nสายส่ง\\nสายสวาท\\nสายสะดือ\\nสายสะพาย\\nสายสัมพันธ์\\nสายสิญจน์\\nสายสืบ\\nสายไหม\\nสายอากาศ\\nสายตา\\nสายหยุด\\nสารตรา\\nสารประกอบ\\nสารละลาย\\nสารส้ม\\nสารหนู\\nสารทฤดู\\nสาวใช้\\nสาวน้อย\\nสาวใหญ่\\nสำนักงาน\\nสำนักพิมพ์\\nสำนักสงฆ์\\nสำมะโนครัว\\nสำเร็จรูป\\nสิกขาบท\\nสิงสถิต\\nสิงสู่\\nสิ่งก่อสร้าง\\nสิ่งของ\\nสิ่งปฏิกูล\\nสิ่งพิมพ์\\nสิ่งแวดล้อม\\nสิ่งศักดิ์สิทธิ์\\nสิทธิกร\\nสิทธิ์ขาด\\nสิทธิชัย\\nสิทธิโชค\\nสิทธิบัตร\\nสินค้า\\nสินจ้าง\\nสินเชื่อ\\nสินไถ่\\nสินทรัพย์\\nสินน้ำใจ\\nสินบน\\nสินแร่\\nสินสมรส\\nสินสอด\\nสินไหม\\nสิ้นเชิง\\nสิ้นสุด\\nสีผึ้ง\\nสีลม\\nสีชอล์ก\\nสีถ่าน\\nสีเทียน\\nสีน้ำ\\nสีน้ำมัน\\nสีโปสเตอร์\\nสีฝุ่น\\nสี่เหลี่ยม\\nสีหน้า\\nสึกหรอ\\nสืบทอด\\nสืบค้น\\nสืบสวน\\nสืบสาว\\nสืบเสาะ\\nสื่อผสม\\nสื่อมวลชน\\nสื่อสาร\\nสุกงอม\\nสุกดิบ\\nสุกปลั่ง\\nสุกใส\\nสุขนาฏกรรม\\nสุขภัณฑ์\\nสุขภาพ\\nสุขลักษณะ\\nสุขวิทยา\\nสุขศาลา\\nสุขศึกษา\\nสุดท้าย\\nสุตกวี\\nสุนทรพจน์\\nสุภาพชน\\nสู่ขอ\\nสู่รู้\\nสู่สม\\nสูงส่ง\\nสูญเปล่า\\nสูญสิ้น\\nสูญเสีย\\nสูญหาย\\nเสสรวล\\nเสแสร้ง\\nเสกสรร\\nเสถียรภาพ\\nเส้นชัย\\nเส้นตรง\\nเส้นตาย\\nเส้นทาง\\nเส้นใย\\nเส้นรุ้ง\\nเส้นเลือด\\nเส้นแวง\\nเส้นสาย\\nเส้นเสียง\\nเส้นหมี่\\nเส้นเอ็น\\nเสบียงกรัง\\nเสมอภาค\\nเสมอหน้า\\nเสมอเหมือน\\nเสมียนตรา\\nเสร็จสรรพ\\nเสร็จสิ้น\\nเสริมส่ง\\nเสริมสร้าง\\nเสริมสวย\\nเสรีไทย\\nเสรีธรรม\\nเสรีนิยม\\nเสรีภาพ\\nเสาเข็ม\\nเสาธง\\nเสียใจ\\nเสียเชิง\\nเสียดาย\\nเสียที\\nเสียเที่ยว\\nเสียเปรียบ\\nเสียเปล่า\\nเสียรู้\\nเสียแรง\\nเสียสละ\\nเสียหลัก\\nเสียหาย\\nเสี่ยงทาย\\nเสียดแทง\\nเสียดแทรก\\nเสียดสี\\nเสี้ยนศึก\\nเสี้ยนหนาม\\nเสี้ยมสอน\\nเสียวซ่าน\\nเสียวไส้\\nเสือดาว\\nเสือดำ\\nเสือปลา\\nเสือป่า\\nเสือไฟ\\nเสื่อกก\\nเสื่อกระจูด\\nเสื่อน้ำมัน\\nเสื่อลำแพน\\nเสื้อกล้าม\\nเสื้อกั๊ก\\nเสื้อเกราะ\\nเสื้อครุย\\nเสื้อแสง\\nเสื้อเมือง\\nเสือกคลาน\\nเสือกสน\\nเสือกไส\\nเสื่อมคลาย\\nเสื่อมถอย\\nเสื่อมทราม\\nเสื่อมโทรม\\nเสื่อมสลาย\\nเสื่อมสูญ\\nเสื่อมเสีย\\nเสือหมอบ\\nแสกหน้า\\nแสดงออก\\nแสเถา\\nแสนกล\\nแสนรู้\\nแสร้งว่า\\nใส่ความ\\nใส่ไคล้\\nใส่ใจ\\nใส่ไฟ\\nไส้กรอก\\nไส้ไก่\\nไส้ติ่ง\\nไส้ศึก\\nไส้อั่ว\\nไส้เดือน\\nไส้ตัน\\nไสยเวท\\nไสยศาสตร์\\nหกล้ม\\nหงส์หยก\\nหงอนไก่\\nหงอยก๋อย\\nหงอยเหงา\\nหงายท้อง\\nหงายหลัง\\nหงำเหงอะ\\nหงำเหงือก\\nหดหาย\\nหดหู่\\nหนทาง\\nหนวกหู\\nหน่วงเหนี่ยว\\nหน่วยก้าน\\nหน่อไม้\\nหนองใน\\nหนองแซง\\nหนักข้อ\\nหนักใจ\\nหนักแน่น\\nหนักหน่วง\\nหนักหนา\\nหนังกลับ\\nหนังตะลุง\\nหนังเรียด\\nหนังสด\\nหนังใหญ่\\nหนังสือพิมพ์\\nหนาแน่น\\nหน้ากระดาน\\nหน้ากาก\\nหน้ากาฬ\\nหน้าแข้ง\\nหน้าจั่ว\\nหน้าฉาน\\nหน้าตัก\\nหน้าตา\\nหน้าต่าง\\nหน้าท้อง\\nหน้าทับ\\nหน้าที่\\nหน้าที่นั่ง\\nหน้าบัน\\nหน้าปัด\\nหน้าผา\\nหน้าผาก\\nหน้าม้า\\nหน้ามุข\\nหน้าไม้\\nหน้าเลือด\\nหน้าอก\\nหนามเตย\\nหน่ายหนี\\nหน่ายแหนง\\nหนาวเหน็บ\\nหนำใจ\\nหนี้สิน\\nหนี้สูญ\\nหนุนเนื่อง\\nหนุนหลัง\\nหมกมุ่น\\nหมดจด\\nหมอขวัญ\\nหมอความ\\nหมอแคน\\nหมองู\\nหมอดู\\nหมอตำแย\\nหมอทำขวัญ\\nหมอนวด\\nหมอผี\\nหมอยา\\nหมอลำ\\nหมอเสน่ห์\\nหม้อแกง\\nหม้อตาล\\nหม้อน้ำ\\nหม้อแปลง\\nหมองใจ\\nหมองมัว\\nหมองหม่น\\nหมองหมาง\\nหมอนขวาน\\nหมอนข้าง\\nหมอนทอง\\nหม่อมเจ้า\\nหม่อมฉัน\\nหม่อมราชวงศ์\\nหม่อมหลวง\\nหม่อมห้าม\\nหมั่นไส้\\nหมาป่า\\nหมาหมู่\\nหมากฝรั่ง\\nหมากสง\\nหมากหอม\\nหมากเก็บ\\nหมากรุก\\nหมากเม่า\\nหมางใจ\\nหมางเมิน\\nหมาไม้\\nหมายเกณฑ์\\nหมายขัง\\nหมายค้น\\nหมายความ\\nหมายจับ\\nหมายใจ\\nหมายตา\\nหมายปล่อย\\nหมายมั่น\\nหมายเรียก\\nหมายเลข\\nหมายเหตุ\\nหมิ่นเหม่\\nหมึกจีน\\nหมุนเวียน\\nหมูแดง\\nหมูป่า\\nหมูแผ่น\\nหมูยอ\\nหมูหย็อง\\nหมูหัน\\nหมูแฮม\\nหมู่บ้าน\\nหยดย้อย\\nหยอกเย้า\\nหยักรั้ง\\nหยักศก\\nหยั่งทราบ\\nหยั่งรู้\\nหยั่งเสียง\\nหยาบคาย\\nหยาบช้า\\nหยาบโลน\\nหยาบหยาม\\nหยิบมือ\\nหยิบยก\\nหยิบยืม\\nหยิบหย่ง\\nหยิบโหย่ง\\nหริรักษ์\\nหริวงศ์\\nหลงผิด\\nหลบฉาก\\nหลบมุม\\nหลวงจีน\\nหลวงพ่อ\\nหลวมตัว\\nหล่อลื่น\\nหล่อเลี้ยง\\nหล่อหลอม\\nหลอกลวง\\nหลอกล่อ\\nหลอกล้อ\\nหลอดลม\\nหลอดเลือด\\nหลอดอาหาร\\nหลอมตัว\\nหลอมเหลว\\nหลักการ\\nหลักเกณฑ์\\nหลักชัย\\nหลักฐาน\\nหลักทรัพย์\\nหลักเมือง\\nหลักลอย\\nหลักสูตร\\nหลักแหล่ง\\nหลักแหลม\\nหลังคา\\nหลังเต่า\\nหลั่งไหล\\nหลับนก\\nหลับใน\\nหลากใจ\\nหลากหลาย\\nหลาบจำ\\nหลายหลาก\\nหลายแหล่\\nหลุดพ้น\\nหลุดลอย\\nหลุดลุ่ย\\nหลุมโจน\\nหลุมพราง\\nหวงก้าง\\nหวงห้าม\\nหวงแหน\\nห่วงใย\\nห้วงน้ำ\\nหวังใจ\\nหวังดี\\nหวั่นกลัว\\nหวั่นเกรง\\nหวั่นใจ\\nหวั่นวิตก\\nหวั่นหวาด\\nหวั่นไหว\\nหวาดกลัว\\nหวาดเกรง\\nหวาดผวา\\nหวาดเสียว\\nหวาดหวั่น\\nหวาดไหว\\nหวานเย็น\\nหว่านล้อม\\nหอคอย\\nหอคำ\\nหอฉัน\\nหอไตร\\nหอประชุม\\nหอพัก\\nห่อหมก\\nห่อเหี่ยว\\nหอกซัด\\nห้องเครื่อง\\nห้องชุด\\nห้องแถว\\nห้องโถง\\nห้องน้ำ\\nห้องสมุด\\nหอสมุด\\nหอมหวน\\nห้อมล้อม\\nห้อยโหน\\nหักล้าง\\nหักหาญ\\nหักห้าม\\nหักเห\\nหักโหม\\nหักมุก\\nหันเห\\nหับเผย\\nหัวขโมย\\nหัวข้อ\\nหัวขั้ว\\nหัวเข่า\\nหัวโขน\\nหัวคะแนน\\nหัวค่ำ\\nหัวคิด\\nหัวจุก\\nหัวโจก\\nหัวใจ\\nหัวเทียน\\nหัวนม\\nหัวนอน\\nหัวป่า\\nหัวมุม\\nหัวเรื่อง\\nหัวแร้ง\\nหัวใส\\nหัวหน้า\\nหัวหน่าว\\nหัวหอก\\nหัวเห็ด\\nหัวไหล่\\nหัวอก\\nหัสดนตรี\\nหัสนาฏกรรม\\nหัสนิยาย\\nหัสดีลิงค์\\nหางเครื่อง\\nหางแถว\\nหางเลข\\nหางว่าว\\nหางเสียง\\nหางเสือ\\nห่างเหิน\\nหาบเร่\\nห้ามปราม\\nห้ามล้อ\\nหายตัว\\nหาวนอน\\nห้าวหาญ\\nห้ำหั่น\\nหินงอก\\nหินทราย\\nหินปูน\\nหินย้อย\\nหินอ่อน\\nหินชาติ\\nหินยาน\\nหีบเพลง\\nหีบห่อ\\nหุ่นกระบอก\\nหุ่นยนต์\\nหุ้นลม\\nหุ้นส่วน\\nหุบเขา\\nหุบผา\\nหุบเหว\\nหูกระต่าย\\nหูช้าง\\nหูรูด\\nหูกวาง\\nเหงาหงอย\\nเหงื่อกาฬ\\nเหตุการณ์\\nเหตุผล\\nเห็นแก่\\nเห็นใจ\\nเหน็บแนม\\nเหน็บชา\\nเหนียวแน่น\\nเหนี่ยวนำ\\nเหนี่ยวรั้ง\\nเหนื่อยหน่าย\\nเหมาะเจาะ\\nเหมาะสม\\nเหมาะเหม็ง\\nเหยเก\\nเหยียดหยาม\\nเหล็กกล้า\\nเหล็กจาร\\nเหล็กใน\\nเหล็กส่ง\\nเหล็กเส้น\\nเหล็กหล่อ\\nเหล็กไหล\\nเหลวแหลก\\nเหลวไหล\\nเหลอหลา\\nเหล่ากอ\\nเหลียวแล\\nเหลือเกิน\\nเหลือขอ\\nเหลือใจ\\nเหลือเชื่อ\\nเหลือเฟือ\\nเหลือร้าย\\nเหลือล้น\\nเหลือหลาย\\nเหลือแหล่\\nเหลือแสน\\nเหลือหลอ\\nเหลื่อมล้ำ\\nเห่อเหิม\\nเหินห่าง\\nเหิมเกริม\\nเหิมหาญ\\nเหี้ยมเกรียม\\nเหี้ยมหาญ\\nเหี้ยมโหด\\nเหี่ยวแห้ง\\nเหือดหาย\\nเหือดแห้ง\\nแห่แหน\\nแหนงหน่าย\\nแหลกลาญ\\nแหลกเหลว\\nแหวกแนว\\nแหวกว่าย\\nโหงพราย\\nโหดร้าย\\nโหดเหี้ยม\\nโหยหวน\\nโหวงเหวง\\nให้การ\\nให้ท่า\\nให้ท้าย\\nให้ร้าย\\nให้หลัง\\nไหมพรม\\nไหวพริบ\\nอกไก่\\nอกร่อง\\nองค์กร\\nองค์การ\\nอดกลั้น\\nอดทน\\nอดสู\\nอดอยาก\\nอดออม\\nอดีตกาล\\nอดีตชาติ\\nอดีตภพ\\nอติชาตบุตร\\nอธิการบดี\\nอนาคตกาล\\nอนิจกรรม\\nอนุชาตบุตร\\nอเนกประสงค์\\nอบรม\\nอบอวล\\nอบอ้าว\\nอบอุ่น\\nอบายภูมิ\\nอบายมุข\\nอภัพบุคคล\\nอภัยทาน\\nอภัยโทษ\\nอภิชาตบุตร\\nอมยิ้ม\\nอมรรัตน์\\nอมฤตบท\\nอมฤตรส\\nอย่างไร\\nอรรถกร\\nอรรถกวี\\nอรรถคดี\\nอรรถประโยชน์\\nอรรถรส\\nอรรธนิศา\\nอรรธภาค\\nอรรธสระ\\nอรสุมพล\\nอรูปฌาน\\nอรูปพรหม\\nอรูปภพ\\nอรูปภูมิ\\nอวชาตบุตร\\nอวดดี\\nอวดอ้าง\\nอ้วนท้วน\\nอ้วนพี\\nอวบอั๋น\\nอวยชัย\\nอวยพร\\nอสุภกรรมฐาน\\nอสุภสัญญา\\nอโหสิกรรม\\nออเจ้า\\nออกแขก\\nออกตัว\\nออกโรง\\nออกฤทธิ์\\nออกลาย\\nออกหาก\\nออดอ้อน\\nออดแอด\\nอ่อนข้อ\\nอ่อนใจ\\nอ่อนช้อย\\nอ่อนน้อม\\nอ่อนเปลี้ย\\nอ่อนเพลีย\\nอ่อนโยน\\nอ่อนหวาน\\nอ่อนหัด\\nอ่อนไหว\\nอ่อนแอ\\nอ้อนวอน\\nอ้อนออด\\nอ้อมค้อม\\nอักษรศาสตร์\\nอักษรสาส์น\\nอัคคีภัย\\nอัญชนะศักราช\\nอัดฉีด\\nอัดอั้น\\nอัตราส่วน\\nอันโตชน\\nอันโตนาที\\nอับจน\\nอับเฉา\\nอับอาย\\nอัสสุชล\\nอัสสุธารา\\nอากัปกิริยา\\nอาการนาม\\nอากาศธาตุ\\nอากาศยาน\\nอาคารชุด\\nอ่างเก็บน้ำ\\nอ้างอิง\\nอาจหาญ\\nอาจอง\\nอาชญากร\\nอาชญากรรม\\nอาชญาบัตร\\nอาชญาสิทธิ์\\nอาญาสิทธิ์\\nอาณาเขต\\nอาณาจักร\\nอาณานิคม\\nอาณาประโยชน์\\nอาโปกสิณ\\nอาโปธาตุ\\nอาภากร\\nอายุขัย\\nอายุวัฒนะ\\nอาโลกกสิณ\\nอาหารว่าง\\nอำพราง\\nอิดโรย\\nอิดออด\\nอิดเอื้อน\\nอิตถีลิงค์\\nอิทธิปาฏิหาริย์\\nอิทธิพล\\nอิทธิฤทธิ์\\nอินังขังขอบ\\nอิ่มตัว\\nอิ่มหนำ\\nอิ่มเอม\\nอิ่มเอิบ\\nอีฉัน\\nอีตัว\\nอึงคะนึง\\nอึงมี่\\nอึงอล\\nอึ่งยาง\\nอึ่งอ่าง\\nอึดใจ\\nอึดอัด\\nอืดอาด\\nอื้อฉาว\\nอื้อซ่า\\nอื้ออึง\\nอุกฉกรรจ์\\nอุกอาจ\\nอุดอู้\\nอุ่นเครื่อง\\nอุ่นใจ\\nอุบอิบ\\nอุบัติภัย\\nอุบัติเหตุ\\nอุโบสถกรรม\\nอุโบสถหัตถี\\nอุปมาโวหาร\\nอุ้มชู\\nอุ้มสม\\nอุ้ยอ้าย\\nอู้อี้\\nเอกจิต\\nเอกฉันท์\\nเอกชน\\nเอกเทศ\\nเอกนัย\\nเอกบุคคล\\nเอกบุรุษ\\nเอกพจน์\\nเอกภพ\\nเอกภาพ\\nเอกมัย\\nเอกราช\\nเอกรูป\\nเอกลักษณ์\\nเอกศก\\nเอกสาร\\nเอกสิทธิ์\\nเอกอุ\\nเอ็ดอึง\\nเอนเอียง\\nเอมอร\\nเอออวย\\nเออออ\\nเอาการ\\nเอางาน\\nเอาจริง\\nเอาใจ\\nเอาเปรียบ\\nเอาเยี่ยง\\nเอิบอาบ\\nเอียงอาย\\nเอียงเอน\\nเอื้อเฟื้อ\\nโอ่โถง\\nโอ้โถง\\nโอ่อวด\\nโอ้อวด\\nโอ่อ่า\\nโอ้โลม\\nโอดครวญ\\nโอดโอย\\nโอนอ่อน\\nโอนเอน\\nโอบอ้อม\\nโอบอุ้ม\\nโอสถกรรม\\nไอเสีย\\nไอกรน\\nฮวบฮาบ\\nฮาป่า\\nฮึกหาญ\\nฮึกห้าว\\nฮึกเหิม\\nฮึกโหม\\nฮึกฮัก\\nเฮงซวย\\nโฮกฮือ\\nโฮกฮาก\\n\\nก็\\nกก\\nก๊ก\\nกกุธภัณฑ์\\nกง\\nก่ง\\nก้ง\\nก๊ง\\nก๋ง\\nกงกอน\\nกงไฉ่\\nกงเต๊ก\\nกงสี\\nกงสุล\\nกช\\nกฎ\\nกฏุก\\nกฐิน\\nกณิกนันต์\\nกณิการ์\\nกด\\nกตเวทิตา\\nกตเวที\\nกตัญชลี\\nกตัญญุตา\\nกตัญญู\\nกตาธิการ\\nกตาภินิหาร\\nกติกา\\nกถา\\nกถิกาจารย์\\nกทลี\\nกน\\nก่น\\nก้น\\nกนก\\nกนิษฐ์\\nกนิษฐา\\nกบ\\nกบฏ\\nกบดาน\\nกบทู\\nกบาล\\nกบินทร์\\nกบิล\\nกบี่\\nกบูร\\nกเบนทร์\\nกม\\nก้ม\\nกมณฑลาภิเษก\\nกมณฑโลทก\\nกมล\\nกมลา\\nกมลาศ\\nกมลาสน์\\nกมเลศ\\nกมัณฑลุ\\nกมุท\\nกร\\nกรกฎ\\nกรกฎาคม\\nกรกฏ\\nกรง\\nกรชกาย\\nกรณฑ์\\nกรณิการ์\\nกรณี\\nกรณีย์\\nกรณียกิจ\\nกรณียะ\\nกรด\\nกรน\\nกรบ\\nกรบูร\\nกรพินธุ์\\nกรม\\nกรรกฎ\\nกรรกศ\\nกรรเกด\\nกรรไกร\\nกรรเจียก\\nกรรชิง\\nกรรเชียง\\nกรรโชก\\nกรรฐ์\\nกรรฐา\\nกรรณ\\nกรรณา\\nกรรณิกา\\nกรรณิการ์\\nกรรดิ\\nกรรดิก\\nกรรดึก\\nกรรตุ\\nกรรไตร\\nกรรทบ\\nกรรแทก\\nกรรบิด\\nกรรบูร\\nกรรภิรมย์\\nกรรม\\nกรรม์\\nกรรม์ภิรมย์\\nกรรมชวาต\\nกรรมัชวาต\\nกรรมาชีพ\\nกรรมาธิการ\\nกรรมาร\\nกรรษก\\nกรรสะ\\nกรรแสง\\nกรวด\\nกรวบ\\nกรวม\\nกร้วม\\nกรวย\\nกรวิก\\nกรสาปน์\\nกรสุทธิ์\\nกรอ\\nกร้อ\\nกรอก\\nกร็อกกร๋อย\\nกรอกแกรก\\nกรอง\\nกรองกรอย\\nกรอด\\nกร่อน\\nกรอบ\\nกรอม\\nกร่อย\\nกระ\\nกระกร\\nกระกรุ่น\\nกระกลับกลอก\\nกระกี้\\nกระเกรอก\\nกระเกริก\\nกระเกริ่น\\nกระคน\\nกระคาย\\nกระงกกระเงิ่น\\nกระง่องกระแง่ง\\nกระง่อนกระแง่น\\nกระเง้ากระงอด\\nกระโงก\\nกระจก\\nกระจง\\nกระจร\\nกระจอก\\nกระจองหง่อง\\nกระจ๋องหง่อง\\nกระจองอแง\\nกระจ้อน\\nกระจอนหู\\nกระจ้อย\\nกระจ๋อหวอ\\nกระจะ\\nกระจัก\\nกระจัง\\nกระจัด\\nกระจับ\\nกระจ่า\\nกระจ่าง\\nกระจาด\\nกระจาน\\nกระจาบ\\nกระจาม\\nกระจาย\\nกระจาว\\nกระจิก\\nกระจิ๋ง\\nกระจิด\\nกระจิบ\\nกระจิ๋ม\\nกระจิริด\\nกระจิ๋ว\\nกระจี้\\nกระจี๋\\nกระจุก\\nกระจุ๋งกระจิ๋ง\\nกระจุบ\\nกระจุ๊บ\\nกระจุ๋มกระจิ๋ม\\nกระจุย\\nกระจู้\\nกระจู๋กระจี๋\\nกระจูด\\nกระเจอะกระเจิง\\nกระเจา\\nกระเจ่า\\nกระเจ้า\\nกระเจาะ\\nกระเจิง\\nกระเจิดกระเจิง\\nกระเจี้ยง\\nกระเจี๊ยบ\\nกระเจียว\\nกระเจี๊ยว\\nกระแจะ\\nกระโจน\\nกระโจม\\nกระฉอก\\nกระฉ่อน\\nกระฉับกระเฉง\\nกระฉิ่ง\\nกระฉีก\\nกระฉูด\\nกระเฉก\\nกระเฉด\\nกระแฉก\\nกระโฉกกระเฉก\\nกระโฉม\\nกระชดกระช้อย\\nกระชอน\\nกระชอมดอก\\nกระช้อย\\nกระชัง\\nกระชั้น\\nกระชับ\\nกระชาก\\nกระชาย\\nกระชิง\\nกระชิด\\nกระชุ\\nกระชุก\\nกระชุ่มกระชวย\\nกระเชอ\\nกระเชา\\nกระเช้า\\nกระเชียง\\nกระแชง\\nกระแชะ\\nกระโชก\\nกระซ่องกระแซ่ง\\nกระซับ\\nกระซาบ\\nกระซิก\\nกระซิบ\\nกระซี้\\nกระซุง\\nกระซุบกระซิบ\\nกระซุ้ม\\nกระซู่\\nกระเซ็น\\nกระเซอ\\nกระเซอะกระเซอ\\nกระเซอะกระเซิง\\nกระเซ้า\\nกระเซิง\\nกระแซ\\nกระแซะ\\nกระโซกระเซ\\nกระฎี\\nกระฎุมพี\\nกระดก\\nกระด้ง\\nกระดนโด่\\nกระดวง\\nกระดวน\\nกระด้วมกระเดี้ยม\\nกระดอ\\nกระดอง\\nกระดองหาย\\nกระดอน\\nกระดอม\\nกระดักกระเดี้ย\\nกระดังงัว\\nกระดังงา\\nกระดาก\\nกระด้าง\\nกระดางลาง\\nกระดาด\\nกระดาดขาว\\nกระดาน\\nกระดานพน\\nกระดาษ\\nกระดำกระด่าง\\nกระดิก\\nกระดิ่ง\\nกระดิ้ง\\nกระดิบ\\nกระดี่\\nกระดี้กระเดียม\\nกระดึง\\nกระดืบ\\nกระดุ\\nกระดุกกระดิก\\nกระดุ้งกระดิ้ง\\nกระดุบ\\nกระดุบกระดิบ\\nกระดุม\\nกระดูก\\nกระเดก\\nกระเด้ง\\nกระเด็น\\nกระเด้า\\nกระเดาะ\\nกระเดิด\\nกระเดี้ย\\nกระเดียด\\nกระเดือก\\nกระเดื่อง\\nกระแด็ก\\nกระแด้ง\\nกระแด้แร่\\nกระแด่ว\\nกระแดะ\\nกระโดก\\nกระโดง\\nกระโดด\\nกระโดน\\nกระได\\nกระตรับ\\nกระตราก\\nกระตรุด\\nกระตรุม\\nกระต้วมกระเตี้ยม\\nกระต้อ\\nกระต่องกระแต่ง\\nกระต๊อบ\\nกระต้อยตีวิด\\nกระตัก\\nกระตั้ว\\nกระต่าย\\nกระติก\\nกระติ๊ด\\nกระติบ\\nกระตือรือร้น\\nกระตุก\\nกระตุ้งกระติ้ง\\nกระตุ่น\\nกระตุ้น\\nกระตูบ\\nกระเตง\\nกระเต็น\\nกระเตอะ\\nกระเตาะ\\nกระเตาะกระแตะ\\nกระเตื้อง\\nกระแต\\nกระแตแต้แว้ด\\nกระโตกกระตาก\\nกระโตน\\nกระถด\\nกระถอบ\\nกระถั่ว\\nกระถาง\\nกระถิก\\nกระถิน\\nกระเถิบ\\nกระโถน\\nกระทก\\nกระทง\\nกระทบ\\nกระทรวง\\nกระทอก\\nกระท้อน\\nกระท่อนกระแท่น\\nกระท่อม\\nกระท้อมกระแท้ม\\nกระทะ\\nกระทั่ง\\nกระทั้น\\nกระทา\\nกระทาย\\nกระทาสี\\nกระทาหอง\\nกระทำ\\nกระทิกกระทวย\\nกระทิง\\nกระทึง\\nกระทืบ\\nกระทุ\\nกระทุง\\nกระทุ้ง\\nกระทุ่ม\\nกระทู้\\nกระเท่\\nกระเทียบ\\nกระเทียม\\nกระเทือน\\nกระเทื้อม\\nกระแทก\\nกระแท่น\\nกระแทะ\\nกระไทชาย\\nกระน่อง\\nกระนั้น\\nกระนี้\\nกระแนะกระแหน\\nกระโน้น\\nกระไน\\nกระบก\\nกระบม\\nกระบวน\\nกระบวย\\nกระบวร\\nกระบอก\\nกระบอง\\nกระบะ\\nกระบัด\\nกระบั้วกระเบี้ย\\nกระบ่า\\nกระบ้า\\nกระบาก\\nกระบาย\\nกระบาล\\nกระบิ\\nกระบิ้ง\\nกระบิด\\nกระบิล\\nกระบี่\\nกระบือ\\nกระบุง\\nกระบุ่มกระบ่าม\\nกระบู้กระบี้\\nกระบูน\\nกระบูร\\nกระเบง\\nกระเบญ\\nกระเบ็ดกระบวน\\nกระเบน\\nกระเบา\\nกระเบิก\\nกระเบียด\\nกระเบียน\\nกระเบื้อง\\nกระแบก\\nกระแบะ\\nกระโบม\\nกระปมกระปำ\\nกระปมกระเปา\\nกระปรอก\\nกระปรอกว่าว\\nกระปรี้กระเปร่า\\nกระปอก\\nกระป้อกระแป้\\nกระป่อง\\nกระป๋อง\\nกระปอดกระแปด\\nกระป๋อหลอ\\nกระปั้วกระเปี้ย\\nกระป่ำ\\nกระปุก\\nกระปุ๊กลุก\\nกระปุ่ม\\nกระปุ่มกระป่ำ\\nกระปุ่มกระปิ่ม\\nกระเป๋า\\nกระเปาะ\\nกระโปก\\nกระโปรง\\nกระผม\\nกระผลีกระผลาม\\nกระผาน\\nกระผีก\\nกระพรวน\\nกระพริ้ม\\nกระพอก\\nกระพอง\\nกระพ้อม\\nกระพัก\\nกระพัง\\nกระพังเหิร\\nกระพังโหม\\nกระพัด\\nกระพัตร\\nกระพัน\\nกระพั่น\\nกระพา\\nกระพาก\\nกระพี้\\nกระพือ\\nกระพุ้ง\\nกระพุ่ม\\nกระเพาะ\\nกระเพิง\\nกระเพื่อม\\nกระแพ้ง\\nกระฟัดกระเฟียด\\nกระฟูมกระฟาย\\nกระมล\\nกระมอบ\\nกระมอมกระแมม\\nกระมัง\\nกระมัน\\nกระมิดกระเมี้ยน\\nกระมุท\\nกระเมาะ\\nกระย่อง\\nกระย่องกระแย่ง\\nกระย่อน\\nกระย่อม\\nกระยา\\nกระยาง\\nกระยาจก\\nกระยาหงัน\\nกระยิก\\nกระยิ้มกระย่อง\\nกระยึกกระยือ\\nกระยืดกระยาด\\nกระเย้อกระแหย่ง\\nกระรอก\\nกระเรียน\\nกระโรกน้ำข้าว\\nกระโรกใหญ่\\nกระไร\\nกระลด\\nกระลบ\\nกระลอก\\nกระลอม\\nกระละหล่ำ\\nกระลัด\\nกระลับ\\nกระลัมพร\\nกระลา\\nกระลำ\\nกระลำพัก\\nกระลำพุก\\nกระลิง\\nกระลี\\nกระลุมพาง\\nกระลุมพุก\\nกระลุมพู\\nกระลูน\\nกระลู่น์\\nกระเล็น\\nกระเลียด\\nกระเลือก\\nกระโลง\\nกระวน\\nกระวัด\\nกระวาด\\nกระวาน\\nกระวาย\\nกระวิน\\nกระวี\\nกระวีกระวาด\\nกระวูดกระวาด\\nกระเวน\\nกระเวยกระวาย\\nกระแวน\\nกระโวยกระวาย\\nกระษัย\\nกระษาปณ์\\nกระสง\\nกระสบ\\nกระสม\\nกระสรวล\\nกระสร้อย\\nกระสวน\\nกระสวย\\nกระสอบ\\nกระสะ\\nกระสัง\\nกระสัน\\nกระสับกระส่าย\\nกระสา\\nกระสานติ์\\nกระสาบ\\nกระสาย\\nกระสือ\\nกระสุงกระสิง\\nกระสุน\\nกระสูทธิ์\\nกระสูบ\\nกระเสด\\nกระเส็นกระสาย\\nกระเส่า\\nกระเสาะกระแสะ\\nกระเสียน\\nกระเสียร\\nกระเสือกกระสน\\nกระแส\\nกระแสง\\nกระแสะ\\nกระโสง\\nกระไส\\nกระหนก\\nกระหนาก\\nกระหนาบ\\nกระหน่ำ\\nกระหมวด\\nกระหมอบ\\nกระหม่อม\\nกระหมั่ง\\nกระหมิบ\\nกระหมุดกระหมิด\\nกระหมุบ\\nกระหย่ง\\nกระหย่อม\\nกระหยัง\\nกระหยับ\\nกระหยิ่ม\\nกระหรอด\\nกระหริ่ง\\nกระหวน\\nกระหวัด\\nกระหอง\\nกระหัง\\nกระหัด\\nกระหาง\\nกระหาย\\nกระหึม\\nกระหึ่ม\\nกระหืดกระหอบ\\nกระเห็น\\nกระเหนียด\\nกระเหม็ดกระเหมียด\\nกระเหม็ดกระแหม่\\nกระเหม่น\\nกระเหม่า\\nกระเหว่า\\nกระเห่อ\\nกระเหิม\\nกระเหี้ยนกระหือรือ\\nกระแห\\nกระแหทอง\\nกระแหนบ\\nกระแหนะ\\nกระแหมบ\\nกระแหม่ว\\nกระแหย่ง\\nกระแหร่ม\\nกระแหล่ง\\nกระโห้\\nกระโหนด\\nกระโหม\\nกระโหย\\nกระโหย่ง\\nกระอวล\\nกระอ้อกระแอ้\\nกระออดกระแอด\\nกระออบ\\nกระออม\\nกระอ้อมกระแอ้ม\\nกระอัก\\nกระอักกระอ่วน\\nกระอั้วแทงควาย\\nกระอ้า\\nกระอาน\\nกระอิด\\nกระอิดกระเอื้อน\\nกระอึก\\nกระอืด\\nกระอุ\\nกระอุก\\nกระเอา\\nกระเอิก\\nกระเอิบ\\nกระแอก\\nกระแอบ\\nกระแอม\\nกระไอ\\nกรัก\\nกรักขี\\nกรัง\\nกรัชกาย\\nกรัณฑ์\\nกรัณย์\\nกรัน\\nกรับ\\nกรัม\\nกราก\\nกราง\\nกร่าง\\nกราด\\nกราดวง\\nกราน\\nกร้าน\\nกราบ\\nกราฟ\\nกราม\\nกราย\\nกร่าย\\nกราว\\nกร้าว\\nกรำ\\nกร่ำ\\nกริก\\nกริ๊ก\\nกริกกริว\\nกริกกรี\\nกริ่ง\\nกริ๊ง\\nกริงกริว\\nกริ้งกริ้ว\\nกริช\\nกริณี\\nกริน\\nกรินทร์\\nกรินี\\nกริบ\\nกริม\\nกริ่ม\\nกริยา\\nกริยานุเคราะห์\\nกริว\\nกริ้ว\\nกรี\\nกรีฑา\\nกรีด\\nกรี๊ด\\nกรีธา\\nกรีษ\\nกรีส\\nกรึ๊บ\\nกรุ\\nกรุง\\nกรุ้งกริ่ง\\nกรุณ\\nกรุณา\\nกรุณาธิคุณ\\nกรุ่น\\nกรุบ\\nกรุ่ม\\nกรุ้มกริ่ม\\nกรุย\\nกรุยเกรียว\\nกรู\\nกรูด\\nกรูม\\nกเรณุ\\nกเรนทร\\nกเรนทร์\\nกฤช\\nกฤดาภินิหาร\\nกฤตติกา\\nกฤษฎา\\nกฤษฎาธาร\\nกฤษฎาภินิหาร\\nกฤษฎีกา\\nกฤษณา\\nกล\\nกลด\\nกล่น\\nกลบ\\nกลม\\nกลละ\\nกลวง\\nกล้วย\\nกลศ\\nกล้อ\\nกลอก\\nกลอง\\nกล่อง\\nกล้อง\\nกล้องแกล้ง\\nกลอน\\nกล่อน\\nกล้อน\\nกล่อม\\nกล้อมแกล้ม\\nกลอย\\nกลัก\\nกลัด\\nกลั่น\\nกลั้น\\nกลันทก์\\nกลันทะ\\nกลับ\\nกลัมพร\\nกลัมพัก\\nกลัว\\nกลั้ว\\nกลา\\nกล้า\\nกลาก\\nกลากลาด\\nกลาง\\nกลาด\\nกลาบาต\\nกลาป\\nกล้าม\\nกลาย\\nกล้าย\\nกลายกลอก\\nกล่าว\\nกลาโหม\\nกล่ำ\\nกล้ำ\\nกลิ้ง\\nกลิงค์\\nกลิ่น\\nกลี\\nกลีบ\\nกลึง\\nกลึงค์\\nกลืน\\nกลุ่ม\\nกลุ้ม\\nกลูโคส\\nกเลวระ\\nกวด\\nกวน\\nกวม\\nกวย\\nกวยจั๊บ\\nกวยจี๊\\nก๋วยเตี๋ยว\\nกวัก\\nกวัด\\nกวา\\nกว่า\\nกวาง\\nกว่าง\\nกว้าง\\nกว่างโซ้ง\\nกวางตุ้ง\\nกวาด\\nกว้าน\\nกว๊าน\\nกว้าว\\nกวาวเครือ\\nกวี\\nกษณะ\\nกษมา\\nกษัตร\\nกษัตรา\\nกษัตริย์\\nกษัตรี\\nกษัตรีย์\\nกษัย\\nกษาปณ์\\nกษิดิ\\nกษีร\\nกษีรธารา\\nกษีระ\\nกสานติ์\\nกสิกร\\nกสิกรรม\\nกสิณ\\nกหังปายา\\nกหาปณะ\\nกเฬวราก\\nกอ\\nก่อ\\nก้อ\\nก๊อ\\nกอก\\nก๊อก\\nกอแก\\nกอง\\nก่อง\\nก้อง\\nกองกอย\\nก๊อซ\\nกอด\\nก่อน\\nก้อน\\nกอบ\\nกอบนาง\\nก๊อบปี้\\nกอปร\\nก้อม\\nกอมก้อ\\nก่อมก้อ\\nกอย\\nก้อย\\nก๋อย\\nกอริลลา\\nกอล์ฟ\\nกอและ\\nกอเอี๊ยะ\\nกะ\\nกะกัง\\nกะง้องกะแง้ง\\nกะจัง\\nกะแจะ\\nกะชะ\\nกะชัง\\nกะชามาศ\\nกะชิง\\nกะชึ่กกะชั่ก\\nกะแช่\\nกะซวก\\nกะซ้าหอย\\nกะซี่\\nกะโซ่\\nกะโซ้\\nกะดก\\nกะดง\\nกะดวน\\nกะดอก\\nกะดะ\\nกะดังบาย\\nกะดัด\\nกะด้าง\\nกะดำกะด่าง\\nกะดี\\nกะดี่\\nกะดุ้ง\\nกะเด้\\nกะเดก\\nกะเดี๋ยว\\nกะตรุด\\nกะตอก\\nกะต่อย\\nกะตัก\\nกะตั้ก\\nกะตัง\\nกะตังกะติ้ว\\nกะต๊าก\\nกะต้ำ\\nกะติ๊กริก\\nกะติงกะแตง\\nกะตีบ\\nกะตึงกะแตง\\nกะตุ๊ก\\nกะตุด\\nกะตูก\\nกะเตง\\nกะโต๊ก\\nกะโตงกะเตง\\nกะโต้งโห่ง\\nกะถัว\\nกะทกรก\\nกะทอ\\nกะทัง\\nกะทังหัน\\nกะทัดรัด\\nกะทันหัน\\nกะทับ\\nกะทิ\\nกะทือ\\nกะทุน\\nกะเทย\\nกะเทาะ\\nกะแท้\\nกะแท่ง\\nกะแทน\\nกะนวล\\nกะนัด\\nกะบ่อนกะแบ่น\\nกะบัง\\nกะบั้ง\\nกะบิ้ง\\nกะบิล\\nกะบึงกะบอน\\nกะบุด\\nกะเบ้อ\\nกะเบียน\\nกะเบือ\\nกะปริดกะปรอย\\nกะปริบ\\nกะปริบกะปรอย\\nกะปลกกะเปลี้ย\\nกะปวกกะเปียก\\nกะปอม\\nกะปอมขาง\\nกะปะ\\nกะป้ำกะเป๋อ\\nกะปิ\\nกะปู\\nกะปูด\\nกะปูดหลูด\\nกะเปะ\\nกะเปิ๊บกะป๊าบ\\nกะเปียด\\nกะแป้น\\nกะแปะ\\nกะโปรง\\nกะโปโล\\nกะผลุบกะโผล่\\nกะเผ่น\\nกะเผลก\\nกะโผลกกะเผลก\\nกะพง\\nกะพรวดกะพราด\\nกะพร่องกะแพร่ง\\nกะพริบ\\nกะพรุน\\nกะพรูดกะพราด\\nกะพล้อ\\nกะพ้อ\\nกะเพรา\\nกะเพียด\\nกะเม็ง\\nกะร่องกะแร่ง\\nกะระตะ\\nกะระหนะ\\nกะรัง\\nกะรัต\\nกะราง\\nกะริง\\nกะรุงกะรัง\\nกะรุ่งกะริ่ง\\nกะรุน\\nกะเร\\nกะเรกะร่อน\\nกะเร่กะร่อน\\nกะเร่อ\\nกะเรี่ยกะราด\\nกะโรกะเร\\nกะลวย\\nกะลอ\\nกะล่อกะแล่\\nกะลอจี๊\\nกะล่อน\\nกะล่อมกะแล่ม\\nกะล่อยกะหลิบ\\nกะละปังหา\\nกะละมัง\\nกะละแม\\nกะละออม\\nกะลังตังไก่\\nกะลัน\\nกะลันทา\\nกะลา\\nกะลาง\\nกะลาสี\\nกะลำพอ\\nกะลิง\\nกะลิงปลิง\\nกะลิ้มกะเหลี่ย\\nกะลิอ่อง\\nกะลุมพี\\nกะเล็ง\\nกะเล่อกะล่า\\nกะเลิด\\nกะเลียว\\nกะแล\\nกะโล่\\nกะโลง\\nกะวอกกะแวก\\nกะวะ\\nกะส้มชื่น\\nกะสัง\\nกะส้าหอย\\nกะหนอกะแหน\\nกะหน็องกะแหน็ง\\nกะหนะ\\nกะหนุงกะหนิง\\nกะหร่อง\\nกะหรอด\\nกะหร็อมกะแหร็ม\\nกะหราน\\nกะหรี่\\nกะหรี่ปั๊บ\\nกะหลาป๋า\\nกะหล่ำ\\nกะหลี่\\nกะหลีกะหลอ\\nกะหลุกกะหลิก\\nกะหำ\\nกะหำแพะ\\nกะหือ\\nกะหูด\\nกะเหรี่ยง\\nกะเหลาะเปาะ\\nกะแหยก\\nกะแหะ\\nกะโหลก\\nกะโหล้ง\\nกะไหล่\\nกะอวม\\nกะออม\\nกะอาน\\nกะอาม\\nกะอูบ\\nกัก\\nกั๊ก\\nกักกรา\\nกักการุ\\nกักขฬะ\\nกัง\\nกั้ง\\nกังก้า\\nกังเกียง\\nกังขา\\nกังฉิน\\nกังฟู\\nกังวล\\nกังวาน\\nกังสดาล\\nกังไส\\nกังหัน\\nกัจฉปะ\\nกัจฉะ\\nกัจฉา\\nกัญ\\nกัญจุก\\nกัญจุการา\\nกัญชา\\nกัญญา\\nกัฐ\\nกัณฏกะ\\nกัณฐกะ\\nกัณฐชะ\\nกัณฐัศ\\nกัณฐัศว์\\nกัณฐา\\nกัณฐี\\nกัณฑ์\\nกัณณ์\\nกัณหา\\nกัด\\nกัตติกมาส\\nกัตติกา\\nกัตติเกยา\\nกัตรา\\nกัทลี\\nกัน\\nกั่น\\nกั้น\\nกันเกรา\\nกันไกร\\nกันชิง\\nกันเชอ\\nกันดาร\\nกันดาล\\nกันได\\nกันต์\\nกันตัง\\nกันไตร\\nกันทร\\nกันทรากร\\nกันภิรมย์\\nกันเมียง\\nกันย์\\nกันยา\\nกันยายน\\nกันลง\\nกันลอง\\nกันแสง\\nกั้นหยั่น\\nกับ\\nกับแก้\\nกัป\\nกัปตัน\\nกัปปาสิก\\nกัปปิยภัณฑ์\\nกัปปิยะ\\nกัมปนาท\\nกัมประโด\\nกัมปี\\nกัมพล\\nกัมพุช\\nกัมพู\\nกัมพูชา\\nกัมโพช\\nกัมมัชวาต\\nกัมมัฏฐาน\\nกัมมันตภาพรังสี\\nกัมมันตรังสี\\nกัมมาร\\nกัมลาศ\\nกัยวิกัย\\nกัลชาญ\\nกัลบก\\nกัลป์\\nกัลปนา\\nกัลปพฤกษ์\\nกัลปังหา\\nกัลปาวสาน\\nกัลปิต\\nกัลเม็ด\\nกัลยา\\nกัลยาณมิตร\\nกัลยาณี\\nกัลออม\\nกัศยป\\nกัษณ\\nกา\\nก๋า\\nกาก\\nกากบาท\\nกากะทิง\\nกากะเยีย\\nกากี\\nกาง\\nก้าง\\nกางเกง\\nกางเขน\\nก๊าซ\\nกาซะลอง\\nกาญจนา\\nกาฐ\\nกาด\\nก๊าด\\nกาน\\nก่าน\\nก้าน\\nก๊าน\\nกานดา\\nกานต์\\nกานน\\nก้านพร้าว\\nกานพลู\\nกาน้า\\nกาบ\\nก้าบ\\nกาบู\\nกาพย์\\nกาเฟอีน\\nกาแฟ\\nกาม\\nก้าม\\nกามารมณ์\\nกามินี\\nกาเมสุมิจฉาจาร\\nกาย\\nก่าย\\nกาเยน\\nการ\\nการณ์\\nการ์ด\\nการ์ตูน\\nการบูร\\nการย์\\nการวิก\\nการเวก\\nการะเกด\\nการะบุหนิง\\nการัณย์\\nการันต์\\nการางหัวขวาน\\nการิตการก\\nการิตวาจก\\nการุญ\\nการุณย์\\nกาเรการ่อน\\nกาล\\nกาลกรรณี\\nกาลกิณี\\nกาลจักร\\nกาลัญญุตา\\nกาลัญญู\\nกาลัด\\nกาลานุกาล\\nกาลิก\\nกาลี\\nกาแล\\nกาแล็กซี\\nกาแล็กโทส\\nกาว\\nก้าว\\nกาววาว\\nกาวาง\\nกาแวน\\nกาศิก\\nกาษฐะ\\nกาษา\\nกาสร\\nกาสะ\\nกาสา\\nกาสาร\\nกาสาวะ\\nกาสิโน\\nกาหล\\nกาหลง\\nกาหลา\\nกาเหว่า\\nกาไหล่\\nกาฬ\\nกาฬาวก\\nกาฮัง\\nกำ\\nก่ำ\\nกำกวม\\nกำกัด\\nกำกับ\\nก้ำกึ่ง\\nกำกูน\\nก้ำเกิน\\nกำเกียง\\nกำคูน\\nกำจร\\nกำจัด\\nกำจาย\\nกำชับ\\nกำชำ\\nกำซาบ\\nกำซำ\\nกำด้น\\nกำดัด\\nกำดาล\\nกำเดา\\nกำธร\\nกำนล\\nกำนัน\\nกำนัล\\nกำเนิด\\nกำบัง\\nก่ำบึ้ง\\nกำเบ้อ\\nกำปอ\\nกำปั่น\\nกำผลา\\nกำพง\\nกำพด\\nกำพต\\nกำพร้า\\nกำพราก\\nกำพวด\\nกำพอง\\nกำพืด\\nกำพุด\\nกำพู\\nกำเพลิง\\nกำแพง\\nกำภู\\nกำมลาศน์\\nกำมเลศ\\nกำมะถัน\\nกำมะลอ\\nกำมะหยี่\\nกำมะหริด\\nกำมังละการ\\nกำมังวิลิต\\nกำมัชพล\\nกำยาน\\nกำยำ\\nกำรอ\\nกำราบ\\nกำราล\\nกำเริบ\\nกำไร\\nกำลัง\\nกำลุง\\nกำเลา\\nกำไล\\nกำสรด\\nกำสรวล\\nกำหนด\\nกำหนัด\\nกำเหน็จ\\nกำแหง\\nกิก\\nกิ๊ก\\nกิ่ง\\nกิ้งก่า\\nกิ้งกือ\\nกิ้งโครง\\nกิจ\\nกิจจะ\\nกิจจา\\nกิดาการ\\nกิดาหยัน\\nกิตติ\\nกิตติมศักดิ์\\nกิน\\nกินนร\\nกินปลี\\nกินเปี้ยว\\nกินริน\\nกินรี\\nกิ๊บ\\nกิมตึ๋ง\\nกิมิชาติ\\nกิมิวิทยา\\nกิโมโน\\nกิโยตีน\\nกิระ\\nกิริณี\\nกิรินท\\nกิริเนศวร\\nกิริยา\\nกิเลน\\nกิเลส\\nกิโล\\nกิโลมกะ\\nกิ่ว\\nกิ๋ว\\nกี\\nกี่\\nกี้\\nกี๊\\nกี๋\\nกีฏวิทยา\\nกีด\\nกีตาร์\\nกีบ\\nกีรติ\\nกีฬา\\nกึก\\nกึง\\nกึ่ง\\nกึ๋น\\nกุ\\nกุก\\nกุ๊ก\\nกุกกุฏ\\nกุกกุร\\nกุกรรม\\nกุ้ง\\nกุงอน\\nกุงาน\\nกุโงก\\nกุจี\\nกุญแจ\\nกุญชร\\nกุฎ\\nกุฎา\\nกุฎี\\nกุฎุมพี\\nกุฏฐัง\\nกุฏิ\\nกุณฑ์\\nกุณฑล\\nกุณฑี\\nกุณโฑ\\nกุณาล\\nกุณี\\nกุด\\nกุดัง\\nกุดั่น\\nกุดา\\nกุทัณฑ์\\nกุน\\nกุ๊น\\nกุนเชียง\\nกุนที\\nกุโนกามอ\\nกุบ\\nกุบกับ\\nกุม\\nกุ่ม\\nกุมฝอย\\nกุมภ์\\nกุมภนิยา\\nกุมภัณฑ์\\nกุมภา\\nกุมภิล\\nกุมภีล์\\nกุมเหง\\nกุมาร\\nกุมารา\\nกุมารี\\nกุมุท\\nกุย\\nกุ๊ย\\nกุ๋ย\\nกุยช่าย\\nกุยเฮง\\nกุรระ\\nกุรุพินท์\\nกุเรา\\nกุล\\nกุลา\\nกุลาหล\\nกุลี\\nกุลีกุจอ\\nกุเลา\\nกุแล\\nกุเวร\\nกุศราช\\nกุศล\\nกุศโลบาย\\nกุสุม\\nกุสุมภ์\\nกุสุมา\\nกุสุมาลย์\\nกุสุมิตลดาเวลลิตา\\nกุหนี\\nกุหนุง\\nกุหร่า\\nกุหล่า\\nกุหลาบ\\nกุแหละ\\nกู\\nกู่\\nกู้\\nกู๊ก\\nกูฏ\\nกูฏา\\nกูณฑ์\\nกูด\\nกูบ\\nกูปรี\\nกูรมะ\\nกูรมาวตาร\\nเก\\nเก้\\nเก๊\\nเก๋\\nเกก\\nเก๊ก\\nเกกมะเหรก\\nเก๊กฮวย\\nเก้กัง\\nเก็ง\\nเก่ง\\nเก้ง\\nเก๋ง\\nเกงกอย\\nเก่งกาจ\\nเกงเขง\\nเก๋งเคง\\nเก็จ\\nเกจิอาจารย์\\nเกชา\\nเกณฑ์\\nเกด\\nเก็ด\\nเกตุ\\nเกน\\nเก็บ\\nเกม\\nเกย\\nเกยูร\\nเกรง\\nเกร็ง\\nเกร็ด\\nเกรน\\nเกร่อ\\nเกรอะ\\nเกราะ\\nเกริก\\nเกริน\\nเกริ่น\\nเกรียก\\nเกรียง\\nเกรียด\\nเกรียน\\nเกรียบ\\nเกรียม\\nเกรียว\\nเกรี้ยว\\nเกเร\\nเกล็ด\\nเกลศ\\nเกลอ\\nเกลา\\nเกล้า\\nเกลาะ\\nเกลี่ย\\nเกลี้ย\\nเกลียง\\nเกลี้ยง\\nเกลียด\\nเกลียว\\nเกลือ\\nเกลื้อ\\nเกลือก\\nเกลื่อน\\nเกลื้อน\\nเกวัฏ\\nเกวียน\\nเกศ\\nเกศว\\nเกศวะ\\nเกศา\\nเกศินี\\nเกศี\\nเกษตร\\nเกษม\\nเกษียณ\\nเกษียน\\nเกษียร\\nเกส\\nเกสร\\nเกสรี\\nเกสา\\nเกสี\\nเก้อ\\nเกอิชา\\nเกะ\\nเกะกะ\\nเกา\\nเก่า\\nเก้า\\nเก๋า\\nเกาต์\\nเกาทัณฑ์\\nเกาบิล\\nเกาลัด\\nเกาลิน\\nเกาไศย\\nเกาหลี\\nเกาเหลา\\nเกาเหลียง\\nเก้าอี้\\nเกาะ\\nเกิ้ง\\nเกิด\\nเกิน\\nเกิบ\\nเกีย\\nเกียกกาย\\nเกียง\\nเกี่ยง\\nเกี๋ยง\\nเกียจ\\nเกียด\\nเกียน\\nเกี้ยมไฉ่\\nเกี้ยมอี๋\\nเกียร์\\nเกียรติ\\nเกียรติ์\\nเกี่ยว\\nเกี้ยว\\nเกี๊ยว\\nเกี๊ยะ\\nเกื้อ\\nเกือก\\nเกื้อกูล\\nเกือบ\\nแก\\nแก่\\nแก้\\nแกง\\nแก่ง\\nแก้ง\\nแก๊ง\\nแกงได\\nแกงแนง\\nแกโดลิเนียม\\nแกน\\nแก่น\\nแก๊ป\\nแกม\\nแก้ม\\nแกมมา\\nแกรก\\nแกร่ง\\nแกร็น\\nแกรนิต\\nแกรไฟต์\\nแกร่ว\\nแกระ\\nแกล\\nแกล้ง\\nแกลน\\nแกลบ\\nแกล้ม\\nแกลลอน\\nแกลเลียม\\nแกล้ว\\nแกละ\\nแกแล\\nแกว\\nแก้ว\\nแกว่ง\\nแก๊ส\\nแกะ\\nโก\\nโก่\\nโก้\\nโก๋\\nโกก\\nโกกนุท\\nโกกิลา\\nโกโก้\\nโกง\\nโก่ง\\nโกงกาง\\nโก้งเก้ง\\nโกงโก้\\nโก้งโค้ง\\nโกเชาว์\\nโกญจนาท\\nโกญจา\\nโกฏิ\\nโกฐ\\nโกฐาส\\nโกณะ\\nโกดัง\\nโกทัณฑ์\\nโกน\\nโก่น\\nโก๋น\\nโกมล\\nโกมุท\\nโกเมน\\nโกเมศ\\nโกย\\nโกรก\\nโกรกกราก\\nโกรง\\nโกร่ง\\nโกร่งกร่าง\\nโกรงเกรง\\nโกร๋งเกร๋ง\\nโกรญจ\\nโกรต๋น\\nโกรธ\\nโกรธา\\nโกร๋น\\nโกรม\\nโกรย\\nโกรศ\\nโกโรโกเต\\nโกโรโกโรก\\nโกโรโกโส\\nโกลน\\nโกลาหล\\nโกไล\\nโกวิท\\nโกศ\\nโกศล\\nโกษม\\nโกสน\\nโกสัช\\nโกสินทร์\\nโกสีย์\\nโกสุม\\nโกไสย\\nโกหก\\nใกล้\\nไก\\nไก่\\nไก๊\\nไก๋\\nไก่กอม\\nไกพัล\\nไกร\\nไกรพ\\nไกรลาส\\nไกรศร\\nไกรศรี\\nไกรสร\\nไกรสรี\\nไกรสิทธิ\\nไกล\\nไกล่\\nไกลาส\\nไกว\\nไกวัล\\nขงจื๊อ\\nขจร\\nขจรจบ\\nขจัด\\nขจ่าง\\nขจาย\\nขจาว\\nขจิต\\nขจี\\nขจุย\\nขเจา\\nขณะ\\nขด\\nขน\\nข้น\\nขนง\\nขนด\\nขนบ\\nขนม\\nขนอง\\nขนอน\\nขนอบ\\nขนัด\\nขนัน\\nขนาก\\nขนาง\\nขนาด\\nขนาน\\nขนาบ\\nขนาย\\nขนำ\\nขนิษฐ\\nขนิษฐา\\nขนุน\\nขนุนนก\\nขบ\\nขบถ\\nขบวน\\nขบวร\\nขม\\nข่ม\\nขมงโกรย\\nขมวด\\nขมวน\\nขมอง\\nขม่อม\\nขมัง\\nขมับ\\nขมา\\nขม้ำ\\nขมิ้น\\nขมิบ\\nขมีขมัน\\nขมึง\\nขมึงทึง\\nขมุ\\nขมุกขมัว\\nขมุบ\\nขโมย\\nขยด\\nขยม\\nขย่ม\\nขยอก\\nขยอง\\nขย่อน\\nขย้อน\\nขยะ\\nขยัก\\nขยัน\\nขยั้น\\nขยับ\\nขยาด\\nขยาย\\nขยำ\\nขย้ำ\\nขยิก\\nขยิบ\\nขยิ่ม\\nขยี้\\nขยุกขยิก\\nขยุกขยุย\\nขยุบ\\nขยุบขยิบ\\nขยุม\\nขยุ้ม\\nขยุย\\nขรม\\nขรรค์\\nขรัว\\nขริบ\\nขรี\\nขรึม\\nขรุขระ\\nขลบ\\nขล้อ\\nขลัง\\nขลับ\\nขลาด\\nขลาย\\nขลิบ\\nขลุก\\nขลุกขลัก\\nขลุกขลิก\\nขลุบ\\nขลุม\\nขลุ่ย\\nขลู\\nขลู่\\nขวง\\nข่วง\\nขวด\\nข่วน\\nขวนขวาย\\nขวบ\\nขวย\\nขวักไขว่\\nขวัญ\\nขวั้น\\nขวับ\\nขวับเขวียว\\nขวา\\nขวาก\\nขวาง\\nขว้าง\\nขวาด\\nขวาน\\nขวายขวน\\nขวาว\\nขว้าว\\nขวิด\\nขอ\\nข่อ\\nข้อ\\nของ\\nข้อง\\nขอด\\nขอน\\nข้อน\\nขอบ\\nขอม\\nข่อย\\nข้อย\\nข่อยหยอง\\nขะแจะ\\nขะเน็ด\\nขะมอมขะแมม\\nขะมักเขม้น\\nขะมุกขะมอม\\nขะยิก\\nขะยุก\\nขะเย้อแขย่ง\\nขัค\\nขัง\\nขังขอก\\nขัช\\nขัณฑสกร\\nขัณฑสีมา\\nขัด\\nขัดมอน\\nขัตติยมานะ\\nขัน\\nขั้น\\nขันติ\\nขันตี\\nขันโตก\\nขันที\\nขันธ์\\nขันธาวาร\\nขับ\\nขัว\\nขั้ว\\nขา\\nข่า\\nข้า\\nขาก\\nขาก๊วย\\nขาง\\nข่าง\\nข้าง\\nขาณุ\\nขาด\\nขาทนียะ\\nขาน\\nขาบ\\nข้าพเจ้า\\nขาม\\nข่าม\\nข้าม\\nขาย\\nข่าย\\nขาล\\nขาว\\nข่าว\\nข้าว\\nข้าวอังกุลี\\nขำ\\nขิก\\nขิง\\nขิงแกลง\\nขิงแครง\\nขิด\\nขิปสัทโท\\nขิม\\nขี่\\nขี้\\nขี้เข็บ\\nขีณาสพ\\nขีด\\nขี้ตังนี\\nขีปนาวุธ\\nขี้ยอก\\nขีระ\\nขึง\\nขึ้ง\\nขึ้น\\nขึ้นฉ่าย\\nขืน\\nขื่น\\nขื่อ\\nขุก\\nขุด\\nขุน\\nขุ่น\\nขุนเพ็ด\\nขุม\\nขุย\\nขู่\\nขูด\\nเข\\nเข้\\nเขก\\nเข็ง\\nเข่ง\\nเขจร\\nเข็ญ\\nเข็ด\\nเขดา\\nเขต\\nเขน\\nเข็น\\nเข่น\\nเขนง\\nเขน็ด\\nเขนย\\nเขบ็จขบวน\\nเขบ็ต\\nเขม\\nเข็ม\\nเข้ม\\nเข้มขาบ\\nเขม็ง\\nเขม็ดแขม่\\nเขม่น\\nเขม้น\\nเขม้นขะมัก\\nเขมร\\nเขมา\\nเขม่า\\nเขมือบ\\nเขย\\nเขยก\\nเขย่ง\\nเขย้อแขย่ง\\nเขย่า\\nเขยิน\\nเขยิบ\\nเขยื้อน\\nเขรอะ\\nเขลง\\nเขลอะ\\nเขละ\\nเขลา\\nเขลาะ\\nเขว\\nเขษม\\nเขฬะ\\nเขะขะ\\nเขา\\nเข่า\\nเข้า\\nเขิง\\nเขิน\\nเขิบ\\nเขี่ย\\nเขียง\\nเขียด\\nเขียดตะปาด\\nเขียน\\nเขี่ยน\\nเขียม\\nเขียว\\nเขี้ยว\\nเขียะ\\nเขือ\\nเขือง\\nเขื่อง\\nเขื่อน\\nเขือม\\nแข\\nแข้\\nแขก\\nแข็ง\\nแข่ง\\nแข้ง\\nแขน\\nแข่น\\nแข้น\\nแขนง\\nแขม\\nแขม็บ\\nแขม่ว\\nแขยง\\nแขย่ง\\nแขวก\\nแขวง\\nแขวน\\nแขวะ\\nโข\\nโขก\\nโขง\\nโข่ง\\nโขด\\nโขดง\\nโขน\\nโขนง\\nโขม\\nโขมง\\nโขมด\\nโขยก\\nโขยง\\nโขย่ง\\nโขยด\\nโขลก\\nโขลง\\nโขลน\\nโขษม\\nไข\\nไข่\\nไข้\\nไขว่\\nไขว้\\nคคนะ\\nคคนัมพร\\nคคนางค์\\nคคนานต์\\nคง\\nคงคา\\nคงไคย\\nคช\\nคชาชาติ\\nคชาชีพ\\nคชาธาร\\nคชาภรณ์\\nคณนา\\nคณบดี\\nคณะ\\nคณาจารย์\\nคณาธิการ\\nคณาธิปไตย\\nคณานับ\\nคณิกา\\nคณิต\\nคเณศ\\nคด\\nคดี\\nคติ\\nคทา\\nคน\\nค้น\\nคนทา\\nคนทิสอ\\nคนที\\nคนโท\\nคนธ์\\nคันธ์\\nคนธรรพ์\\nคเนจร\\nคบ\\nคม\\nคมน์\\nคมนาการ\\nคมนาคม\\nคมิกภัต\\nครก\\nครบ\\nครรชิต\\nครรภ\\nครรภ์\\nครรลอง\\nครรโลง\\nครรไล\\nครวญ\\nครวี\\nครหา\\nครอก\\nครอง\\nครองแครง\\nคร่อเงาะ\\nคร่อเทียน\\nครอบ\\nคร่อม\\nคระเมิม\\nคระแลง\\nคระไล\\nคระแวง\\nคระหน\\nคระหวน\\nคระหาย\\nคระโหย\\nครั่ง\\nครั้ง\\nครัดเคร่ง\\nครัน\\nครั่น\\nครั้น\\nครับ\\nครัว\\nครา\\nคร่า\\nคราก\\nคราง\\nคราญ\\nคราด\\nคร้าน\\nคราบ\\nคราม\\nคร้าม\\nครามครัน\\nคราว\\nคร่าว\\nคราส\\nครำ\\nคร่ำ\\nคร่ำเคร่ง\\nคริปทอน\\nคริสต์\\nครีบ\\nครีม\\nครีษมายัน\\nครึ\\nครึกครื้น\\nครึกโครม\\nครึ่ง\\nครึ่ด\\nครึน\\nครึ้ม\\nครืด\\nครืน\\nครื้น\\nครืนครั่น\\nครื้นครั่น\\nครื้นครึก\\nครื้นเครง\\nครือ\\nครุ\\nครุคระ\\nครุฑ\\nครุ่น\\nครุมเครือ\\nครุย\\nครุวนา\\nครู\\nครู่\\nครูด\\nคฤโฆษ\\nคฤนถ์\\nคฤหบดี\\nคฤหัสถ์\\nคฤหาสน์\\nคลวง\\nคลอ\\nคล้อ\\nคลอก\\nคลอง\\nคล่อง\\nคล้อง\\nคลอด\\nคลอน\\nคล้อย\\nคลอรีน\\nคลอโรฟอร์ม\\nคลอโรฟีลล์\\nคละ\\nคละคลุ้ง\\nคลัก\\nคลั่ก\\nคลัง\\nคลั่ง\\nคลัตช์\\nคลับคล้าย\\nคลับคลา\\nคลา\\nคล้า\\nคลางแคลง\\nคลาด\\nคลาน\\nคลาย\\nคล้าย\\nคล้ายคลึง\\nคล่าว\\nคลำ\\nคล่ำ\\nคล้ำ\\nคลิ้งโคลง\\nคลิด\\nคลินิก\\nคลี\\nคลี่\\nคลึง\\nคลื่น\\nคลุก\\nคลุ้ง\\nคลุบ\\nคลุม\\nคลุ่ม\\nคลุ้ม\\nควง\\nควณ\\nควน\\nควบ\\nควย\\nควร\\nควัก\\nควั่ก\\nควั่งคว้าง\\nควัน\\nควั่น\\nคว้า\\nควาก\\nคว้าง\\nควาญ\\nควาน\\nคว้าน\\nความ\\nควาย\\nคว่าว\\nคว่ำ\\nควินิน\\nควิวคว่าง\\nคหกรรม\\nคหกรรมศาสตร์\\nคหบดี\\nคหัฐ\\nคอ\\nค้อ\\nคอก\\nค็อกคัส\\nค็อกเทล\\nคอเคซอยด์\\nค่องอ้อย\\nคอด\\nคอแดง\\nคอน\\nค่อน\\nค้อน\\nคอนกรีต\\nคอนเดนเซอร์\\nคอนแวนต์\\nคอนเสิร์ต\\nคอม\\nค่อม\\nค้อม\\nคอมพิวเตอร์\\nคอมมานโด\\nคอมมิวนิสต์\\nคอย\\nค่อย\\nค้อย\\nคอยล์\\nคอร์ด\\nคอแลน\\nคอสติกโซดา\\nคะ\\nค่ะ\\nคะไขว่\\nคะค้อย\\nคะคาน\\nคะนน\\nคะนอง\\nคะน้า\\nคะนึง\\nคะเน\\nคะเนงร้าย\\nคะเน็ด\\nคะแนน\\nคะมำ\\nคะยั้นคะยอ\\nคะเยอ\\nคัก\\nคั่ก\\nคัคนะ\\nคัคนัมพร\\nคัคนางค์\\nคัคนานต์\\nคั่ง\\nคังไคย\\nคัจฉ\\nคัณฑมาลา\\nคัณฑสูตร\\nคัด\\nคัดเค้า\\nคัดมอน\\nคัดเม็ง\\nคัทลียา\\nคัน\\nคั่น\\nคั้น\\nคันถรจนาจารย์\\nคันธกุฎี\\nคันธมาทน์\\nคันธารราษฎร์\\nคับ\\nคับค้อน\\nคับคา\\nคับแค\\nคัพภ์\\nคัมภีร์\\nคัมภีรภาพ\\nคัล\\nคั่ว\\nคา\\nค่า\\nค้า\\nค่าคบ\\nคาง\\nค่าง\\nค้าง\\nคางคก\\nค้างคาว\\nคาด\\nคาถา\\nคาทอลิก\\nคาน\\nค้าน\\nคาบ\\nคาพยุต\\nคาม\\nคามวาสี\\nคามณีย์\\nคามภีร์\\nคาย\\nค่าย\\nคาร์บอน\\nคาร์บอเนต\\nคาร์บอลิก\\nคาร์บูเรเตอร์\\nคาร์โบรันดัม\\nคาร์โบไฮเดรต\\nคารม\\nคารวะ\\nคาราเต้\\nคาราวาน\\nคาว\\nค่าว\\nค้าว\\nคาวตอง\\nคาวี\\nคาวุต\\nคาส\\nคำ\\nค่ำ\\nค้ำ\\nคำนวณ\\nคำนวร\\nคำนับ\\nคำนัล\\nคำนึง\\nคำนูณ\\nคำฝอย\\nคำเพลิง\\nคำรน\\nคำรบ\\nคำราม\\nคำแสด\\nคำแหง\\nคำโอง\\nคิก\\nคิง\\nคิด\\nคิมหันต์\\nคิรี\\nคิลาน\\nคิลานะ\\nคิว\\nคิ้ว\\nคี่\\nคีต\\nคีบ\\nคีม\\nคีรี\\nคีรีบูน\\nคึก\\nคึ่ก\\nคึกคัก\\nคืน\\nคืบ\\nคือ\\nคุ\\nคุก\\nคุกกี้\\nคุกคาม\\nคุกพาทย์\\nคุ้ง\\nคุณ\\nคุด\\nคุดทะราด\\nคุต\\nคุตติ\\nคุ่น\\nคุ้น\\nคุป\\nคุปต์\\nคุปติ\\nคุม\\nคุ่ม\\nคุ้ม\\nคุย\\nคุ้ย\\nคุยหฐาน\\nคุยหประเทศ\\nคุรุ\\nคุลา\\nคุลิก่า\\nคุลีการ\\nคุหา\\nคู\\nคู่\\nคู้\\nคูณ\\nคูถ\\nคูน\\nคูปอง\\nคูเรียม\\nคูหา\\nเค้ก\\nเค้เก้\\nเค้ง\\nเคณฑะ\\nเคด\\nเค็ด\\nเคน\\nเค้น\\nเคเบิล\\nเค็ม\\nเคมี\\nเคย\\nเครง\\nเคร่ง\\nเครงครา\\nเครงครำ\\nเครดิต\\nเครน\\nเครา\\nเคร่า\\nเคราหณี\\nเคราะห์\\nเครียด\\nเครียว\\nเครือ\\nเครื่อง\\nเคล้ง\\nเคล็ด\\nเคล้น\\nเคล้า\\nเคล่าคล่อง\\nเคลิบเคลิ้ม\\nเคลิ้ม\\nเคลีย\\nเคลื่อน\\nเคลือบ\\nเคว้ง\\nเคหะ\\nเคหา\\nเคอะ\\nเค้า\\nเคาน์เตอร์\\nเคารพ\\nเคาะ\\nเคาะแคะ\\nเคียง\\nเคียด\\nเคียน\\nเคียม\\nเคี่ยม\\nเคียร\\nเคียว\\nเคี่ยว\\nเคี้ยว\\nเคือง\\nแค\\nแค่\\nแค้\\nแคแล\\nแคดเมียม\\nแค็ตตาล็อก\\nแคแตร\\nแคโทด\\nแคน\\nแค่น\\nแค้น\\nแคบ\\nแคบหมู\\nแคปซูล\\nแคม\\nแคร่\\nแครก\\nแครง\\nแคระ\\nแคลคูลัส\\nแคลง\\nแคลเซียม\\nแคลน\\nแคล้ว\\nแคล่วคล่อง\\nแคลอรี\\nแคลิฟอร์เนียม\\nแคว\\nแควก\\nแคว้น\\nแคแสด\\nแคะ\\nโค\\nโคก\\nโคเคน\\nโค่ง\\nโค้ง\\nโคจร\\nโคเซแคนต์\\nโคไซน์\\nโคตร\\nโคแทนเจนต์\\nโคธา\\nโคน\\nโค่น\\nโคบอลต์\\nโคปผกะ\\nโคม\\nโคม่า\\nโครก\\nโครกคราก\\nโครง\\nโคร่ง\\nโคร่งคร่าง\\nโครม\\nโครเมียม\\nโครโมโซม\\nโคราช\\nโครำ\\nโคล\\nโคลง\\nโคลน\\nโควตา\\nโคออร์ดิเนต\\nใคร\\nใคร่\\nใคร่ครวญ\\nไค\\nไค้\\nไคร้\\nไคร้เครือ\\nไคล\\nไคล้\\nฆนะ\\nฆราวาส\\nฆ้อง\\nฆ่า\\nฆาต\\nฆาน\\nฆานินทรีย์\\nเฆี่ยน\\nโฆรวิส\\nโฆษก\\nโฆษณา\\nโฆษะ\\nโฆษิต\\nงก\\nงง\\nงด\\nงดงาม\\nงบ\\nงม\\nงวง\\nง่วง\\nงวด\\nง่วน\\nง้วน\\nงวยงง\\nงอ\\nง้อ\\nงอก\\nงอกแงก\\nง่อกแง่ก\\nง่อง\\nง่องแง่ง\\nงอแง\\nงอด\\nงอดแงด\\nงอน\\nง่อน\\nง่อนแง่น\\nงอนหง่อ\\nงอบ\\nงอม\\nง้อม\\nงอย\\nง่อย\\nงัก\\nงั่ก\\nงั่ง\\nงัด\\nงัน\\nงันงก\\nงับ\\nงัว\\nงั่ว\\nงัวเงีย\\nงา\\nง่า\\nง้าง\\nงาน\\nง่าน\\nงาบ\\nงาม\\nง่าม\\nงาย\\nง่าย\\nง้าว\\nงำ\\nง่ำ\\nง้ำ\\nงิ้ว\\nงี่เง่า\\nงีบ\\nงึก\\nงึน\\nงึม\\nงุด\\nงุนงง\\nงุ่นง่าน\\nงุบ\\nงุบงิบ\\nงุ้ม\\nงุ่มง่าม\\nงุย\\nงู\\nงูบ\\nงูสวัด\\nเงก\\nเงย\\nเงอะ\\nเงอะงะ\\nเงา\\nเง่า\\nเง้า\\nเงาะ\\nเงิน\\nเงี่ยง\\nเงี่ยน\\nเงียบ\\nเงี้ยว\\nเงี่ยหู\\nเงื้อ\\nเงือก\\nเงื่อง\\nเงือด\\nเงื่อน\\nเงือบ\\nเงื้อม\\nแง\\nแง่\\nแง่ง\\nแง่น\\nแง้ม\\nแงะ\\nโง\\nโง่\\nโงก\\nโงกเงก\\nโงง\\nโง่ง\\nโง้ง\\nโงงเงง\\nโง่งเง่ง\\nโงเง\\nโงน\\nโงนเงน\\nไง้\\nจก\\nจง\\nจ่ง\\nจงกรม\\nจงกล\\nจงกลนี\\nจงโคร่ง\\nโจงโคร่ง\\nจงอร\\nจงอาง\\nจด\\nจดุรงค์\\nจตุปัจจัย\\nจตุลังคบาท\\nจตุโลกบาล\\nจตุสดมภ์\\nจตุตถ\\nจตุตถี\\nจตุร\\nจตุรงค์\\nจตุรพักตร์\\nจตุรพิธ\\nจตุรพิธพร\\nจน\\nจบ\\nจม\\nจ่ม\\nจมร\\nจมรี\\nจมูก\\nจยุติ\\nจร\\nจรณะ\\nจรด\\nจรรจา\\nจรรโจษ\\nจรรม\\nจรรยา\\nจรรโลง\\nจรลี\\nจรวจ\\nจรวด\\nจรส\\nจรอก\\nจระเข้\\nจระนำ\\nจระบี\\nจรัล\\nจรัส\\nจราจร\\nจราญ\\nจริก\\nจริง\\nจริต\\nจริม\\nจริยธรรม\\nจริยวัตร\\nจริยาวัตร\\nจริยศาสตร์\\nจริยศึกษา\\nจริยา\\nจรุง\\nจรูง\\nจรูญ\\nจเร\\nจล\\nจลนพลศาสตร์\\nจลนศาสตร์\\nจลนี\\nจลาจล\\nจวก\\nจ๊วก\\nจวง\\nจ้วง\\nจ๋วง\\nจวด\\nจวน\\nจวบ\\nจวัก\\nจอ\\nจ่อ\\nจ้อ\\nจ๋อ\\nจอก\\nจ้อก\\nจ๊อก\\nจ้อกแจ้ก\\nจอง\\nจ้อง\\nจ๋อง\\nจ้องเต\\nจองเปรียง\\nจ้องหน่อง\\nจองหอง\\nจอแจ\\nจ๋อแจ๋\\nจอด\\nจอน\\nจ้อน\\nจอนจ่อ\\nจอบ\\nจอม\\nจ่อม\\nจอมสุรางค์\\nจ่อย\\nจ้อย\\nจ๋อย\\nจอแส\\nจะ\\nจ้ะ\\nจ๊ะ\\nจ๋ะ\\nจะกละ\\nจะกลาม\\nจะกูด\\nจะขาบ\\nจะเข้\\nจะเข็บ\\nจะงอย\\nจะจะ\\nจ๊ะจ๋า\\nจะแจ้ง\\nจะแจ่ม\\nจะละเม็ด\\nจะละหวั่น\\nจัก\\nจั้ก\\nจักกาย\\nจั๊กกิ้ม\\nจักขุ\\nจักจั่น\\nจักจี้\\nจั๊กจี้\\nจั๊กเดียม\\nจักร\\nจักรพาก\\nจักรวาก\\nจักริน\\nจักรี\\nจั๊กเล้อ\\nจักษุ\\nจักแหล่น\\nจัง\\nจั้ง\\nจั๋ง\\nจังกวด\\nจังกอบ\\nจังก้า\\nจังกูด\\nจังโกฏก์\\nจังงัง\\nจั้งมั่ง\\nจังไร\\nจังหนับ\\nจังหรีด\\nจังหวะ\\nจังหวัด\\nจังหัน\\nจัญไร\\nจัณฑ์\\nจัณฑาล\\nจัด\\nจัตตาฬีสะ\\nจัตวา\\nจัตุ\\nจัตุรงค์\\nจัตุรัส\\nจัตุลังคบาท\\nจัตุโลกบาล\\nจัตุสดมภ์\\nจัน\\nจั่น\\nจันโจษ\\nจั่นดิน\\nจันท์\\nจันทน์\\nจันทร์\\nจันทรคติ\\nจันทรคราส\\nจันทรุปราคา\\nจันทรเม็ด\\nจันทวาร\\nจันทัน\\nจันอับ\\nจับ\\nจับกัง\\nจับฉ่าย\\nจับเดิม\\nจับปิ้ง\\nจับยี่กี\\nจัมบก\\nจัมปกะ\\nจัมปา\\nจัมมะ\\nจัว\\nจั่ว\\nจั๊วะ\\nจา\\nจ่า\\nจ้า\\nจ๋า\\nจาก\\nจากพาก\\nจาคะ\\nจาคี\\nจาง\\nจ่าง\\nจ้าง\\nจางปาง\\nจางวาง\\nจาด\\nจาตุรงค์\\nจาตุรนต์\\nจาตุรันต์\\nจาน\\nจ้าน\\nจาบ\\nจาบัล\\nจาบัลย์\\nจาป\\nจาม\\nจ่ามงกุฎ\\nจามจุรี\\nจามร\\nจามรี\\nจามีกร\\nจ่าย\\nจาร\\nจ่ารง\\nจารวาก\\nจาระไน\\nจาระบี\\nจาริก\\nจารึก\\nจารี\\nจารีต\\nจารุ\\nจ้าละหวั่น\\nจาว\\nจ้าว\\nจ่าหวัก\\nจำ\\nจ้ำ\\nจำกัด\\nจำงาย\\nจ้ำจี้\\nจำเจ\\nจำเดิม\\nจำทวย\\nจำนง\\nจำนน\\nจำนรรจ์\\nจำนรรจา\\nจำนวน\\nจำนอง\\nจำนัล\\nจำนำ\\nจำเนียน\\nจำเนียม\\nจำเนียร\\nจำแนก\\nจำบ่ม\\nจำบัง\\nจ้ำเบ้า\\nจำปา\\nจำปาดะ\\nจำปี\\nจำปูน\\nจำพวก\\nจำเพาะ\\nจ้ำม่ำ\\nจำรัส\\nจำราญ\\nจำรูญ\\nจำเริญ\\nจำเรียง\\nจำลอง\\nจำเลย\\nจำเลาะ\\nจำแลง\\nจำแล่น\\nจำหนับ\\nจ๋ำหนับ\\nจำหน่าย\\nจำหระ\\nจำหล่อ\\nจำหลัก\\nจำเหียง\\nจำอวด\\nจิ\\nจิก\\nจิ้งโกร่ง\\nจิ้งจก\\nจิงจ้อ\\nจิ้งจอก\\nจิงจัง\\nจิ้งจัง\\nจิงโจ้\\nจิ้งหรีด\\nจิ้งเหลน\\nจิต\\nจิตกาธาน\\nจิตต์\\nจิตร\\nจิตรจุล\\nจิตระ\\nจิตรา\\nจินเจา\\nจินดา\\nจินดาหนา\\nจินดาหรา\\nจินต์\\nจิบ\\nจิปาถะ\\nจิ่ม\\nจิ้ม\\nจิ้มก้อง\\nจิ้มลิ้ม\\nจิรกาล\\nจิ๋ว\\nจี\\nจี่\\nจี้\\nจี๋\\nจี๋จ้อ\\nจีแจ๊บ\\nจี๊ด\\nจีน\\nจีนแส\\nจีบ\\nจีโบ\\nจีม\\nจีวร\\nจึง\\nจึ่ง\\nจึ้ง\\nจืด\\nจุ\\nจุก\\nจุ๊กกรู๊\\nจุกจิก\\nจุกชี\\nจุกผาม\\nจุกโรหินี\\nจุ่ง\\nจุ๋งจิ๋ง\\nจุฑา\\nจุณ\\nจุณณียบท\\nจุด\\nจุติ\\nจุตูปปาตญาณ\\nจุทส\\nจุน\\nจุ่น\\nจุ้น\\nจุนจู๋\\nจุ้นจู๊\\nจุนทการ\\nจุนสี\\nจุบ\\nจุ๊บ\\nจุบจิบ\\nจุ๊บแจง\\nจุ่ม\\nจุ้ม\\nจุ๋มจิ๋ม\\nจุมพฏ\\nจุมพรวด\\nจุมพล\\nจุมพิต\\nจุมโพล่\\nจุ้ย\\nจุรณ\\nจูรณ\\nจุรี\\nจุไร\\nจุล\\nจุลจอมเกล้า\\nจุลวงศ์\\nจุฬา\\nจุฬาราชมนตรี\\nจุฬาลัมพา\\nจุฬาลำพา\\nจู\\nจู่\\nจู้\\nจู๋\\nจูง\\nจู้จี้\\nจู๋จี๋\\nจู๊ด\\nจูบ\\nเจ\\nเจ๊ก\\nเจ่ง\\nเจ้ง\\nเจ๊ง\\nเจ๋ง\\nเจ็ด\\nเจ็ดตะคลี\\nเจดีย์\\nเจดียสถาน\\nเจต\\nเจตนา\\nเจตพังคี\\nเจตมูลเพลิง\\nเจตสิก\\nเจโตวิมุติ\\nเจน\\nเจ็บ\\nเจรจา\\nเจริญ\\nเจริด\\nเจรียง\\nเจลียง\\nเจว็ด\\nเจษฎา\\nเจ๊สัว\\nเจอ\\nเจ่อ\\nเจ๋อ\\nเจ๋อเจ๊อะ\\nเจอร์เมเนียม\\nเจอะ\\nเจา\\nเจ่า\\nเจ้า\\nเจ๊า\\nเจาะ\\nเจิ่ง\\nเจิด\\nเจิ่น\\nเจิม\\nเจีย\\nเจียง\\nเจียด\\nเจียน\\nเจี๋ยน\\nเจี๊ยบ\\nเจียม\\nเจี๋ยมเจี้ยม\\nเจียร\\nเจียระไน\\nเจียระบาด\\nเจียว\\nเจี๊ยวจ๊าว\\nเจือ\\nเจื่อน\\nเจื้อย\\nเจือสม\\nแจ\\nแจ้\\nแจ๋\\nแจก\\nแจกัน\\nแจง\\nแจ่ง\\nแจ้ง\\nแจงลอน\\nแจ๊ด\\nแจ๊ดแจ๋\\nแจตร\\nแจ้น\\nแจบ\\nแจ่ม\\nแจรง\\nแจว\\nแจ่ว\\nแจ้ว\\nแจ๋ว\\nแจะ\\nโจก\\nโจ๊ก\\nโจง\\nโจ่งครึ่ม\\nโจ๋งครึ่ม\\nโจ่งครุ่ม\\nโจ๋งเจ๋ง\\nโจ่งแจ้ง\\nโจท\\nโจทก์\\nโจทนา\\nโจทย์\\nโจน\\nโจม\\nโจร\\nโจล\\nโจษ\\nโจษจัน\\nใจ\\nไจ\\nไจ้\\nฉก\\nฉกรรจ์\\nฉกษัตริย์\\nฉกาจ\\nฉกามาพจร\\nฉกามาวจร\\nฉง\\nฉงน\\nฉงาย\\nฉทึง\\nฉนวน\\nฉนัง\\nฉนาก\\nฉนำ\\nฉบัง\\nฉบัด\\nฉบับ\\nฉบำ\\nฉม\\nฉมบ\\nฉมวก\\nฉมวย\\nฉม่อง\\nฉมัง\\nฉมัน\\nฉมา\\nฉมำ\\nฉล\\nฉลวย\\nฉลอง\\nฉลอม\\nฉลัก\\nฉลับ\\nฉลาก\\nฉลาง\\nฉลาด\\nฉลาม\\nฉลาย\\nฉลิว\\nฉลีก\\nฉลุ\\nฉลู\\nฉวย\\nฉวะ\\nฉวัดเฉวียน\\nฉวาง\\nฉวี\\nฉศก\\nฉ้อ\\nฉอก\\nฉ่อง\\nฉอด\\nฉ่อย\\nฉอเลาะ\\nฉะ\\nฉะฉาด\\nฉะฉาน\\nฉะฉ่ำ\\nฉะฉี่\\nฉะเฉื่อย\\nฉะนั้น\\nฉะนี้\\nฉะอ้อน\\nฉักกะ\\nฉัฐ\\nฉัด\\nฉัตร\\nฉัททันต์\\nฉัน\\nฉันท\\nฉันท์\\nฉันทะ\\nฉันทา\\nฉันทาคติ\\nฉันทานุมัติ\\nฉับ\\nฉัพพรรณรังสี\\nฉัยยา\\nฉ่า\\nฉาก\\nฉาง\\nฉ่าง\\nฉ่าฉาว\\nฉาด\\nฉาดฉาน\\nฉาตกภัย\\nฉาน\\nฉาบ\\nฉาบฉวย\\nฉาย\\nฉายา\\nฉาว\\nฉ่ำ\\nฉำฉา\\nฉำแฉะ\\nฉิ่ง\\nฉิน\\nฉินท์\\nฉินทฤกษ์\\nฉิบ\\nฉิมพลี\\nฉิว\\nฉี่\\nฉีก\\nฉีด\\nฉุ\\nฉุก\\nฉุด\\nฉุน\\nฉุป\\nฉุป\\nฉุย\\nฉุยฉาย\\nฉู่\\nฉู่ฉี่\\nฉูด\\nฉูดฉาด\\nเฉ\\nเฉก\\nเฉโก\\nเฉ่ง\\nเฉด\\nเฉท\\nเฉนียน\\nเฉพาะ\\nเฉย\\nเฉลย\\nเฉลว\\nเฉลา\\nเฉลิม\\nเฉลี่ย\\nเฉลียง\\nเฉลี่ยง\\nเฉลียบ\\nเฉลียว\\nเฉวียง\\nเฉวียน\\nเฉอะแฉะ\\nเฉา\\nเฉาก๊วย\\nเฉาฮื้อ\\nเฉาะ\\nเฉิด\\nเฉิบ\\nเฉียง\\nเฉียงพร้านางแอ\\nเฉียด\\nเฉียบ\\nเฉียว\\nเฉี่ยว\\nเฉือน\\nเฉื่อย\\nแฉ\\nแฉ่\\nแฉก\\nแฉง\\nแฉ่ง\\nแฉลบ\\nแฉล้ม\\nแฉะ\\nโฉ\\nโฉ่\\nโฉเก\\nโฉ่งฉ่าง\\nโฉงเฉง\\nโฉด\\nโฉนด\\nโฉบ\\nโฉเบ๊\\nโฉม\\nโฉลก\\nไฉน\\nไฉไล\\nชก\\nชคัตตรัย\\nชง\\nชงโค\\nชงฆ์\\nชงฆา\\nชงโลง\\nชฎา\\nชฎามังษี\\nชฎามังสี\\nชฎิล\\nชด\\nชน\\nชนก\\nชนนี\\nชนม์\\nชนวน\\nชนะ\\nชนัก\\nชนา\\nชนาง\\nชนิด\\nชเนตตี\\nชบา\\nชม\\nชมดชม้อย\\nชมนาด\\nชมพู\\nชมพู่\\nชมรม\\nชม้อย\\nชม้าย\\nชไม\\nชยา\\nชโย\\nชรทึง\\nชรริน\\nชรอุ่ม\\nชระล้ำ\\nชระลุ\\nชระอาบ\\nชระเอม\\nชรัด\\nชรา\\nชล\\nชโลง\\nชโลม\\nช่วง\\nชวด\\nชวน\\nชวย\\nช่วย\\nชวร\\nชวลิต\\nชวา\\nชวาล\\nชวาลา\\nช่อ\\nชอก\\nช็อก\\nช็อกโกเลต\\nช็อกโกแลต\\nชอง\\nช่อง\\nช้อง\\nชองระอา\\nชอน\\nช่อน\\nช้อน\\nชอบ\\nชอม\\nช้อย\\nชอล์ก\\nชอ่ำ\\nชอุ่ม\\nชะ\\nชะคราม\\nชะงอก\\nชะง่อน\\nชะงัก\\nชะงัด\\nชะง้ำ\\nชะงุ้ม\\nชะเง้อ\\nชะเงื้อม\\nชะแง้\\nชะโงก\\nชะฉ่า\\nชะช่อง\\nชะชะ\\nชะช้า\\nชะโด\\nชะตา\\nชะต้า\\nชะนี\\nชะเนาะ\\nชะเนียง\\nชะพลู\\nชะเพลิง\\nชะมด\\nชะมบ\\nชะมวง\\nชะมัง\\nชะมัด\\nชะแม่\\nชะรอย\\nชะลอ\\nชะลอม\\nชะล่า\\nชะลาน\\nชะลิน\\nชะลูด\\nชะเลง\\nชะเลย\\nชะแล็ก\\nชะแลง\\nชะวาก\\nชะวาด\\nชะเวิกชะวาก\\nชะแวง\\nชะอม\\nชะอ้อน\\nชะเอม\\nชะโอน\\nชัก\\nชักคราม\\nชักช้า\\nชัง\\nชั่ง\\nชังคา\\nชังฆ\\nชัชวาล\\nชัฏ\\nชัด\\nชัดช้า\\nชัน\\nชั้น\\nชันกาด\\nชันชี\\nชันตุ\\nชันนะตุ\\nชันนุ\\nชันโรง\\nชันษา\\nชันสูตร\\nชัปนะ\\nชัพ\\nชัมพูนท\\nชัย\\nชัยพฤกษ์\\nชัยภูมิ\\nชัลลุกา\\nชั่ว\\nชั้ว\\nชัวชม\\nชา\\nช้า\\nชาคระ\\nชาคริต\\nชาคริยานุโยค\\nช่าง\\nช้าง\\nช้าช่อน\\nชาญ\\nชาด\\nชาดก\\nชาต\\nชาตบุษย์\\nชาตรี\\nชาตะ\\nชาตา\\nชาติ\\nชาน\\nชานุ\\nช้าปี่\\nชาปีไหน\\nช้าแป้น\\nช้าพลู\\nชาม\\nชามพูนท\\nชามาดร\\nชามาดา\\nชามาตุ\\nชาย\\nชายา\\nชาล\\nชาลา\\nชาลินี\\nช้าเลือด\\nชาว\\nชาวี\\nชำ\\nช่ำ\\nช้ำ\\nชำงัด\\nชำงาย\\nช่ำชอง\\nชำนะ\\nชำนัญ\\nชำนัน\\nชำนาญ\\nชำนิ\\nชำเนียร\\nชำมะนาด\\nชำมะเลียง\\nชำร่วย\\nชำระ\\nช้ำรั่ว\\nชำรุด\\nชำเรา\\nชำเราะ\\nชำแรก\\nชำแระ\\nชำเลือง\\nชำแหละ\\nชิ\\nชิง\\nชิ่ง\\nชิงชัน\\nชิงช้า\\nชิงช้าชาลี\\nชิงชี่\\nชิงฮื้อ\\nชิชะ\\nชิชิ\\nชิณณะ\\nชิด\\nชิเดนทรีย์\\nชิต\\nชิตินทรีย์\\nชิน\\nชิ้น\\nชินโต\\nชิโนรส\\nชิม\\nชิมแปนซี\\nชิยา\\nชิรณะ\\nชิระ\\nชิวหา\\nชิสา\\nชี\\nชี่\\nชี้\\nชีปะขาว\\nชีผะขาว\\nชีผ้าขาว\\nชีพ\\nชีฟอง\\nชีรณ\\nชีระ\\nชีวเคมี\\nชีวประวัติ\\nชีวภาพ\\nชีววิทยา\\nชีวะ\\nชีวัน\\nชีวา\\nชีวาตม์\\nชีวาลัย\\nชีวิต\\nชีวิตักษัย\\nชีวิน\\nชีวี\\nชืด\\nชื่น\\nชื้น\\nชื่อ\\nชุก\\nชุกชี\\nชุ้ง\\nชุณห\\nชุด\\nชุติ\\nชุน\\nชุบ\\nชุม\\nชุ่ม\\nชุมนุม\\nชุมพร\\nชุมพา\\nชุมแพรก\\nชุมรุม\\nชุมแสง\\nชุมเห็ด\\nชุ่ย\\nชุลมุน\\nชุลี\\nชุษณะ\\nชู\\nชู้\\nเช็ค\\nเช้ง\\nเช้งวับ\\nเชงเลง\\nเช็ด\\nเชน\\nเช่น\\nเชย\\nเชลง\\nเชลย\\nเชลแล็ก\\nเชลียง\\nเชวง\\nเชษฐะ\\nเชษฐา\\nเชอ\\nเช่า\\nเช้า\\nเชาว์\\nเชาวน์\\nเชิง\\nเชิญ\\nเชิด\\nเชิ้ต\\nเชียง\\nเชี่ยน\\nเชียบ\\nเชี่ยม\\nเชียร\\nเชียร์\\nเชียว\\nเชี่ยว\\nเชื่อ\\nเชื้อ\\nเชือก\\nเชื่อง\\nเชือด\\nเชือน\\nเชื่อม\\nแช\\nแช่\\nแช่ง\\nแชงมา\\nแชบ๊วย\\nแช่ม\\nแชร์\\nแชล่ม\\nแชสซี\\nแชะ\\nโชก\\nโชค\\nโชงโลง\\nโชดก\\nโชดึก\\nโชต\\nโชตก\\nโชติ\\nโชติก\\nโชน\\nโชมโรม\\nโชย\\nโชยงการ\\nโชยชาย\\nโชยติส\\nโชว์\\nใช่\\nใช้\\nไช\\nไชนะ\\nไชย\\nไชโย\\nซก\\nซ่ก\\nซงดำ\\nซ่งฮื้อ\\nซด\\nซน\\nซ้น\\nซบ\\nซม\\nซวดเซ\\nซวน\\nซวย\\nซอ\\nซอก\\nซอง\\nซ่อง\\nซ้อง\\nซองแมว\\nซ้องแมว\\nซอน\\nซ่อน\\nซ้อน\\nซอม\\nซ่อม\\nซ้อม\\nซอมซ่อ\\nซอย\\nซอส\\nซัก\\nซักส้าว\\nซัง\\nซั้ง\\nซัด\\nซับ\\nซัลฟา\\nซั้ว\\nซา\\nซ่า\\nซาก\\nซาง\\nซ่าง\\nซาด\\nซาน\\nซ่าน\\nซาบซ่าน\\nซาบซึ้ง\\nซ่าโบะ\\nซาแมเรียม\\nซ้าย\\nซาลาเปา\\nซาว\\nซ่าหริ่ม\\nซำ\\nซ้ำ\\nซิ\\nซี\\nซิก\\nซิกข์\\nซิกซี้\\nซิกแซ็ก\\nซิการ์\\nซิงโคนา\\nซิ่น\\nซินนามิก\\nซินแส\\nซิบ\\nซิป\\nซิฟิลิส\\nซิลิคอน\\nซิว\\nซี่\\nซีก\\nซีเซียม\\nซีด\\nซี้ด\\nซีนอน\\nซีป่าย\\nซีเมนต์\\nซีเรียม\\nซีลีเนียม\\nซีอิ๊ว\\nซึก\\nซึง\\nซึ่ง\\nซึ้ง\\nซึม\\nซื่อ\\nซื้อ\\nซุก\\nซุง\\nซุน\\nซุบ\\nซุป\\nซุ่ม\\nซุ้ม\\nซุ่มซ่าม\\nซุย\\nซู่\\nซูโครส\\nซูด\\nซู้ด\\nซูดซาด\\nซูบ\\nเซ\\nเซ็ก\\nเซแคนต์\\nเซ็ง\\nเซ่ง\\nเซ้ง\\nเซ็งแซ่\\nเซต\\nเซน\\nเซ็น\\nเซ่น\\nเซนติกรัม\\nเซนติเกรด\\nเซนติเมตร\\nเซนติลิตร\\nเซปักตะกร้อ\\nเซราะ\\nเซรุ่ม\\nเซลเซียส\\nเซลล์\\nเซลลูลอยด์\\nเซลลูโลส\\nเซ่อ\\nเซอร์โคเนียม\\nเซอะ\\nเซา\\nเซ้าซี้\\nเซาะ\\nเซิง\\nเซิ้ง\\nเซียน\\nเซียบ\\nเซียมซี\\nเซียว\\nเซี่ยว\\nเซี่ยวกาง\\nเซื่อง\\nแซ\\nแซ่\\nแซ็กคาริน\\nแซง\\nแซงแซว\\nแซด\\nแซบ\\nแซม\\nแซยิด\\nแซ่ว\\nแซะ\\nโซ\\nโซ่\\nโซก\\nโซ่ง\\nโซงโขดง\\nโซเซ\\nโซดา\\nโซเดียม\\nโซม\\nโซรม\\nโซลา\\nไซ\\nไซ้\\nไซเกิล\\nไซโคลน\\nไซน์\\nไซยาไนด์\\nไซร้\\nไซเรน\\nไซโล\\nฌาน\\nฌาปน\\nฌาปนกิจ\\nฌาปนสถาน\\nเฌอ\\nเฌอเอม\\nญวน\\nญัตติ\\nญาณ\\nญาติ\\nญานาซะฮ์\\nญิบ\\nญี่ปุ่น\\nเญยธรรม\\nไญยธรรม\\nฎีกา\\nฐกัด\\nฐากูร\\nฐาน\\nฐานะ\\nฐานันดร\\nฐานานุกรม\\nฐานานุรูป\\nฐานานุศักดิ์\\nฐานียะ\\nฐาปน\\nฐาปนา\\nฐายี\\nฐิต\\nฐิติ\\nฑาหก\\nฑาหะ\\nเฒ่า\\nณรงค์\\nเณร\\nดก\\nดง\\nด้ง\\nด้น\\nดนโด่\\nดนตรี\\nดนัย\\nดนุ\\nดนู\\nดบัสวิน\\nดบัสวี\\nดม\\nดรงค์\\nดรณี\\nดรรชนี\\nดราฟต์\\nดรุณ\\nดรุณี\\nดล\\nดวง\\nด้วง\\nดวด\\nด่วน\\nด้วน\\nด้วย\\nดอก\\nดอง\\nด่อง\\nด้อง\\nดองฉาย\\nดองดึง\\nดอด\\nดอน\\nด่อน\\nดอม\\nด้อม\\nดอย\\nด้อย\\nดอลลาร์\\nดะ\\nดะโต๊ะ\\nดะหมัง\\nดัก\\nดักดาน\\nดักแด้\\nดัง\\nดั่ง\\nดั้ง\\nดัชนี\\nดัด\\nดัตช์\\nดัน\\nดั้น\\nดับ\\nดัมพ์\\nดั้วเดี้ย\\nดัสกร\\nดา\\nด่า\\nดาก\\nด่าง\\nด้าง\\nดาด\\nดาน\\nด่าน\\nด้าน\\nดาบ\\nดาบส\\nดาม\\nด้าม\\nด้ามจิ้ว\\nดามพ์\\nดาย\\nด้าย\\nดารกะ\\nดารณี\\nดารดาษ\\nดาระ\\nดารา\\nดาล\\nดาลัด\\nดาว\\nด่าว\\nด้าว\\nดาวดึงส์\\nดาวบส\\nดาษ\\nดาษดา\\nดำ\\nด่ำ\\nด้ำ\\nดำกล\\nดำเกิง\\nดำแคง\\nดำดง\\nดำนาณ\\nดำเนิน\\nดำบล\\nดำรง\\nดำรวจ\\nดำรัส\\nดำริ\\nดำรี\\nดำรู\\nดำฤษณา\\nดำเลิง\\nดิก\\nดิ่ง\\nดิฉัน\\nดิฐ\\nดิตถ์\\nดิถี\\nดิน\\nดิ้น\\nดิบ\\nดิรัจฉาน\\nดิลก\\nดิ่ว\\nดิ้ว\\nดิ้วเดี้ยว\\nดิษฐ์\\nดิสโพรเซียม\\nดี\\nดีเซล\\nดีด\\nดีดีที\\nดีบุก\\nดีปลี\\nดีเปรสชัน\\nดีหมี\\nดีหลี\\nดึก\\nดึง\\nดึ่ง\\nดึ่ม\\nดื่น\\nดื่ม\\nดือ\\nดื้อ\\nดุ\\nดุก\\nดุกดิก\\nดุกทะเล\\nดุ้ง\\nดุ้งดิ้ง\\nดุจ\\nดุด\\nดุน\\nดุ้น\\nดุบ\\nดุม\\nดุ่ม\\nดุ่ย\\nดุรงค์\\nดุริยะ\\nดุริยางค์\\nดุริยางคศาสตร์\\nดุริยางคศิลป์\\nดุล\\nดุษฎี\\nดุษณี\\nดุษณีภาพ\\nดุษิต\\nดุสิต\\nดุเหว่า\\nดู\\nดูกค่าง\\nดูกร\\nดูด\\nดูรา\\nดูแล\\nเด\\nเด่\\nเดก\\nเด็ก\\nเดกซ์โทรส\\nเดคากรัม\\nเดคาเมตร\\nเดคาลิตร\\nเด้ง\\nเด็จ\\nเดช\\nเดชน์\\nเดชนะ\\nเดชะ\\nเดโช\\nเดซิกรัม\\nเดซิเมตร\\nเดซิลิตร\\nเด็ด\\nเดน\\nเด่น\\nเดนมาร์ก\\nเดรัจฉาน\\nเด๋อ\\nเด๋อด๋า\\nเดา\\nเด้า\\nเดาะ\\nเดิน\\nเดิ่น\\nเดิม\\nเดียง\\nเดียด\\nเดียรดาษ\\nเดียรถีย์\\nเดียรัจฉาน\\nเดียว\\nเดี่ยว\\nเดี๋ยว\\nเดียะ\\nเดื่อ\\nเดือก\\nเดื่อง\\nเดือด\\nเดือน\\nเดือย\\nแด\\nแด่\\nแดก\\nแด็ก\\nแดกงา\\nแดกแด้\\nแดง\\nแดด\\nแดน\\nแด่น\\nแด่ว\\nแดะ\\nแดะแด๋\\nโด\\nโด่\\nโดกเดก\\nโด่ง\\nโดด\\nโดน\\nโดม\\nโดมร\\nโดย\\nโดรณ\\nใด\\nได\\nได้\\nไดแซ็กคาไรด์\\nไดนาโม\\nไดนาไมต์\\nไดโนเสาร์\\nไดเรกตริกซ์\\nตก\\nต๊กโต\\nตง\\nต๋ง\\nตงฉิน\\nตงิด\\nตงุ่น\\nตด\\nตติย\\nตถาคต\\nตน\\nต้น\\nตนัย\\nตนุ\\nตบ\\nตบะ\\nตปนียะ\\nตม\\nต้ม\\nตมูก\\nตยาคี\\nตรง\\nตรณี\\nตรม\\nตรรก\\nตรรกะ\\nตรลบ\\nตรลอด\\nตรลาด\\nตรวจ\\nตรวน\\nตรอก\\nตรอง\\nตรอมใจ\\nตรอมตรม\\nตระ\\nตระกล\\nตระกวน\\nตระกอง\\nตระการ\\nตระกูล\\nตระคัร\\nตระเตรียม\\nตระนาว\\nตระบก\\nตระบอก\\nตระบอง\\nตระบัด\\nตระบัน\\nตระเบ็ง\\nตระแบก\\nตระแบง\\nตระโบม\\nตระพอง\\nตระพัง\\nตระลาการ\\nตระวัน\\nตระเว็ด\\nตระเวน\\nตระสัก\\nตระหง่าน\\nตระหนก\\nตระหนัก\\nตระหน่ำ\\nตระหนี่\\nตรัง\\nตรังค์\\nตรับ\\nตรับฟัง\\nตรัย\\nตรัยตรึงศ์\\nตรัส\\nตรัสสา\\nตรา\\nตรากตรำ\\nตราชู\\nตราบ\\nตราสัง\\nตรำ\\nตริ\\nตริว\\nตรี\\nตรีปวาย\\nตรีพิธพรรณ\\nตรียัมปวาย\\nตรึก\\nตรึง\\nตรุ\\nตรุณ\\nตรุณะ\\nตรุษ\\nตรู\\nตรู่\\nตฤณ\\nตฤตีย\\nตฤษณา\\nตลก\\nตลบ\\nตลอด\\nตลับ\\nตลาด\\nตลิ่ง\\nตลึง\\nตวง\\nต่วน\\nต้วมเตี้ยม\\nตวัก\\nตวัด\\nตวาด\\nตอ\\nตอม่อ\\nต่อ\\nต้อ\\nตอก\\nต๊อก\\nต๊อกต๋อย\\nตอง\\nต้อง\\nตองกราย\\nต้องเต\\nตองแตก\\nต่องแต่ง\\nตองเหลือง\\nตอด\\nตอน\\nต้อน\\nตอบ\\nตอเบา\\nตอม\\nต่อม\\nต๋อม\\nต่อย\\nต้อย\\nต้อยตริ่ง\\nต้อยติ่ง\\nต้อยตีวิด\\nตอแย\\nตอร์ปิโด\\nต่อไส้\\nตอแหล\\nตะ\\nตะกรน\\nตะกร้อ\\nตะกรัน\\nตะกรับ\\nตะกร้า\\nตะกราม\\nตะกรุด\\nตะกรุม\\nตะกรุมตะกราม\\nตะกละ\\nตะกลาม\\nตะกวด\\nตะกอ\\nตะกอน\\nตะกัง\\nตะกั่ว\\nตะกาง\\nตะกาด\\nตะกาย\\nตะกาว\\nตะกุกตะกัก\\nตะกุย\\nตะกู\\nตะกูด\\nตะเกียกตะกาย\\nตะเกียง\\nตะเกียบ\\nตะแก\\nตะแก่\\nตะแกรง\\nตะโก\\nตะโก้\\nตะโกก\\nตะโกน\\nตะโกรง\\nตะโกรม\\nตะไกร\\nตะขบ\\nตะขอ\\nตะขาบ\\nตะขิดตะขวง\\nตะเข้\\nตะเข็บ\\nตะโขง\\nตะคร้อ\\nตะครอง\\nตะครั่นตะครอ\\nตะคร้ำ\\nตะคริว\\nตะคิว\\nตะครุบ\\nตะคอก\\nตะคัน\\nตะค้า\\nตะคาก\\nตะค้าน\\nตะคุ่ม\\nตะเครียว\\nตะเคียว\\nตะเคียน\\nตะแคง\\nตะไคร่\\nตะไคร้\\nตะเฆ่\\nตะนอย\\nตะนาว\\nตะบม\\nตะบอง\\nตะบอย\\nตะบัน\\nตะบิ้ง\\nตะบิด\\nตะบิดตะบอย\\nตะบี้ตะบัน\\nตะบึง\\nตะบูน\\nตะเบ็ง\\nตะเบ็งมาน\\nตะเบ๊ะ\\nตะแบก\\nตะแบง\\nตะโบม\\nตะไบ\\nตะปบ\\nตะปลิง\\nตะปิ้ง\\nตะปุ่มตะป่ำ\\nตะปู\\nตะพง\\nตะพด\\nตะพอง\\nตะพัก\\nตะพัง\\nตะพัด\\nตะพั้น\\nตะพาก\\nตะพาน\\nตะพาบ\\nตะพาย\\nตะพึด\\nตะพึดตะพือ\\nตะพุ่น\\nตะเพรา\\nตะเพิง\\nตะเพิด\\nตะเพียน\\nตะโพก\\nตะโพง\\nตะโพน\\nตะเภา\\nตะใภ้\\nตะม่อ\\nตะมอย\\nตะรังกะนู\\nตะรังตังกวาง\\nตะรังตังช้าง\\nตะราง\\nตะลอง\\nตะลอน\\nตะล่อม\\nตะละ\\nตะลาน\\nตะลิงปลิง\\nตะลิบ\\nตะลีตะลาน\\nตะลึง\\nตะลึงพรึงเพริด\\nตะลุง\\nตะลุ่ม\\nตะลุ่มนก\\nตะลุมบอน\\nตะลุ่มโปง\\nตะลุมพอ\\nตะลุมพุก\\nตะลุย\\nตะเลง\\nตะแลงแกง\\nตะไล\\nตะวัน\\nตะเวน\\nตะหลิว\\nตะหลุก\\nตะหลุง\\nตะแหง่ว\\nตะแหมะแขะ\\nตะโหงก\\nตัก\\nตักกะ\\nตักเตือน\\nตั๊กแตน\\nตักษัย\\nตัง\\nตั่ง\\nตั้ง\\nตังเก\\nตังฉ่าย\\nตังเม\\nตังวาย\\nตังโอ๋\\nตัจฉก\\nตัจฉนี\\nตัณฑุล\\nตัณหา\\nตัด\\nตัน\\nตันตระ\\nตันติ\\nตันหยง\\nตับ\\nตับปิ้ง\\nตัว\\nตั๋ว\\nตัวจี๊ด\\nตัวตืด\\nตั้วโผ\\nตั้วเหี่ย\\nตา\\nตาก\\nตากวาง\\nต่าง\\nตาด\\nตาน\\nต่าน\\nต้าน\\nตานนกกด\\nตานี\\nตาบ\\nตาม\\nตามะแน\\nตามิน\\nตาย\\nตาราไต\\nตาล\\nตาลุ\\nต๋าว\\nตาเสือ\\nตาหนู\\nตาฬ\\nตำ\\nต่ำ\\nตำนาน\\nตำบล\\nตำแบ\\nตำแย\\nตำรวจ\\nตำรับ\\nตำรา\\nตำรุ\\nตำลึง\\nตำเสา\\nตำหนัก\\nตำหนิ\\nตำแหน่ง\\nติ\\nติก\\nติ๊ก\\nติกะ\\nติกาหรัง\\nติง\\nติ่ง\\nติ๋ง\\nติ่งตั่ง\\nติ๋งต่าง\\nติงส\\nติงสติ\\nติณ\\nติด\\nติตติกะ\\nติตติร\\nติตถ\\nติตถะ\\nติถี\\nติมิงคละ\\nติรัจฉาน\\nติลก\\nติละ\\nติ้ว\\nตี\\nตี่\\nตีน\\nตีบ\\nตีรถะ\\nตีระ\\nตึ\\nตึก\\nตึ้ก\\nตึ้กตั้ก\\nตึง\\nตึดตื๋อ\\nตึ๊ดตื๋อ\\nตืด\\nตื่น\\nตื้น\\nตื้อ\\nตื๊อ\\nตื๋อ\\nตุ\\nตุ๊\\nตุ๊กแก\\nตุ๊กตา\\nตุ๊กต่ำ\\nตุกติก\\nตุ๊กติ๊ก\\nตุ๊กตุ่น\\nตุ๊กตุ๋ย\\nตุง\\nตุ้งก่า\\nตุ้งติ้ง\\nตุ๊ดตู่\\nตุน\\nตุ่น\\nตุ๋น\\nตุนาหงัน\\nตุบ\\nตุ้บ\\nตุ๊บป่อง\\nตุปัดตุป่อง\\nตุปัดตุเป๋\\nตุ่ม\\nตุ้ม\\nตุ๋ม\\nตุ้มกว้าว\\nตุมกา\\nตุ้มแซะ\\nตุมตัง\\nตุ้มเต๋น\\nตุ้มปี่\\nตุมพะ\\nตุ่ย\\nตุ้ย\\nตุ๊ย\\nตุ๋ยตุ่ย\\nตุรคะ\\nตุรงค์\\nตุล\\nตุลา\\nตุหรัดตุเหร่\\nตู\\nตู่\\nตู้\\nตูก\\nตูด\\nตูบ\\nตูม\\nเต๊ก\\nเต็ง\\nเต่ง\\nเตช\\nเตโช\\nเต้น\\nเต็นท์\\nเต็ม\\nเตย\\nเตร่\\nเตร็ด\\nเตรตา\\nเตรียม\\nเตรียมตรม\\nเตละ\\nเตลิด\\nเตว็ด\\nเต่อ\\nเตอะ\\nเตะ\\nเตา\\nเต่า\\nเต้า\\nเต๋า\\nเต่าเกียด\\nเต้าเจี้ยว\\nเต้าทึง\\nเต้าหู้\\nเต้าฮวย\\nเต๊าะ\\nเตาะแตะ\\nเติ่ง\\nเติบ\\nเติม\\nเตี้ย\\nเตียง\\nเตียน\\nเตียบ\\nเตี๋ยม\\nเตียรถ์\\nเตียว\\nเตี่ยว\\nเตือน\\nแต่\\nแต้\\nแตก\\nแตง\\nแต่ง\\nแตงเม\\nแต้จิ๋ว\\nแตด\\nแต๊ดแต๋\\nแตน\\nแต้ม\\nแตร\\nแตระ\\nแต้ว\\nแต้วแร้ว\\nแต้วแล้ว\\nแต่ว่า\\nแต้แว้ด\\nแตะ\\nโต\\nโต้\\nโตก\\nโต่ง\\nโต้ง\\nโตงเตง\\nโตฎก\\nโต๊ด\\nโตน\\nโตนด\\nโต้โผ\\nโตมร\\nโตย\\nโตรก\\nโต๊ะ\\nใต้\\nไต\\nไต่\\nไต้\\nไต๋\\nไตร\\nไตรกิศยา\\nไตรดายุค\\nไตร่ตรอง\\nไตรย\\nไต้หวัน\\nถก\\nถกล\\nถงาด\\nถด\\nถนน\\nถนอม\\nถนัด\\nถนัน\\nถนำ\\nถนิม\\nถม\\nถ่ม\\nถมอ\\nถมึงทึง\\nถลก\\nถลกบาตร\\nถลน\\nถล่ม\\nถลอก\\nถลัน\\nถลา\\nถลาก\\nถลาย\\nถลำ\\nถลึงตา\\nถลุง\\nถ่วง\\nถ้วน\\nถ้วย\\nถวัล\\nถวัลย์\\nถวาย\\nถวิน\\nถวิล\\nถ่อ\\nถ้อ\\nถอก\\nถอง\\nถ่อง\\nถ้อง\\nถอด\\nถอน\\nถอบ\\nถอบแถบ\\nถ่อม\\nถอย\\nถ่อย\\nถ้อย\\nถะ\\nถะถั่น\\nถะมัดถะแมง\\nถัก\\nถัง\\nถั่ง\\nถัด\\nถัทธ\\nถัน\\nถั่น\\nถับ\\nถัมภ์\\nถัว\\nถั่ว\\nถา\\nถ้า\\nถาก\\nถาง\\nถ่าง\\nถาด\\nถาน\\nถ่าน\\nถาบ\\nถาม\\nถามะ\\nถ่าย\\nถ่าว\\nถาวร\\nถาวรธิรา\\nถ้ำ\\nถิ่น\\nถี่\\nถีบ\\nถึก\\nถึง\\nถือ\\nถุง\\nถุน\\nถุย\\nถู\\nถูก\\nเถกิง\\nเถน\\nเถร\\nเถระ\\nเถรานุเถระ\\nเถรี\\nเถลไถล\\nเถลิง\\nเถลือกถลน\\nเถ่อ\\nเถอะ\\nเถา\\nเถ้า\\nเถาวัลย์\\nเถาะ\\nเถิก\\nเถิง\\nเถิด\\nเถิดเทิง\\nเถิน\\nเถียง\\nเถียร\\nเถือ\\nเถือก\\nเถื่อน\\nแถ\\nแถก\\nแถง\\nแถน\\nแถบ\\nแถม\\nแถลง\\nแถลบ\\nแถว\\nโถ\\nโถง\\nโถงเถง\\nโถบ\\nโถม\\nโถมนาการ\\nไถ\\nไถ่\\nไถ้\\nไถง\\nไถล\\nทกล้า\\nทแกล้ว\\nท่ง\\nทด\\nทน\\nท้น\\nทนต์\\nทนโท่\\nทนาย\\nทบ\\nทบวง\\nทมอ\\nทมะ\\nทมิฬ\\nทโมน\\nทยอย\\nทแยง\\nทรกรรม\\nทรชน\\nทรชาติ\\nทรพิษ\\nทรยศ\\nทรราช\\nทรลักษณ์\\nทรง\\nทรพี\\nทรมาทรกรรม\\nทรมาน\\nทรรทึง\\nทรรป\\nทรรปณ์\\nทรรปณะ\\nทรรศนะ\\nทรรศนาการ\\nทรรศนีย์\\nทรวง\\nทรวดทรง\\nทรวาร\\nทรหด\\nทรหวล\\nทรหึง\\nทรอมโบน\\nทระนง\\nทรัพย์\\nทรัพยากร\\nทรัมเป็ต\\nทรานซิสเตอร์\\nทราบ\\nทราม\\nทราย\\nทรุด\\nทฤษฎี\\nทลาย\\nทลิท\\nทลิททก\\nทวง\\nท้วง\\nท่วงท่า\\nท่วงทำนอง\\nท่วงที\\nทวด\\nทวน\\nท้วน\\nท่วม\\nท้วม\\nทวย\\nท่วย\\nท้วย\\nทวอย\\nทวัตดึงส์\\nทวัย\\nทวา\\nทวาบร\\nทว่า\\nทวาย\\nทวาร\\nทวิ\\nทวิช\\nทวิตีย์\\nทวิตียา\\nทวี\\nทวีธาภิเษก\\nทวีป\\nทศ\\nทศมี\\nทศางค์\\nทหระ\\nทหาร\\nทอ\\nท่อ\\nท้อ\\nทอก\\nทอง\\nท่อง\\nท้อง\\nทองกวาว\\nทองภู\\nทองลิน\\nทองหลาง\\nทองโหลง\\nทองอุไร\\nทอด\\nทอน\\nท่อน\\nทอนซิล\\nทอฟฟี่\\nท่อม\\nทอย\\nทอเรียม\\nทะ\\nทะงัน\\nทะนง\\nทะนน\\nทะนาน\\nทะนุ\\nทะเบียน\\nทะมัดทะแมง\\nทะมึน\\nทะมื่น\\nทะแม่ง\\nทะยาน\\nทะเยอทะยาน\\nทะแย\\nทะร่อทะแร่\\nทะลวง\\nทะลอก\\nทะลัก\\nทะลาย\\nทะลึ่ง\\nทะลุ\\nทะลุดทะลาด\\nทะเล\\nทะเล้น\\nทะเล่อทะล่า\\nทะเลาะ\\nทะเลิ่กทะลั่ก\\nทะวาย\\nทัก\\nทักข์\\nทักขิญ\\nทักขิณ\\nทักขิณา\\nทักขิณาวัฏ\\nทักขิโณทก\\nทักขิไณยบุคคล\\nทักทิน\\nทักษะ\\nทักษา\\nทักษิณ\\nทักษิณา\\nทักษิโณทก\\nทัง\\nทั่ง\\nทั้ง\\nทังวล\\nทังวี้ทังวล\\nทังสเตน\\nทัณฑ์\\nทัณฑกรรม\\nทัณฑฆาต\\nทัณฑสถาน\\nทัณฑะ\\nทัณฑิกา\\nทัณฑิมา\\nทัณฑีบท\\nทัด\\nทัดทา\\nทัต\\nทัน\\nทันต์\\nทันตชะ\\nทันตแพทย์\\nทันติน\\nทันตี\\nทันธ์\\nทับ\\nทับทิม\\nทับสมิงคลา\\nทัพ\\nทัพพะ\\nทัพพี\\nทั่ว\\nทัศ\\nทัศน์\\nทัศนะ\\nทัศนา\\nทัศนคติ\\nทัศนวิสัย\\nทัศนศาสตร์\\nทัศนศิลป์\\nทัศนศึกษา\\nทัศนาการ\\nทัศนาจร\\nทัศนีย์\\nทัศนียภาพ\\nทัศนูปกรณ์\\nทัศไนย\\nทัสนานุตริยะ\\nทัฬหะ\\nทัฬหิ\\nทัฬหี\\nทา\\nท่า\\nท้า\\nทาก\\nทาง\\nท้าง\\nทาฐะ\\nทาฐิกะ\\nทาฒะ\\nทาฒิกะ\\nทาน\\nท่าน\\nทานต์\\nทานพ\\nทาบ\\nทาม\\nท่ามกลาง\\nทาย\\nท้าย\\nทายก\\nทายัช\\nทายาด\\nทายาท\\nทายิกา\\nทารก\\nทารพี\\nทาริกา\\nทารุณ\\nทาว\\nท่าว\\nท้าว\\nทาส\\nทาสี\\nทำ\\nทำนบ\\nทำนอง\\nทำนาย\\nทำนุ\\nทำนูล\\nทำเนา\\nทำเนียบ\\nทำไม\\nทำลาย\\nทำเล\\nทิคัมพร\\nทิฆัมพร\\nทิ้ง\\nทิงเจอร์\\nทิ้งถ่อน\\nทิ้งทูด\\nทิชะ\\nทิชากร\\nทิชาชาติ\\nทิฏฐะ\\nทิฏฐานุคติ\\nทิฏฐุชุกรรม\\nทิฐธรรม\\nทิฐิ\\nทิด\\nทิต\\nทิน\\nทิพ\\nทิพย์\\nทิพา\\nทิม\\nทิ่ม\\nทิมทอง\\nทิว\\nทิวงคต\\nทิวทัศน์\\nทิวา\\nทิศ\\nทิศา\\nทิศานุทิศ\\nที\\nที่\\nทีฆชาติ\\nทีฆนิกาย\\nทีฆสระ\\nทีฆายุ\\nทีป\\nทีม\\nทีเอ็นที\\nทึก\\nทึกทัก\\nทึ่ง\\nทึ้ง\\nทึดทือ\\nทึนทึก\\nทึบ\\nทึม\\nทึ่ม\\nทื่อ\\nทุ\\nทุก\\nทุกข์\\nทุกขลาภ\\nทุกขเวทนา\\nทุกขารมณ์\\nทุกฏ\\nทุกรกิริยา\\nทุกะ\\nทุกัง\\nทุกูล\\nทุคตะ\\nทุคติ\\nทุ่ง\\nทุ้ง\\nทุงงะ\\nทุจริต\\nทุด\\nทุทรรศนนิยม\\nทุนิยม\\nทุน\\nทุ่น\\nทุนนิมิต\\nทุบ\\nทุบทู\\nทุปปัญญา\\nทุพพรรณ\\nทุพพล\\nทุพพลภาพ\\nทุพภิกขภัย\\nทุม\\nทุ่ม\\nทุ้ม\\nทุย\\nทุ้ย\\nทุรกันดาร\\nทุรชน\\nทุรชาติ\\nทุรพล\\nทุรลักษณ์\\nทุรน\\nทุรนทุราย\\nทุรัศ\\nทุราคม\\nทุราจาร\\nทุเรศ\\nทุเรียน\\nทุลักทุเล\\nทุเลา\\nทุศีล\\nทุสสะ\\nทุสสีล\\nทู\\nทูโม่ง\\nทู่\\nทู้\\nทูกัง\\nทู่ซี้\\nทูต\\nทูตานุทูต\\nทูน\\nทูบ\\nทูม\\nทูล\\nทูเลียม\\nเท\\nเท่\\nเทคนิค\\nเทคนีเชียม\\nเทคโนโลยี\\nเท้ง\\nเท้งเต้ง\\nเท็จ\\nเทนนิส\\nเทพ\\nเทพา\\nเทพารักษ์\\nเทพยเจ้า\\nเทพยดา\\nเทพยุดา\\nเทพิน\\nเทพินทร์\\nเทพี\\nเทเพนทร์\\nเทโพ\\nเทริด\\nเทลลูเรียม\\nเทวทัณฑ์\\nเทวดา\\nเทวทูต\\nเทวธรรม\\nเทวนาครี\\nเทวนิยม\\nเทวรูป\\nเทวโลก\\nเทววิทยา\\nเทวสถาน\\nเทวศ\\nเทวษ\\nเทวัญ\\nเทวัน\\nเทวาลัย\\nเทวินทร์\\nเทวี\\nเทเวศ\\nเทเวศร์\\nเทเวศวร์\\nเทศ\\nเทศะ\\nเทศาภิบาล\\nเทศน์\\nเทศนา\\nเทห์\\nเท่ห์\\nเทห์ฟากฟ้า\\nเทหวัตถุ\\nเท่อ\\nเท้อ\\nเทอญ\\nเทอม\\nเทอร์เบียม\\nเทอร์โมมิเตอร์\\nเทอะทะ\\nเทา\\nเท่า\\nเท้า\\nเท้ายายม่อม\\nเท่ารึง\\nเทิ่ง\\nเทิด\\nเทิน\\nเทิบ\\nเทิบทาบ\\nเทิ้ม\\nเที่ยง\\nเทียด\\nเทียน\\nเที้ยน\\nเทียบ\\nเทียม\\nเทียร\\nเที้ยร\\nเทียว\\nเที่ยว\\nเทือ\\nเทื่อ\\nเทื้อ\\nเทือก\\nแท้\\nแท็กซี่\\nแทง\\nแท่ง\\nแท้ง\\nแท็งก์\\nแทงทวย\\nแทงวิสัย\\nแทตย์\\nแทน\\nแท่น\\nแทนเจนต์\\nแทนทาลัม\\nแทบ\\nแทรก\\nแทรกเตอร์\\nแทลเลียม\\nแทะ\\nโท\\nโท่\\nโทกเทก\\nโทง\\nโทงเทง\\nโทณะ\\nโทน\\nโทนโท่\\nโทมนัส\\nโทรคมนาคม\\nโทรทรรศน์\\nโทรทัศน์\\nโทรพิมพ์\\nโทรภาพ\\nโทรเลข\\nโทรศัพท์\\nโทรสาร\\nโทรม\\nโทษ\\nโทษา\\nโทษานุโทษ\\nโทสะ\\nโทสาคติ\\nโทโส\\nโทหฬินี\\nไท\\nไท้\\nไทเทเนียม\\nไทเทรต\\nไทย\\nไทร\\nไทวะ\\nธง\\nธงก์\\nธชะ\\nธชี\\nธตรฐ\\nธนบัตร\\nธนสมบัติ\\nธนสาร\\nธนะ\\nธนา\\nธนาคม\\nธนาคาร\\nธนาณัติ\\nธเนศ\\nธโนปจัย\\nธไนศวรรย์\\nธนิต\\nธนิษฐะ\\nธนิษฐา\\nธนุ\\nธนุรวิทยา\\nธนุรเวท\\nธนู\\nธม\\nธมกรก\\nธรณะ\\nธรณิน\\nธรณินทร์\\nธรณิศ\\nธรณิศร\\nธรณิศวร์\\nธรณี\\nธรมาน\\nธรรม\\nธรรมนูญ\\nธรรมยุต\\nธรรมยุติกนิกาย\\nธรรมะ\\nธรรมาทิตย์\\nธรรมาธรรม\\nธรรมาธิปไตย\\nธรรมาธิษฐาน\\nธรรมานุสาร\\nธรรมาภิมุข\\nธรรมาภิสมัย\\nธรรมายตนะ\\nธรรมารมณ์\\nธรรมาสน์\\nธรรมิก\\nธรา\\nธราดล\\nธราธร\\nธราธาร\\nธราธิบดี\\nธราธิป\\nธริษตรี\\nธเรษตรี\\nธเรศ\\nธวัช\\nธัช\\nธัญ\\nธัญญาหาร\\nธันยา\\nธันยาวาท\\nธันวาคม\\nธัมมะ\\nธาดา\\nธาตรี\\nธาตวากร\\nธาตุ\\nธาตุโขภ\\nธาตุมมิสสา\\nธานิน\\nธานินทร์\\nธานี\\nธาร\\nธารกำนัล\\nธารคำนัล\\nธารณะ\\nธารณา\\nธารา\\nธาษตรี\\nธำมรงค์\\nธำรง\\nธิดา\\nธิติ\\nธีระ\\nธุช\\nธุดงค์\\nธุดงควัตร\\nธุต\\nธุตตะ\\nธุมเกตุ\\nธุมา\\nธุรการ\\nธุรกิจ\\nธุระ\\nธุรำ\\nธุลี\\nธุวดารา\\nธุวภาค\\nธุวมณฑล\\nธูป\\nเธนุ\\nเธอ\\nเธียร\\nโธ่\\nโธวนะ\\nนก\\nนกุล\\nนขลิขิต\\nนขะ\\nนขา\\nนเคนทร์\\nนโคทร\\nนคร\\nนครินทร์\\nนคเรศ\\nนง\\nนงคุฐ\\nนที\\nนนตรา\\nนนท์\\nนันทน์\\nนนทรี\\nนนทลี\\nนนทิ\\nนบ\\nนปุงสกลิงค์\\nนปุงสกลึงค์\\nนพ\\nนพนิต\\nนภจร\\nนภดล\\nนภศูล\\nนภา\\nนภาลัย\\nนม\\nนมตำเรีย\\nนมตำเลีย\\nนมะ\\nนมัสการ\\nนมาซ\\nนยนะ\\nนยนา\\nนโยบาย\\nนรชาติ\\nนรเทพ\\nนรนาถ\\nนรบดี\\nนรบาล\\nนรสิงห์\\nนรสีห์\\nนรา\\nนรากร\\nนราธิป\\nนรินทร์\\nนริศ\\nนริศร\\nนริศวร\\nนเรศ\\nนเรศวร\\nนเรศวร์\\nนโรดม\\nนรก\\nนรกานต์\\nนรการ\\nนรี\\nนฤเทพ\\nนฤบดี\\nนฤบาล\\nนฤเบศ\\nนฤปเวศม์\\nนฤปัตนี\\nนฤคหิต\\nนฤนาท\\nนฤมล\\nนฤตย์\\nนฤตยสถาน\\nนฤพาน\\nนฤมาณ\\nนฤมิต\\nนลาฏ\\nนลิน\\nนลินี\\nนวกรรม\\nนวการ\\nนวกิจ\\nนวนิยาย\\nนวปฎล\\nนวรัตน์\\nนวโลหะ\\nนวกะ\\nนวโกวาท\\nนวด\\nนวม\\nน่วม\\nนวมี\\nนวย\\nนวล\\nนวัตกรรม\\nนวาระ\\nนหารุ\\nนหุต\\nนฬการ\\nนอ\\nนอก\\nนอง\\nน่อง\\nน้อง\\nน่องแน่ง\\nนอต\\nนอน\\nนอบ\\nน้อม\\nน้อย\\nน้อยหน่า\\nน้อยโหน่ง\\nนะ\\nนะแน่ง\\nนัก\\nนักขัต\\nนักขัตฤกษ์\\nนักษัตร\\nนักสราช\\nนัข\\nนั่ง\\nนังคัล\\nนัจ\\nนัฑ\\nนัด\\nนัดดา\\nนัตถุ์\\nนั่น\\nนั้น\\nนันททายี\\nนันทนาการ\\nนันทวัน\\nนันทิ\\nนับ\\nนัย\\nนัยน์\\nนัยนา\\nนัว\\nนัวเนีย\\nนา\\nน่า\\nน้า\\nนาก\\nนากบุด\\nนากาสาหรี\\nนาค\\nนาคร\\nนาคา\\nนาคาวโลก\\nนาคินทร์\\nนาคี\\nนาเคนทร์\\nนาเคศวร\\nนาง\\nนางเกล็ด\\nนางนวล\\nนางนูน\\nนางรม\\nนางรำ\\nนางล้อม\\nนางเล็ด\\nนางเลิ้ง\\nนางหงส์\\nนางอาย\\nนางแอ่น\\nนาฏ\\nนาฏกะ\\nนาด\\nนาถ\\nนาท\\nนาที\\nนาน\\nน่าน\\nนานัครส\\nนานัปการ\\nนานา\\nนาเนก\\nนาบ\\nนาภี\\nนาม\\nนามานุกรม\\nนามาภิไธย\\nนาย\\nน่าย\\nนายก\\nนายิกา\\nนารา\\nนารายณ์\\nนารี\\nนาเรศ\\nนาลิวัน\\nนาว\\nน้าว\\nนาวา\\nนาวิก\\nนาวิน\\nนาวี\\nนาเวศ\\nนาศ\\nนาสา\\nนาสิก\\nนาฬิกา\\nนาฬิเก\\nนาฬี\\nนำ\\nน้ำ\\nน้ำละว้า\\nน้ำว้า\\nนิ\\nนิกเกิล\\nนิกขะ\\nนิกร\\nนิกรอยด์\\nนิกาย\\nนิคม\\nนิครนถ์\\nนิคหกรรม\\nนิคหะ\\nนิคหิต\\nนิคาลัย\\nนิเคราะห์\\nนิโคติน\\nนิโครธ\\nนิโครม\\nนิ่ง\\nนิจ\\nนิด\\nนิตย์\\nนิตยทาน\\nนิตยภัต\\nนิตยสาร\\nนิติ\\nนิทร\\nนิทรรศการ\\nนิทรา\\nนิทรารมณ์\\nนิทัศน์\\nนิทาน\\nนิเทศ\\nนิธาน\\nนิธิ\\nนินทา\\nนินนาท\\nนินาท\\nนิบาต\\nนิปริยาย\\nนิปัจการ\\nนิพจน์\\nนิพนธ์\\nนิพพาน\\nนิพพิทา\\nนิพัทธ์\\nนิพันธ์\\nนิพิท\\nนิเพท\\nนิภา\\nนิ่ม\\nนิ้ม\\nนิมนต์\\nนิมมาน\\nนิมมานรดี\\nนิมิต\\nนิยต\\nนิยม\\nนิยัตินิยม\\nนิยาม\\nนิยาย\\nนิยุต\\nนิรคุณ\\nนิรชร\\nนิรชรา\\nนิรทุกข์\\nนิรเทศ\\nนิรโทษ\\nนิรโทษกรรม\\nนิรนัย\\nนิรนาม\\nนิรภัย\\nนิรมล\\nนิรมาน\\nนิรัตศัย\\nนิรันดร\\nนิราพาธ\\nนิรามัย\\nนิรามิษ\\nนิราศรัย\\nนิรินธน์\\nนิรมาณ\\nนิรมิต\\nนิรยบาล\\nนิรัพพุท\\nนิรา\\nนิราศ\\nนิรุกติ\\nนิรุตติ\\nนิรุทธ์\\nนิโรธ\\nนิล\\nนิลุบล\\nนิโลบล\\nนิ่ว\\nนิ้ว\\nนิวคลิอิก\\nนิวเคลียร์\\nนิวเคลียส\\nนิวตรอน\\nนิวรณ์\\nนิวัต\\nนิวัตน์\\nนิวาต\\nนิวาส\\nนิเวศ\\nนิเวศน์\\nนิศา\\nนิษาท\\nนิสัช\\nนิสัชชาการ\\nนิสัย\\nนิสาท\\nนิสิต\\nนิสีทนสันถัต\\nนิสีทนะ\\nนิสีทนาการ\\nนิเสธ\\nนี่\\nนี้\\nนี่นัน\\nนีรนาท\\nนีออน\\nนีโอดิเมียม\\nนึก\\nนึง\\nนึ่ง\\nนุง\\nนุ่ง\\nนุงนัง\\nนุช\\nนุต\\nนุ่น\\nนุ่ม\\nนุ้ย\\nนูน\\nนู่น\\nนู้น\\nเนกขัม\\nเนตบอล\\nเนตร\\nเนติ\\nเน้น\\nเนบิวลา\\nเนปจูน\\nเนปทูเนียม\\nเนมิ\\nเนย\\nเนรกัณฐี\\nเนรคุณ\\nเนรเทศ\\nเนรนาด\\nเนรมิต\\nเนระพูสี\\nเนอ\\nเน้อ\\nเนา\\nเน่า\\nเนาวนิต\\nเนาวรัตน์\\nเนิน\\nเนิ่น\\nเนิบ\\nเนียง\\nเนียน\\nเนียม\\nเนียร\\nเนียรทุกข์\\nเนียรเทศ\\nเนียรนาท\\nเนื้อ\\nเนือง\\nเนื่อง\\nเนือย\\nแน่\\nแน่ง\\nแน่น\\nแนบ\\nแน่บ\\nแนม\\nแนว\\nแน่ว\\nแนะ\\nแน่ะ\\nแนะแหน\\nโน\\nโน้ต\\nโนน\\nโน่น\\nโน้น\\nโนเบเลียม\\nโน้ม\\nโนมพรรณ\\nโนรา\\nโนรี\\nใน\\nไน\\nไนต์คลับ\\nไนโตรเจน\\nไนลอน\\nไนโอเบียม\\nบ่\\nบก\\nบง\\nบ่ง\\nบงก์\\nบ๊งเบ๊ง\\nบงสุ์\\nบด\\nบดินทร์\\nบดี\\nบถ\\nบท\\nบน\\nบ่น\\nบพิตร\\nบพิธ\\nบ่ม\\nบรม\\nบรมัตถ์\\nบรรจง\\nบรรจถรณ์\\nบรรจบ\\nบรรจวบ\\nบรรจุ\\nบรรเจิด\\nบรรณ\\nบรรดา\\nบรรตานึก\\nบรรถร\\nบรรทม\\nบรรทัด\\nบรรทาน\\nบรรทุก\\nบรรเทา\\nบรรเทือง\\nบรรพ\\nบรรพ์\\nบรรพชา\\nบรรพชิต\\nบรรพต\\nบรรยง\\nบรรยงก์\\nบรรยเวกษก์\\nบรรยากาศ\\nบรรยาย\\nบรรลัย\\nบรรลาย\\nบรรลุ\\nบรรเลง\\nบรรโลม\\nบรรษัท\\nบรรสบ\\nบรรสพ\\nบรรสม\\nบรรสาน\\nบรรสาร\\nบรรหาน\\nบรรหาร\\nบรอนซ์\\nบรั่นดี\\nบรัศว์\\nบราลี\\nบริกรรม\\nบริการ\\nบริขาร\\nบริขารโจล\\nบริคณห์\\nบริจาค\\nบริจาริกา\\nบริเฉท\\nบริชน\\nบริดจ์\\nบริบท\\nบริบาล\\nบริบูรณ์\\nบริพนธ์\\nบริพัตร\\nบริพันธ์\\nบริพาชก\\nบริพาร\\nบริภัณฑ์\\nบริภาษ\\nบริโภค\\nบริมาส\\nบริยาย\\nบริรม\\nบริรักษ์\\nบริราช\\nบริวรรต\\nบริวาร\\nบริวาส\\nบริเวณ\\nบริษัท\\nบริสชน\\nบริสุทธิ์\\nบริหาร\\nบล็อก\\nบวก\\nบวง\\nบ่วง\\nบวช\\nบวน\\nบ้วน\\nบวบ\\nบวม\\nบ๊วย\\nบวร\\nบหลิ่ม\\nบอ\\nบ่อ\\nบ้อ\\nบอก\\nบอง\\nบ่อง\\nบ้อง\\nบ๊อง\\nบ้องแบ๊ว\\nบองหลา\\nบอด\\nบอน\\nบ่อน\\nบอบ\\nบ้อม\\nบ๋อม\\nบ่อย\\nบอระเพ็ด\\nบอล\\nบอลลูน\\nบ้อหุ้น\\nบ๊ะ\\nบ๊ะจ่าง\\nบะหมี่\\nบัก\\nบักโกรก\\nบัคเตรี\\nบัง\\nบั้ง\\nบังกะโล\\nบังเกิด\\nบังคน\\nบังคม\\nบังคล\\nบังควร\\nบังคับ\\nบังคัล\\nบังแทรก\\nบังวาย\\nบังเวียน\\nบังสุกุล\\nบังสุกูลิก\\nบังสูรย์\\nบังหวน\\nบังเหตุ\\nบังเหียน\\nบังอร\\nบังอวจ\\nบังอาจ\\nบังเอิญ\\nบัญจก\\nบัญชร\\nบัญชา\\nบัญชี\\nบัญญัติ\\nบัญหา\\nบัฏ\\nบัณฑร\\nบัณฑิต\\nบัณฑิตย์\\nบัณฑุ\\nบัณฑูร\\nบัณเฑาะก์\\nบัณเฑาะว์\\nบัณณาส\\nบัณรส\\nบัณรสี\\nบัด\\nบัดกรี\\nบัดซบ\\nบัดสี\\nบัตร\\nบัทม์\\nบัน\\nบั่น\\nบั้น\\nบันจวบ\\nบันดล\\nบันดาล\\nบันได\\nบันทึก\\nบันทึง\\nบันเทิง\\nบันยะบันยัง\\nบันลือ\\nบัปผาสะ\\nบัพ\\nบัพชา\\nบัพพาชนียกรรม\\nบัล\\nบัลลพ\\nบัลลังก์\\nบัลลูน\\nบัลเลต์\\nบัว\\nบา\\nบ่า\\nบ้า\\nบาก\\nบาง\\nบ่าง\\nบ้าง\\nบาจรีย์\\nบาซิลลัส\\nบาด\\nบาดทะจิต\\nบาดทะพิษ\\nบาดทะยัก\\nบาดาล\\nบาตร\\nบาท\\nบาทสกุณี\\nบาทหลวง\\nบาทาธึก\\nบาทุกา\\nบาน\\nบ้าน\\nบานชื่น\\nบานเช้า\\nบานบุรี\\nบานไม่รู้โรย\\nบานเย็น\\nบ้าบ๋า\\nบาป\\nบาย\\nบ่าย\\nบ้าย\\nบาร์\\nบารนี\\nบารมี\\nบาร์เรล\\nบาร์เลย์\\nบารอมิเตอร์\\nบ้าระบุ่น\\nบาเรียน\\nบาเรียม\\nบาล\\nบาลี\\nบ่าว\\nบ่าวขุน\\nบาศ\\nบาศก์\\nบาสเกตบอล\\nบาหลี\\nบ๋ำ\\nบำเทิง\\nบำนาญ\\nบำบวง\\nบำบัด\\nบำเพ็ญ\\nบำราบ\\nบำราศ\\nบำรุง\\nบำรู\\nบำเรอ\\nบำหยัด\\nบำเหน็จ\\nบิ\\nบิฐ\\nบิณฑบาต\\nบิด\\nบิดร\\nบิดหล่า\\nบิดา\\nบิตุ\\nบิตุจฉา\\nบิตุรงค์\\nบิตุเรศ\\nบิตุลา\\nบิน\\nบิ่น\\nบินยา\\nบิลเลียด\\nบิวเรตต์\\nบิสมัท\\nบี้\\nบีฑา\\nบีตา\\nบีบ\\nบีเยศ\\nบึก\\nบึกบึน\\nบึง\\nบึ่ง\\nบึ้ง\\nบุ\\nบุก\\nบุคคล\\nบุคลากร\\nบุคลาธิษฐาน\\nบุคลิก\\nบุง\\nบุ่ง\\nบุ้ง\\nบุ้งกี๋\\nบุญ\\nบุญญาธิการ\\nบุญญานุภาพ\\nบุญญาภินิหาร\\nบุญญาภิสังขาร\\nบุณฑริก\\nบุณมี\\nบุณย์\\nบุตร\\nบุตรี\\nบุถุชน\\nบุทคล\\nบุนนาค\\nบุบ\\nบุบบิบ\\nบุปผชาติ\\nบุพกรรม\\nบุพการี\\nบุพกิจ\\nบุพชาติ\\nบุพทักษิณ\\nบุพนิมิต\\nบุพบท\\nบุพพาจารย์\\nบุพเพสันนิวาส\\nบุพโพ\\nบุ๋ม\\nบุ่มบ่าม\\nบุ้ย\\nบุรณะ\\nบุรพทิศ\\nบุรพบท\\nบุรพาจารย์\\nบูรพาจารย์\\nบุระ\\nบุราณ\\nบุรินทร์\\nบุริมทิศ\\nบุริมพรรษา\\nบุริมสิทธิ\\nบุรี\\nบุรุษ\\nบุโรทั่ง\\nบุษกร\\nบุษบก\\nบุษบง\\nบุษบัน\\nบุษบา\\nบุษบามินตรา\\nบุษปราค\\nบุษปะ\\nบุษย์\\nบุษย์น้ำทอง\\nบุษยมาส\\nบุษยะ\\nบุษราคัม\\nบุหงัน\\nบุหงา\\nบุหรง\\nบุหรี่\\nบุหลัน\\nบู่\\nบู้\\nบูชนียสถาน\\nบูชา\\nบูชิต\\nบูด\\nบูดู\\nบูร\\nบูรณ์\\nบูรณภาพ\\nบูรณมี\\nบูรณะ\\nบูรณาการ\\nบูรพ์\\nบูรพะ\\nบูรพา\\nเบ้\\nเบ่ง\\nเบ๊จี๋\\nเบญกานี\\nเบญจกัลยาณี\\nเบญจกามคุณ\\nเบญจขันธ์\\nเบญจดุริยางค์\\nเบญจธรรม\\nเบญจบรรพต\\nเบญจพรรณ\\nเบญจเพส\\nเบญจมาศ\\nเบญจรงค์\\nเบญจศก\\nเบญจศีล\\nเบญจะ\\nเบญจา\\nเบญจางค์\\nเบญจางคประดิษฐ์\\nเบญญา\\nเบญพาด\\nเบ็ด\\nเบ็ดเตล็ด\\nเบ็ดเสร็จ\\nเบน\\nเบนซิน\\nเบรก\\nเบริลเลียม\\nเบส\\nเบ้อ\\nเบอร์\\nเบอร์คีเลียม\\nเบ้อเร่อ\\nเบ้อเร่อเท่อ\\nเบ้อเริ่ม\\nเบ้อเริ่มเทิ่ม\\nเบอะ\\nเบอะบะ\\nเบะ\\nเบา\\nเบ้า\\nเบาราณ\\nเบาะ\\nเบิก\\nเบิ่ง\\nเบี้ย\\nเบี่ยง\\nเบียด\\nเบียน\\nเบียร์\\nเบี้ยว\\nเบือ\\nเบื่อ\\nเบื้อ\\nเบื้อง\\nเบือน\\nแบ\\nแบ้\\nแบก\\nแบคทีเรีย\\nแบ่ง\\nแบงก์\\nแบดมินตัน\\nแบตเตอรี่\\nแบน\\nแบนโจ\\nแบบ\\nแบ็บ\\nแบเรียม\\nแบหลา\\nแบะ\\nโบ\\nโบ้\\nโบ๋\\nโบก\\nโบกขรณี\\nโบกขรพรรษ\\nโบชุก\\nโบต\\nโบนัส\\nโบ๊เบ๊\\nโบย\\nโบรมีน\\nโบรอน\\nโบราณ\\nโบสถ์\\nใบ\\nใบ้\\nไบ่\\nปก\\nปกติ\\nปกรณ์\\nปกรณัม\\nปกิณกะ\\nปกีรณัม\\nปโกฏิ\\nปง\\nป่ง\\nปงช้าง\\nปฎล\\nปฏัก\\nปฏิกรณ์\\nปฏิกรรม\\nปฏิการะ\\nปฏิกิริยา\\nปฏิกูล\\nปฏิคม\\nปฏิคหิต\\nปฏิคาหก\\nปฏิฆะ\\nปฏิชีวนะ\\nปฏิญญา\\nปฏิญาณ\\nปฏิทิน\\nปฏิบถ\\nปฏิบัติ\\nปฏิปทา\\nปฏิปักษ์\\nปฏิปัน\\nปฏิปุจฉาพยากรณ์\\nปฏิปุจฉาวาที\\nปฏิพัทธ์\\nปฏิพากย์\\nปฏิภาค\\nปฏิภาณ\\nปฏิมา\\nปฏิมากร\\nปฏิยุทธ์\\nปฏิรพ\\nปฏิรูป\\nปฏิโลม\\nปฏิวัติ\\nปฏิวาต\\nปฏิวาท\\nปฏิเวธ\\nปฏิสนธิ\\nปฏิสวะ\\nปฏิสังขรณ์\\nปฏิสันถาร\\nปฏิสัมภิทา\\nปฏิเสธ\\nปฐพี\\nปฐม\\nปฐวี\\nปณต\\nปณาม\\nปณิธาน\\nปณิธิ\\nปณีต\\nปด\\nปดิวรัดา\\nปติ\\nปถพี\\nปถมัง\\nปถวี\\nปทัฏฐาน\\nปทัสถาน\\nปทานุกรม\\nปทีป\\nปทุม\\nปน\\nป่น\\nปนัดดา\\nปปัญจะ\\nปม\\nปรนัย\\nปรปักษ์\\nปรโลก\\nปรวาที\\nปรก\\nปรกติ\\nปรง\\nปรตยักษ์\\nปรน\\nปรนนิบัติ\\nปรนิมมิตวสวัตดี\\nปรบ\\nปรปักษ์\\nปรมัตถ์\\nปรมาจารย์\\nปรมาณู\\nปรมาภิไธย\\nปรมาภิเษก\\nปรมินทร์\\nบรเมนทร์\\nปรเมศวร์\\nปรเมษฐ์\\nปรวด\\nปรวนแปร\\nปรศุ\\nปรสิต\\nปร๋อ\\nปรองดอง\\nปรอด\\nปรอท\\nปรอย\\nประ\\nประกบ\\nประกฤต\\nประกฤติ\\nประกล\\nประกวด\\nประกวดประขัน\\nประกอบ\\nประกัน\\nประกับ\\nประกาย\\nประกายพรึก\\nประการ\\nประกาศ\\nประกาศนียบัตร\\nประกาศิต\\nประกำ\\nประกิด\\nประกิต\\nประคด\\nประคนธรรพ\\nประคนธรรพ์\\nประคบ\\nประคบประหงม\\nประคอง\\nประคับประคอง\\nประคัลภ์\\nประคำ\\nประคิ่น\\nประคุณ\\nประเคน\\nประเคราะห์\\nประโคน\\nประโคนธรรพ\\nประโคนธรรพ์\\nประโคม\\nประจง\\nประจญ\\nประจบ\\nประจบประแจง\\nประจวบ\\nประจ๋อประแจ๋\\nประจักษ์\\nประจักษนิยม\\nประจัญ\\nประจัน\\nประจาก\\nประจาค\\nประจาน\\nประจำ\\nประจิม\\nประจิ้มประเจ๋อ\\nประจุ\\nประจุคมน์\\nประจุบัน\\nประเจก\\nประเจิด\\nประเจิดประเจ้อ\\nประเจียด\\nประแจ\\nประชด\\nประชน\\nประชวม\\nประชวร\\nประชัน\\nประชา\\nประชาธิปไตย\\nประชิด\\nประชี\\nประชุม\\nประเชิญ\\nประณต\\nประณม\\nประณาม\\nประณิธาน\\nประณิธิ\\nประณีต\\nประณุท\\nประดง\\nประดน\\nประดวน\\nประดอน\\nประดอย\\nประดัก\\nประดักประเดิด\\nประดัง\\nประดับ\\nประดา\\nประดาก\\nประดาป\\nประดาษ\\nประดิชญา\\nประดิดประดอย\\nประดิทิน\\nประดิษฐ์\\nประดิษฐกรรม\\nประดิษฐาน\\nประดุง\\nประดุจ\\nประดู่\\nประเด\\nประเด็น\\nประเดิม\\nประเดียง\\nประเดี๋ยว\\nประเดี๋ยวประด๋าว\\nประแดง\\nประแดะ\\nประโดง\\nประโดย\\nประตง\\nประตัก\\nประตาป\\nประติชญา\\nประติญาณ\\nประติทิน\\nประติมากร\\nประติมากรรม\\nประติรพ\\nประตู\\nประถม\\nประถมจินดา\\nประทม\\nประท้วง\\nประทวน\\nประทักษ์\\nประทักษิณ\\nประทัง\\nประทัด\\nประทับ\\nประทาน\\nประทาย\\nประทาศี\\nประทิน\\nประทิ่น\\nประทีป\\nประทุฐ\\nประทุน\\nประทุษ\\nประทุษฐ์\\nประเทศ\\nประเทา\\nประเทียด\\nประเทียบ\\nประเทือง\\nประธาน\\nประธานาธิบดี\\nประนม\\nประนอ\\nประนอม\\nประนัง\\nประนัปดา\\nประนีประนอม\\nประปราน\\nประปราย\\nประปา\\nประเปรี้ยง\\nประเปรียว\\nประพจน์\\nประพนธ์\\nประพรม\\nประพฤติ\\nประพฤทธิ์\\nประพัด\\nประพัทธ์\\nประพันธ์\\nประพาต\\nประพาส\\nประพาสมหรณพ\\nประพาฬ\\nประพิณ\\nประพิมพ์ประพาย\\nประพุทธ์\\nประเพณี\\nประโพธ\\nประไพ\\nประไพร\\nประภพ\\nประภัสสร\\nประภา\\nประภาคาร\\nประภาพ\\nประภาษ\\nประภาส\\nประเภท\\nประมง\\nประมวล\\nประมาณ\\nประมาท\\nประมุข\\nประมุท\\nประมูล\\nประเมิน\\nประโมง\\nประโมทย์\\nประยงค์\\nประยุกต์\\nประยุทธ์\\nประยุร\\nประยูร\\nประโยค\\nประโยชน์\\nประโรหิต\\nประลมพ์\\nประลอง\\nประลัย\\nประลาต\\nประลาย\\nประลุ\\nประเล่ห์\\nประเล้าประโลม\\nประโลม\\nประวรรต\\nประวรรตน์\\nประวัติ\\nประวาล\\nประวาลปัทม์\\nประวาส\\nประวิง\\nประวิช\\nประวิตร\\nประวิน\\nประวีณ\\nประเวณี\\nประเวศ\\nประเวศน์\\nประศม\\nประศาสน์\\nประศุ\\nประสก\\nประสงค์\\nประสบ\\nประสพ\\nประสม\\nประสะ\\nประสัก\\nประสันนาการ\\nประสัยห์\\nประสา\\nประสาท\\nประสาธน์\\nประสาน\\nประสาร\\nประสิทธิ์\\nประสิทธิผล\\nประสิทธิภาพ\\nประสีประสา\\nประสูต\\nประสูติ\\nประเสบัน\\nประเสบันอากง\\nประเสริฐ\\nประหนึ่ง\\nประหม่า\\nประหยัด\\nประหลาด\\nประหล่ำ\\nประหวัด\\nประหวั่น\\nประหัตประหาร\\nประหาณ\\nประหาร\\nประเหล\\nประเหส\\nประไหมสุหรี\\nประอบ\\nประอร\\nปรัก\\nปรักปรำ\\nปรักมะ\\nปรัง\\nปรัชญา\\nปรัตถจริยา\\nปรัตยุบัน\\nปรัน\\nปรับ\\nปรัมปรา\\nปรัศจิม\\nปรัศนา\\nปรัศนี\\nปรัศว์\\nปรัสสบท\\nปร่า\\nปรากฏ\\nปรากรม\\nปรากฤต\\nปราการ\\nปราง\\nปรางค์\\nปราจีน\\nปราชญ์\\nปราชญา\\nปราชัย\\nปราณ\\nปราณี\\nปราด\\nปราน\\nปรานี\\nปราบ\\nปราบดาภิเษก\\nปราปต์\\nปราม\\nปรามาส\\nปราโมช\\nปราโมทย์\\nปราย\\nปรารถนา\\nปรารภ\\nปรารมภ์\\nปราศ\\nปราศจาก\\nปราศรัย\\nปราษณี\\nปราษาณ\\nปราสัย\\nปราสาท\\nปรำ\\nปริ\\nปริก\\nปริกขาร\\nปริกรรม\\nปริกัป\\nปริคณห์\\nปริจาค\\nปริจาริกา\\nปริเฉท\\nปริชน\\nปริซึม\\nปริญญา\\nปริณาม\\nปริณายก\\nปริต\\nปริตตะ\\nปริตโตทก\\nปริตร\\nปริทรรศน์\\nปริทัยหัคคี\\nปริทัศน์\\nปริเทพ\\nปริเทวะ\\nปรินิพพาน\\nปริบ\\nปริบท\\nปริปันถ์\\nปริพนธ์\\nปริพัตร\\nปริพันธ์\\nปริพาชก\\nปริภัณฑ์\\nปริภาษ\\nปริภูมิ\\nปริโภค\\nปริ่ม\\nปริมณฑล\\nปริมาณ\\nปริมาตร\\nปริยัติ\\nปริยานุช\\nปริยาย\\nปริเยศ\\nปริโยสาน\\nปริวรรต\\nปริวัตร\\nปริวาร\\nปริวาส\\nปริวิตก\\nปริเวณ\\nปริศนา\\nปริษัท\\nปริสัญญู\\nปริสุทธิ\\nปริหาน\\nปริหาร\\nปรี่\\nปรีชญา\\nปรีชา\\nปรี๊ด\\nปรีดา\\nปรีดิ\\nปรีดิ์\\nปรีดี\\nปรีติ\\nปรียะ\\nปรียา\\nปรึก\\nปรึกษา\\nปรึง\\nปรือ\\nปรื๋อ\\nปรุ\\nปรุง\\nปรู\\nปรู๋\\nปรูด\\nปรู๊ด\\nปรู๊ดปร๊าด\\nปรู๊ฟ\\nปฤงคพ\\nปฤจฉา\\nปฤษฎางค์\\nปฤษฐ\\nปลก\\nปลกเปลี้ย\\nปลง\\nปล่ง\\nปลด\\nปล้น\\nปลวก\\nปลอก\\nปล่อง\\nปล้อง\\nปลอด\\nปล้อน\\nปลอบ\\nปลอม\\nปล่อย\\nปละ\\nปลัก\\nปลั๊ก\\nปลัง\\nปลั่ง\\nปลัด\\nปลัดขิก\\nปลา\\nปลาต\\nปลาบ\\nปลาย\\nปลาสเตอร์\\nปลาสนาการ\\nปล้ำ\\nปลิง\\nปลิด\\nปลิ้น\\nปลิโพธ\\nปลิม\\nปลิ่ม\\nปลิว\\nปลี\\nปลีก\\nปลื้ม\\nปลุก\\nปลูก\\nปวกเปียก\\nปวง\\nป่วง\\nปวด\\nป่วน\\nป้วน\\nป้วนเปี้ยน\\nป่วย\\nปวัตน์\\nปวารณา\\nปวาล\\nปวาส\\nปวาฬ\\nปวิช\\nปวิตร\\nปวิธ\\nปวิเวก\\nปวีณ\\nปวุติ\\nปเวณี\\nปเวส\\nปเวสน์\\nปศุ\\nปสันนะ\\nปสันนาการ\\nปสาท\\nปสาน\\nปสาสน์\\nปสุ\\nปสุต\\nปสูติ\\nปหังสนะ\\nปหาน\\nปหาร\\nปหาส\\nปอ\\nป้อ\\nป๋อ\\nปอก\\nปอง\\nป่อง\\nป้อง\\nปอด\\nปอน\\nป้อน\\nปอนด์\\nปอเนาะ\\nปอบ\\nป้อแป้\\nปอม\\nป้อม\\nป๋อม\\nปอย\\nป้อย\\nป้อยอ\\nปะ\\nปะกน\\nปะกัง\\nปะการัง\\nปะกำ\\nปะขาว\\nปะงาบ\\nปะตาปา\\nปะตาระกาหลา\\nปะติดปะต่อ\\nปะติยาน\\nปะทะ\\nปะทะปะทัง\\nปะทุ\\nปะทุน\\nปะปน\\nปะมง\\nปะราลี\\nปะรำ\\nปะไร\\nปะลอม\\nปะเลง\\nปะแล่ม\\nปะโลง\\nปะวะหล่ำ\\nปะหงับ\\nปะหนัน\\nปะหัง\\nปะเหลาะ\\nปัก\\nปักข์\\nปักเป้า\\nปักษ์\\nปักษา\\nปักษิน\\nปักษี\\nปัง\\nปั๋ง\\nปังสุ์\\nปังสุกุล\\nปัจจัตตะ\\nปัจจันต์\\nปัจจันตคาม\\nปัจจันตชนบท\\nปัจจันตประเทศ\\nปัจจัย\\nปัจจามิตร\\nปัจจุคมน์\\nปัจจุทธรณ์\\nปัจจุบัน\\nปัจจุสมัย\\nปัจเจก\\nปัจโจปการกิจ\\nปัจฉา\\nปัจฉิม\\nปัจถรณ์\\nปัจนึก\\nปัจยาการ\\nปัจเวกขณ์\\nปัชชุน\\nปัญจนที\\nปัญจวัคคีย์\\nปัญจก\\nปัญจกะ\\nปัญจมี\\nปัญจวีสติ\\nปัญญัติ\\nปัญญา\\nปัญหา\\nปัฏ\\nปัฏนะ\\nปัฐยาวัต\\nปัณฑรหัตถี\\nปัณณะ\\nปัณณาส\\nปัณณาสก์\\nปัณรสี\\nปัณหิ\\nปัด\\nปัตคาด\\nปัตตะ\\nปัตตานึก\\nปัตตานุโมทนา\\nปัตตาเวีย\\nปัตติ\\nปัตติก\\nปัตถร\\nปัตถะ\\nปัตนิ\\nปัตนี\\nปัตหล่า\\nปัถพี\\nปัถวี\\nปัทม์\\nปัทมะ\\nปัทมาสน์\\nปัน\\nปั่น\\nปั้น\\nปั้นจั่น\\nปันจุเหร็จ\\nปั้นลม\\nปั้นหยา\\nปั้นเหน่ง\\nปับ\\nปั๊บ\\nปัปผาสะ\\nปัพพาชนียกรรม\\nปัพภาระ\\nปั๊ม\\nปัยกา\\nปัยยิกา\\nปัวเปีย\\nปัศจิม\\nปัศตัน\\nปัสสาวะ\\nปัสสาสะ\\nปา\\nป่า\\nป้า\\nปาก\\nปาง\\nป้าง\\nปาจรีย์\\nปาจิตตีย์\\nปาจีน\\nปาฏลิ\\nปาฏิบท\\nปาฏิบุคลิก\\nปาฏิโภค\\nปาฏิหาริย์\\nปาฐก\\nปาฐกถา\\nปาฐะ\\nปาณกชาติ\\nปาณะ\\nปาณาติบาต\\nปาณิ\\nปาณี\\nปาด\\nปาติโมกข์\\nปาตี\\nปาเต๊ะ\\nปาท่องโก๋\\nปาทังกา\\nปาทาน\\nปาทุกา\\nปาน\\nป่าน\\nป้าน\\nปานะ\\nปานียะ\\nป้าบ\\nป๊าบ\\nปาพจน์\\nปาม\\nปาโมกข์\\nป่าย\\nป้าย\\nปายาส\\nปาร์เกต์\\nปารมี\\nปารเมศ\\nปาราชิก\\nปาริฉัตร\\nปาริชาต\\nปารุสกวัน\\nปาล\\nปาล์ม\\nปาลิไลยก์\\nปาลี\\nปาว\\nป่าว\\nป๊าว\\nปาวาร\\nปาษาณ\\nปาส\\nปาสาณ\\nปาสาทิกะ\\nปาหนัน\\nปาหี่\\nปำ\\nป้ำ\\nป้ำเป๋อ\\nปิกนิก\\nปิ้ง\\nปิงคละ\\nปิงปอง\\nปิฎก\\nปิฏฐะ\\nปิฐิ\\nปิณฑะ\\nปิด\\nปิตตะ\\nปิตา\\nปิตามหัยกา\\nปิตามหัยยิกา\\nปิตุ\\nปิตุจฉา\\nปิตุภูมิ\\nปิตุลา\\nปิโตรเลียม\\nปิ่น\\nปิ่นแก้ว\\nปิ่นโต\\nปิปผลี\\nปิ่ม\\nปิ้ม\\nปิยะ\\nปิยังคุ\\nปิโยรส\\nปิลันธน์\\nปิ๋ว\\nปิศาจ\\nปิหกะ\\nปี\\nปี่\\nปี้\\nปี๋\\nปีก\\nปีฐะ\\nปี๊ด\\nปีติ\\nปีน\\nปีบ\\nปี๊บ\\nปีศาจ\\nปีฬกะ\\nปึก\\nปึง\\nปึ่ง\\nปึ๋ง\\nปึ้ด\\nปึมปื้อ\\nปืน\\nปื้น\\nปือ\\nปื้อ\\nปื๋อ\\nปุ\\nปุ๊\\nปุก\\nปุกปุย\\nปุคละ\\nปุ้งกี๋\\nปุงควะ\\nปุงลิงค์\\nปุงลึงค์\\nปุจฉา\\nปุฏะ\\nปุณฑริก\\nปุด\\nปุตตะ\\nปุถุชน\\nปุนนาค\\nปุนภพ\\nปุนัพสุ\\nปุบ\\nปุ๊บ\\nปุปผะ\\nปุปะ\\nปุพพะ\\nปุ่ม\\nปุ่มป่ำ\\nปุ้ม\\nปุ๋ม\\nปุย\\nปุ้ย\\nปุ๋ย\\nปุรณะ\\nปุระ\\nปุราณ\\nปุราณะ\\nปุริมพรรษา\\nปุเรจาริก\\nปุโรหิต\\nปุลลิงค์\\nปุลลึงค์\\nปุลินท์\\nปุโลปุเล\\nปุษยะ\\nปุสสะ\\nปู\\nปู่\\nปูชกะ\\nปูชนียบุคคล\\nปูชนียวัตถุ\\nปูชนียะ\\nปูชา\\nปูชิต\\nปูด\\nปูน\\nปูม\\nปู้ยี่ปู้ยำ\\nปูระ\\nปูลู\\nเป้\\nเป๋\\nเปก\\nเป๊ก\\nเป่ง\\nเป้ง\\nเป๋ง\\nเป็ด\\nเปตพลี\\nเปตอง\\nเป็น\\nเปยยาล\\nเปร็ง\\nเปรต\\nเปรม\\nเปรย\\nเปรอ\\nเปรอะ\\nเปราะ\\nเปรียง\\nเปรี้ยง\\nเปรี้ยงปร้าง\\nเปรียญ\\nเปรียบ\\nเปรี่ยม\\nเปรียว\\nเปรี้ยว\\nเปรียะ\\nเปรี๊ยะ\\nเปรื่อง\\nเปรื้อย\\nเปล\\nเปล่ง\\nเปลว\\nเปลา\\nเปล่า\\nเปล้า\\nเปลาะ\\nเปลี้ย\\nเปลี่ยน\\nเปลี่ยม\\nเปลี่ยว\\nเปลือก\\nเปลือง\\nเปลื้อง\\nเปลือย\\nเปศะ\\nเปศัส\\nเปสการ\\nเปสละ\\nเปสุญวาท\\nเป๋อ\\nเป้อเย้อ\\nเปอร์\\nเปอร์เซ็นต์\\nเปะ\\nเปา\\nเป่า\\nเป้า\\nเป๊า\\nเป๋า\\nเป๋าฮื้อ\\nเปาะ\\nเป๊าะ\\nเปาะเปี๊ยะ\\nเปาะแปะ\\nเปิก\\nเปิง\\nเปิงมาง\\nเปิด\\nเปิ่น\\nเปิบ\\nเปิ๊บ\\nเปีย\\nเปียก\\nเปี๊ยก\\nเปี๊ยบ\\nเปี่ยม\\nเปี้ยว\\nเปี๊ยว\\nเปียะ\\nเปี๊ยะ\\nเปือก\\nเปื้อน\\nเปื่อย\\nแป\\nแป้ง\\nแป๋ง\\nแปด\\nแป๊ด\\nแปทู\\nแป้น\\nแป๊น\\nแปบ\\nแป๊บ\\nแปม\\nแปร\\nแปร๋\\nแปรก\\nแปรง\\nแปร่ง\\nแปร๊ด\\nแปร้น\\nแปร๋น\\nแปรปรวน\\nแประ\\nแปล\\nแปล้\\nแปลก\\nแปลง\\nแปลน\\nแปลบ\\nแปล๊บ\\nแป้ว\\nแป๊ว\\nแปะ\\nแป๊ะ\\nแป๊ะซะ\\nโป\\nโป่\\nโป้\\nโป๊\\nโปก\\nโป๊ก\\nโป๊กเกอร์\\nโปกขรณี\\nโปกขรพรรษ\\nโปเก\\nโปง\\nโป่ง\\nโป้ง\\nโป่งข่าม\\nโปงลาง\\nโป่งวิด\\nโปฐบท\\nโปฐปทมาส\\nโปดก\\nโปตถกะ\\nโปน\\nโป๊ป\\nโป๊ยเซียน\\nโปรแกรม\\nโปรง\\nโปร่ง\\nโปรด\\nโปรตอน\\nโปรตีน\\nโปรเตสแตนต์\\nโปรแทรกเตอร์\\nโปรย\\nโปล่ง\\nโปลิโอ\\nโปโล\\nโปสก\\nโปสต์การ์ด\\nโปะ\\nโป๊ะ\\nโป๊ะจ้าย\\nไป\\nไป่\\nไป๋\\nไปยาล\\nไปรษณีย์\\nไปรษณียบัตร\\nไปรษณียภัณฑ์\\nไปรษณียากร\\nไปล่\\nไปศาจ\\nผก\\nผกา\\nผกาย\\nผคม\\nผง\\nผงก\\nผงม\\nผงะ\\nผงาด\\nผง่าน\\nผจง\\nผจญ\\nผจัญ\\nผจาน\\nผชุม\\nผณิน\\nผณินทร\\nผณิศวร\\nผด\\nผดุง\\nผเดิน\\nผทม\\nผนวก\\nผนวช\\nผนัง\\nผนิด\\nผนึก\\nผม\\nผยอง\\nผรณาปีติ\\nผรสุ\\nผริต\\nผรุสวาท\\nผล\\nผลคุน\\nผลคุนี\\nผล็อย\\nผละ\\nผลัก\\nผลัด\\nผลับ\\nผลัวะ\\nผลา\\nผลาญ\\nผลานิสงส์\\nผลาผล\\nผลาหาร\\nผลิ\\nผลิกะ\\nผลิต\\nผลิน\\nผลี\\nผลีผลาม\\nผลึก\\nผลึ่ง\\nผลือ\\nผลุ\\nผลุง\\nผลุด\\nผลุน\\nผลุนผลัน\\nผลุบ\\nผลุบผลับ\\nผลุย\\nผลู\\nผวน\\nผวย\\nผวา\\nผสม\\nผสาน\\nผอง\\nผ่อง\\nผ่อน\\nผอบ\\nผอม\\nผ็อย\\nผอูน\\nผะ\\nผะดา\\nผะสา\\nผัก\\nผัคคุณ\\nผัคคุณี\\nผัง\\nผัด\\nผัน\\nผับ\\nผัว\\nผัวะ\\nผัสสะ\\nผัสสาหาร\\nผา\\nผ่า\\nผ้า\\nผาก\\nผาง\\nผ่าง\\nผาณิต\\nผาด\\nผาติ\\nผ่าน\\nผาม\\nผาย\\nผ่ายผอม\\nผาล\\nผาลคุน\\nผาลา\\nผ่าว\\nผาสุก\\nผ้าฮาด\\nผำ\\nผ้ำ\\nผิ\\nผิง\\nผิด\\nผิตะ\\nผิน\\nผิว\\nผี\\nผี้ว์\\nผึง\\nผึ่ง\\nผึ้ง\\nผึ้งรวง\\nผืน\\nผื่น\\nผุ\\nผุด\\nผุยผง\\nผุสราคา\\nผู้\\nผูก\\nเผ\\nเผง\\nเผชิญ\\nเผ็ด\\nเผด็จ\\nเผดิม\\nเผดียง\\nเผ่น\\nเผนิก\\nเผย\\nเผยอ\\nเผยิบ\\nเผยิบผยาบ\\nเผล\\nเผล่\\nเผล็ด\\nเผลอ\\nเผลอไผล\\nเผละ\\nเผลาะ\\nเผลาะแผละ\\nเผลียง\\nเผอเรอ\\nเผอิญ\\nเผอิล\\nเผะ\\nเผา\\nเผ่า\\nเผ้า\\nเผาะ\\nเผิ้ง\\nเผิน\\nเผียน\\nเผือ\\nเผื่อ\\nเผือก\\nเผือด\\nเผือน\\nเผื่อน\\nแผ่\\nแผก\\nแผง\\nแผด\\nแผน\\nแผ่น\\nแผนก\\nแผล\\nแผลง\\nแผล็บ\\nแผล็ว\\nแผละ\\nแผ่ว\\nแผ้ว\\nโผ\\nโผง\\nโผฏฐัพพะ\\nโผน\\nโผเผ\\nโผย\\nโผล่\\nโผลกเผลก\\nโผละ\\nโผอน\\nโผะ\\nไผ\\nไผ่\\nไผท\\nฝน\\nฝรั่ง\\nฝรั่งเศส\\nฝ่อ\\nฝอย\\nฝัก\\nฝัง\\nฝั่ง\\nฝัด\\nฝัน\\nฝา\\nฝ่า\\nฝ้า\\nฝาก\\nฝาง\\nฝาด\\nฝาน\\nฝาย\\nฝ่าย\\nฝ้าย\\nฝิ่น\\nฝี\\nฝี่\\nฝีก\\nฝึก\\nฝืด\\nฝืน\\nฝุ่น\\nฝูง\\nเฝ้า\\nเฝือ\\nเฝือก\\nเฝือง\\nเฝื่อน\\nแฝก\\nแฝง\\nแฝด\\nใฝ่\\nไฝ\\nพก\\nพกุล\\nพง\\nพงศ์\\nพงศกร\\nพงศธร\\nพงศา\\nพงศาวดาร\\nพจน์\\nพจนา\\nพจนานุกรม\\nพจนารถ\\nพจนีย์\\nพจมาน\\nพจี\\nพชระ\\nพญา\\nพญาลอ\\nพณิช\\nพณิชย์\\nพดด้วง\\nพธู\\nพนันดร\\nพนาดร\\nพนาดอน\\nพนาราม\\nพนาลัย\\nพนาลี\\nพนาวาส\\nพนาเวศ\\nพนาศรม\\nพนาสณฑ์\\nพนาสัณฑ์\\nพเนจร\\nพ่น\\nพ้น\\nพนม\\nพนอง\\nพนอม\\nพนัก\\nพนักงาน\\nพนัง\\nพนัน\\nพนัส\\nพนา\\nพนาย\\nพนิดา\\nพนิต\\nพบ\\nพม่า\\nพยนต์\\nพยศ\\nพยัก\\nพยักพเยิด\\nพยัคฆ์\\nพยัคฆา\\nพยัคฆิน\\nพยัคฆี\\nพยัชน์\\nพยัญชนะ\\nพยัต\\nพยับ\\nพยากรณ์\\nพยาฆร์\\nพยางค์\\nพยาธิ\\nพยาน\\nพยาบาท\\nพยาบาล\\nพยาม\\nพยามะ\\nพยายาม\\nพยุ\\nพยุง\\nพยุหยาตรา\\nพยุหโยธา\\nพยุหเสนา\\nพยุหะ\\nพยู่ห์\\nพเยีย\\nพร\\nพรต\\nพรม\\nพรรค\\nพรรค์\\nพรรคานต์\\nพรรณ\\nพรรณนา\\nพรรดึก\\nพรรลาย\\nพรรษ\\nพรรษา\\nพรรเอิญ\\nพรวด\\nพรวน\\nพรหม\\nพรหมจรรย์\\nพรหมจาริณี\\nพรหมจารี\\nพรหมา\\nพรหมาสตร์\\nพรหมินทร์\\nพรอก\\nพร่อง\\nพร้อง\\nพรอด\\nพร้อม\\nพร้อมพรัก\\nพร่อย\\nพร้อย\\nพระ\\nพระนอม\\nพระนาด\\nพระฮาม\\nพรักพร้อม\\nพรั่ง\\nพรัด\\nพรั่น\\nพรับ\\nพร่า\\nพร้า\\nพราก\\nพราง\\nพร่าง\\nพราด\\nพราน\\nพราย\\nพราว\\nพราหมณ์\\nพราหมณะ\\nพราหมณี\\nพราหมี\\nพรำ\\nพร่ำ\\nพริก\\nพริ้ง\\nพริบ\\nพริ้ม\\nพรึง\\nพรึน\\nพรึบ\\nพรึ่บ\\nพรืด\\nพรุ\\nพรุ่ง\\nพรุน\\nพรู\\nพรูด\\nพฤกษ์\\nพฤกษชาติ\\nพฤกษเทวดา\\nพฤกษราช\\nพฤกษศาสตร์\\nพฤกษา\\nพฤฒ\\nพฤฒา\\nพฤฒาจารย์\\nพฤฒิ\\nพฤต\\nพฤติ\\nพฤทธ์\\nพฤทธิ์\\nพฤนต์\\nพฤนท์\\nพฤศจิก\\nพฤศจิกายน\\nพฤษภ\\nพฤษภาคม\\nพฤหัสบดี\\nพล\\nพละ\\nพลากร\\nพลาดิศัย\\nพลาธิการ\\nพลานามัย\\nพลบ\\nพลวก\\nพลวง\\nพลวัต\\nพลศาสตร์\\nพลอ\\nพล้อ\\nพลอง\\nพลอด\\nพลอน\\nพลอมแพลม\\nพลอย\\nพล่อย\\nพลั่ก\\nพลัง\\nพลั่ง\\nพลั้ง\\nพลัด\\nพลัน\\nพลับ\\nพลับพลา\\nพลับพลึง\\nพลั่ว\\nพล่า\\nพลาง\\nพลาญ\\nพลาด\\nพล่าน\\nพลาม\\nพล่าม\\nพลาย\\nพลาสติก\\nพลาสมา\\nพลาหก\\nพลำ\\nพล้ำ\\nพลำภัง\\nพลิก\\nพลิพัท\\nพลิ้ว\\nพลี\\nพลุ\\nพลุก\\nพลุ่ก\\nพลุกพล่าน\\nพลุ่ง\\nพลุ้ย\\nพลู\\nพลูโต\\nพลูโทเนียม\\nพวก\\nพวง\\nพ่วง\\nพวน\\nพวย\\nพสก\\nพสุ\\nพสุธา\\nพสุสงกรานต์\\nพหล\\nพหุ\\nพหุล\\nพหู\\nพอ\\nพ่อ\\nพ้อ\\nพอก\\nพอง\\nพ้อง\\nพอน\\nพ้อม\\nพอโลเนียม\\nพะ\\nพะงา\\nพะงาบ\\nพะจง\\nพะทำมะรง\\nพะนอ\\nพะเน้าพะนอ\\nพะเนิน\\nพะเนียง\\nพะแนง\\nพะพาน\\nพะพิง\\nพะเพิง\\nพะยอม\\nพ่ะย่ะค่ะ\\nพะยูง\\nพะยูน\\nพะเยิบ\\nพะเยิบพะยาบ\\nพะรุงพะรัง\\nพะโล้\\nพะไล\\nพะวง\\nพะวักพะวน\\nพะวา\\nพะว้าพะวัง\\nพะอง\\nพะอากพะอำ\\nพะอืดพะอม\\nพัก\\nพักตร์\\nพักตรา\\nพักร\\nพัง\\nพังกา\\nพังงา\\nพังผืด\\nพังพวย\\nพังพอน\\nพังพาน\\nพังพาบ\\nพังเพย\\nพัช\\nพัชนี\\nพัชระ\\nพัญจน์\\nพัฒนะ\\nพัฒนา\\nพัฒนากร\\nพัฒนาการ\\nพัด\\nพัดชา\\nพัดดึงส์\\nพัตร\\nพัทธ์\\nพัทธยา\\nพัทธสีมา\\nพัทร\\nพัน\\nพันตู\\nพันทาง\\nพันธ์\\nพันธะ\\nพันธกรณี\\nพันธบัตร\\nพันธมิตร\\nพันธนะ\\nพันธนาคาร\\nพันธนาการ\\nพันธุ์\\nพันธุกรรม\\nพันลึก\\nพันลือ\\nพันเลิศ\\nพันเอิญ\\nพับ\\nพัลลภ\\nพัลวัน\\nพัว\\nพัวะ\\nพัศดี\\nพัสดุ\\nพัสตร์\\nพัสถาน\\nพา\\nพาก\\nพากเพียร\\nพากย์\\nพาง\\nพ่าง\\nพาชี\\nพาณิช\\nพาณิชย์\\nพาณิชยกรรม\\nพาณิชยการ\\nพาณิชยศาสตร์\\nพาณิชยศิลป์\\nพาณินี\\nพาณี\\nพาณีนี\\nพาด\\nพาท\\nพาทย์\\nพาธ\\nพาธา\\nพาน\\nพ่าน\\nพานร\\nพานรินทร์\\nพาม\\nพาย\\nพ่าย\\nพายม้า\\nพายัพ\\nพายุ\\nพาร์เซก\\nพารณ\\nพารา\\nพาราฟิน\\nพาล\\nพาลา\\nพาลี\\nพาลุก\\nพาโล\\nพาไล\\nพาส\\nพาสน์\\nพาสนา\\nพาสุกรี\\nพ่าห์\\nพาหนะ\\nพาหะ\\nพาหา\\nพาหิรกะ\\nพาหิระ\\nพาหุ\\nพาหุรัด\\nพาหุสัจจะ\\nพาเหียร\\nพาฬ\\nพำ\\nพำนัก\\nพำพึม\\nพำลา\\nพิกล\\nพิกสิต\\nพิกัด\\nพิกัติ\\nพิกัน\\nพิการ\\nพิกุล\\nพิเคราะห์\\nพิฆน์\\nพิฆเนศ\\nพิฆเนศวร\\nพิฆาต\\nพิง\\nพิจัย\\nพิจาร\\nพิจารณ์\\nพิจารณา\\nพิจิก\\nพิจิต\\nพิจิตร\\nพิชญ์\\nพิชัย\\nพิชาน\\nพิชิต\\nพิเชฐ\\nพิเชียร\\nพิฑูรย์\\nพิณ\\nพิดทูล\\nพิดาน\\nพิโดร\\nพิตร\\nพิถี\\nพิถีพิถัน\\nพิทย\\nพิทย์\\nพิทยา\\nพิทยาคม\\nพิทยาคาร\\nพิทยาธร\\nพิทยาลัย\\nพิทักษ์\\nพิทูร\\nพิเทศ\\nพิธาน\\nพิธี\\nพิธุ\\nพินทุ\\nพินอบพิเทา\\nพินัย\\nพินาศ\\nพินิจ\\nพินิต\\nพินิศ\\nพินิศจัย\\nพิเนต\\nพิบัติ\\nพิบุล\\nพิบูล\\nพิปริต\\nพิปลาส\\nพิพรรธ\\nพิพรรธน์\\nพิพักพิพ่วน\\nพิพัฒ\\nพิพัฒน์\\nพิพากษ์\\nพิพากษา\\nพิพาท\\nพิพิธ\\nพิพิธภัณฑ์\\nพิพิธภัณฑสถาน\\nพิภพ\\nพิภัช\\nพิภาค\\nพิภูษณะ\\nพิเภก\\nพิมปะการัง\\nพิมพ์\\nพิมพการัง\\nพิมพา\\nพิมพาภรณ์\\nพิมล\\nพิมเสน\\nพิมาน\\nพิมุข\\nพิโมกข์\\nพิโมกษ์\\nพิโยกพิเกน\\nพิโยค\\nพิรอด\\nพิระ\\nพิรากล\\nพิราบ\\nพิราม\\nพิราลัย\\nพิริยะ\\nพิรี้พิไร\\nพิรุณ\\nพิรุธ\\nพิรุฬห์\\nพิเรนทร์\\nพิเราะ\\nพิโรธ\\nพิไร\\nพิลังกาสา\\nพิลาป\\nพิลาส\\nพิลิปดา\\nพิลึก\\nพิลึกกึกกือ\\nพิลึกพิลั่น\\nพิโลน\\nพิไล\\nพิศ\\nพิศวง\\nพิศวาส\\nพิศาล\\nพิศุทธ์\\nพิศุทธิ์\\nพิเศษ\\nพิษ\\nพิษฐาน\\nพิษนาศน์\\nพิสดาร\\nพิสมร\\nพิสมัย\\nพิสัง\\nพิสัช\\nพิสัย\\nพิสิฐ\\nพิสุทธิ์\\nพิสูจน์\\nพิหค\\nพิหาร\\nพิฬาร\\nพี\\nพี่\\nพี้\\nพีชคณิต\\nพีระมิด\\nพึง\\nพึ่ง\\nพึ่บ\\nพึ่บพั่บ\\nพึม\\nพึมพำ\\nพืช\\nพืด\\nพื้น\\nพุ\\nพุก\\nพุกาม\\nพุง\\nพุ่ง\\nพุงดอ\\nพุฒ\\nพุฒิ\\nพุด\\nพุดตาน\\nพุทธ\\nพุทธะ\\nพุทธังกูร\\nพุทธางกูร\\nพุทธันดร\\nพุทธาภิเษก\\nพุทธาวาส\\nพุทธิ\\nพุทโธ่\\nพุทรา\\nพุธ\\nพุ่ม\\nพุมเรียง\\nพุ้ย\\nพู\\nพูพอน\\nพู่\\nพูด\\nพูน\\nพู้น\\nพู่ระหง\\nเพ\\nเพ็ก\\nเพกา\\nเพคะ\\nเพ็ง\\nเพ่ง\\nเพ็จ\\nเพชฉลูกรรม\\nเพชฌฆาต\\nเพชร\\nเพชรดา\\nเพชรปาณี\\nเพชรฤกษ์\\nเพชรายุธ\\nเพชรกลับ\\nเพชรสังฆาต\\nเพชรหลีก\\nเพชรหึง\\nเพ็ญ\\nเพฑูริย์\\nเพณี\\nเพ็ดทูล\\nเพดาน\\nเพท\\nเพทนา\\nเพทาย\\nเพทุบาย\\nเพโทบาย\\nเพ่นพ่าน\\nเพนียด\\nเพไนย\\nเพ้ย\\nเพรง\\nเพรซีโอดิเมียม\\nเพรา\\nเพราะ\\nเพริด\\nเพริศ\\nเพรียก\\nเพรียง\\nเพรียบ\\nเพรี้ยม\\nเพรียว\\nเพรื่อ\\nเพรือง\\nเพล\\nเพลง\\nเพล็ด\\nเพล้โพล้\\nเพลา\\nเพลาะ\\nเพลิง\\nเพลิดเพลิน\\nเพลิน\\nเพลีย\\nเพลี้ย\\nเพลี่ยง\\nเพศ\\nเพส\\nเพสลาด\\nเพ่อ\\nเพ้อ\\nเพ้อเจ้อ\\nเพอิญ\\nเพะ\\nเพา\\nเพาะ\\nเพิก\\nเพิง\\nเพิ่ง\\nเพิดเพ้ย\\nเพิ่ม\\nเพี้ย\\nเพียง\\nเพี้ยง\\nเพียงออ\\nเพี้ยน\\nเพียบ\\nเพียร\\nเพื่อ\\nเพื่อน\\nแพ\\nแพ้\\nแพง\\nแพ่ง\\nแพงพวย\\nแพทย์\\nแพทยศาสตร์\\nแพน\\nแพ่น\\nแพนก\\nแพนงเชิง\\nแพร\\nแพร่\\nแพรก\\nแพร่ง\\nแพรว\\nแพร้ว\\nแพลง\\nแพลทินัม\\nแพล็บ\\nแพลม\\nแพลเลเดียม\\nแพละ\\nแพละโลม\\nแพว\\nแพ้ว\\nแพศย์\\nแพศยา\\nแพะ\\nโพ\\nโพก\\nโพกพาย\\nโพง\\nโพงพาง\\nโพชฌงค์\\nโพซิตรอน\\nโพด\\nโพทะเล\\nโพแทสเซียม\\nโพธ\\nโพธิ\\nโพธิ์\\nโพน\\nโพ้น\\nโพนทะนา\\nโพบาย\\nโพย\\nโพยก๊วน\\nโพยม\\nโพรก\\nโพรง\\nโพรโทแอกทิเนียม\\nโพรมีเทียม\\nโพระดก\\nโพล่\\nโพลง\\nโพล่ง\\nโพล้ง\\nโพลน\\nโพล้เพล้\\nโพละ\\nโพสพ\\nไพ\\nไพ่\\nไพจิตร\\nไพชน\\nไพชยนต์\\nไพฑูรย์\\nไพที\\nไพบูลย์\\nไพพรรณ\\nไพร\\nไพร่\\nไพรจิตร\\nไพรชน\\nไพรชยนต์\\nไพรฑูรย์\\nไพรที\\nไพรบูลย์\\nไพรเราะ\\nไพรัช\\nไพรำ\\nไพริน\\nไพรินทร์\\nไพรี\\nไพเราะ\\nไพโรจน์\\nไพล\\nไพล่\\nไพศาขะ\\nไพศาล\\nไพเศษ\\nไพสพ\\nไพสิฐ\\nไพหาร\\nฟก\\nฟ้ง\\nฟรักโทส\\nฟรี\\nฟลูออรีน\\nฟ่อ\\nฟ้อ\\nฟอก\\nฟอง\\nฟ่อง\\nฟ้อง\\nฟอด\\nฟอน\\nฟ่อน\\nฟ้อน\\nฟ้อแฟ้\\nฟอร์มาลดีไฮด์\\nฟอร์มาลิน\\nฟอสฟอรัส\\nฟอสเฟต\\nฟัก\\nฟักฟุ้น\\nฟัง\\nฟังก์ชัน\\nฟัด\\nฟัน\\nฟั่น\\nฟั้น\\nฟ้า\\nฟาก\\nฟาง\\nฟ่าง\\nฟาด\\nฟาทอม\\nฟาน\\nฟ่าม\\nฟาย\\nฟาร์ม\\nฟาสซิสต์\\nฟิด\\nฟิต\\nฟิบ\\nฟิล์ม\\nฟิวส์\\nฟิสิกส์\\nฟี่\\nฟี้\\nฟืดฟาด\\nฟืน\\nฟื้น\\nฟืม\\nฟุ\\nฟุ้ง\\nฟุต\\nฟุน\\nฟุบ\\nฟุ่บ\\nฟุ่มเฟือย\\nฟุลสแก๊ป\\nฟู\\nฟู่\\nฟูก\\nฟูด\\nฟูม\\nเฟ็ด\\nเฟ้น\\nเฟลด์สปาร์\\nเฟ้อ\\nเฟอร์เมียม\\nเฟอะ\\nเฟอะฟะ\\nเฟะ\\nเฟะฟะ\\nเฟิน\\nเฟี้ยม\\nเฟี้ยว\\nเฟือ\\nเฟื้อ\\nเฟือง\\nเฟื่อง\\nเฟื้อง\\nเฟือน\\nเฟือย\\nเฟื้อย\\nแฟ่\\nแฟง\\nแฟชั่น\\nแฟน\\nแฟบ\\nแฟ้ม\\nแฟรนเซียม\\nแฟลกซ์\\nแฟลต\\nแฟะ\\nโฟกัส\\nไฟ\\nภควดี\\nภควัต\\nภควันต์\\nภควัม\\nภควา\\nภควาน\\nภคะ\\nภคันทลา\\nภคินี\\nภณะ\\nภณิดา\\nภพ\\nภมร\\nภมริน\\nภมรี\\nภมุกา\\nภยันตราย\\nภยาคติ\\nภระ\\nภรณี\\nภรต\\nภรรดร\\nภรรดา\\nภรรยา\\nภระมร\\nภระมรี\\nภราดร\\nภราดรภาพ\\nภราดา\\nภริยา\\nภฤศ\\nภวะ\\nภวตัณหา\\nภวนะ\\nภวังค์\\nภวังคจิต\\nภักดี\\nภักตะ\\nภักติ\\nภักษ์\\nภักษา\\nภักษาหาร\\nภัค\\nภัคน์\\nภังคะ\\nภังคี\\nภัจ\\nภัณฑ์\\nภัณฑาคาร\\nภัณฑาคาริก\\nภัณฑารักษ์\\nภัณฑนะ\\nภัณฑู\\nภัต\\nภัตตาคาร\\nภัตตาหาร\\nภัตร\\nภัทระ\\nภัทรกัป\\nภัพ\\nภัย\\nภัสดา\\nภัสตรา\\nภัสมะ\\nภัสสร\\nภา\\nภาค\\nภาคย์\\nภาคยานุวัติ\\nภาคินี\\nภาคิไนย\\nภาคี\\nภาคียะ\\nภาชนะ\\nภาชี\\nภาณ\\nภาณวาร\\nภาณกะ\\nภาณี\\nภาณุ\\nภาดร\\nภาดา\\nภาตระ\\nภาตา\\nภาตุ\\nภาติกะ\\nภาติยะ\\nภาพ\\nภาพย์\\nภาม\\nภาย\\nภาร\\nภาระ\\nภารดี\\nภารต\\nภารตี\\nภารยทรัพย์\\nภารยา\\nภารา\\nภาวนา\\nภาวะ\\nภาษ\\nภาษณ์\\nภาษา\\nภาษิต\\nภาษี\\nภาส\\nภาสน์\\nภาสวร\\nภาสา\\nภาสุระ\\nภิกขา\\nภิกขาจาร\\nภิกขุ\\nภิกขุนี\\nภิกษา\\nภิกษาจาร\\nภิกษาหาร\\nภิกษุ\\nภิกษุณี\\nภิงคาร\\nภิญโญ\\nภิตติ\\nภินท์\\nภินทนาการ\\nภิยโย\\nภิรมย์\\nภิรมย์สุรางค์\\nภิษัช\\nภิสัก\\nภีตะ\\nภีมะ\\nภีรุ\\nภุกต์\\nภุขัน\\nภุช\\nภุชงค์\\nภุต\\nภุมมะ\\nภุมรัตน์\\nภุมวาร\\nภุมรา\\nภุมริน\\nภุมรี\\nภุมเรศ\\nภู\\nภู่\\nภูต\\nภูติ\\nภูม\\nภูมิ\\nภูมี\\nภูริ\\nภูรี\\nภูวดล\\nภูวนาถ\\nภูวเนตร\\nภูวไนย\\nภูษา\\nภูษิต\\nเภกะ\\nเภตรา\\nเภท\\nเภทุบาย\\nเภรี\\nเภสัช\\nโภค\\nโภคะ\\nโภคิน\\nโภคี\\nโภไคย\\nโภไคศวรรย์\\nโภช\\nโภชย์\\nโภชก\\nโภชนะ\\nโภชนา\\nโภชนาหาร\\nโภชนียะ\\nไภริน\\nไภรี\\nไภษัชคุรุ\\nไภษัชย์\\nมกร\\nมกราคม\\nมกุฎ\\nมคธ\\nมฆวัน\\nมฆะ\\nมฆา\\nม่ง\\nมงกุฎ\\nมงโกรย\\nมงคล\\nมงคลวาร\\nมณฑ์\\nมณฑก\\nมณฑนะ\\nมณฑป\\nมณฑล\\nมณฑา\\nมณฑารพ\\nมณฑิระ\\nมณเฑียร\\nมณี\\nมด\\nมตะ\\nมตกภัต\\nมติ\\nมทนะ\\nมทะ\\nมธุ\\nมธุกร\\nมธุการี\\nมธุลีห์\\nมธุระ\\nมธุรพจน์\\nมน\\nมนินทรีย์\\nม่น\\nมนต์\\nมนตร์\\nมนตรี\\nมนท์\\nมนทิราลัย\\nมนเทียร\\nมนสิการ\\nมนัส\\nมนัสวี\\nมนินทรีย์\\nมนิมนา\\nมนิลา\\nมนุญ\\nมนุษย์\\nมนุษยชาติ\\nมนุษยธรรม\\nมนุษย์มนา\\nมนุษยโลก\\nมนุษยศาสตร์\\nมนุษยสัมพันธ์\\nมนุสาร\\nมนู\\nมนูสาร\\nมโน\\nมโนช\\nมโนชญ์\\nมโนราห์\\nมโนสาเร่\\nมโนห์รา\\nมมังการ\\nมยุรฉัตร\\nมยุระ\\nมยุรา\\nมยุรี\\nมยุเรศ\\nมยูร\\nมรกต\\nมรคา\\nมรฑป\\nมรณ์\\nมรณะ\\nมรณกรรม\\nมรณบัตร\\nมรณภัย\\nมรณภาพ\\nมรดก\\nมรรค\\nมรรคา\\nมรรตัย\\nมรรยาท\\nมรรษ\\nมรสุม\\nมริจ\\nมริยาท\\nมรีจิ\\nมรุต\\nมฤค\\nมฤคย์\\nมฤคศิระ\\nมฤคศิรมาส\\nมฤคเศียร\\nมฤคินทร์\\nมฤเคนทร์\\nมฤดก\\nมฤต\\nมฤตยู\\nมฤทุ\\nมล\\nมละ\\nมลัก\\nมลังเมลือง\\nมล้าง\\nมลาย\\nมลายู\\nมวก\\nม่วง\\nมวน\\nม่วน\\nม้วน\\nม้วนต้วน\\nมวย\\nม้วย\\nมวล\\nมหกรรม\\nมหรณพ\\nมหรรณพ\\nมหรสพ\\nมหัจฉริยะ\\nมหัต\\nมหัทธนะ\\nมหันต์\\nมหันตโทษ\\nมหัพภาค\\nมหัศจรรย์\\nมหา\\nมหากฐิน\\nมหากาฬ\\nมหาขันธกะ\\nมหาจักร\\nมหาชน\\nมหาชัย\\nมหาชาติ\\nมหาโชตรัต\\nมหาดไทย\\nมหาดเล็ก\\nมหาตมะ\\nมหาไถ่\\nมหาเทพ\\nมหาเทพี\\nมหาเทวี\\nมหาธาตุ\\nมหานิกาย\\nมหานิล\\nมหาบพิตร\\nมหาบัณฑิต\\nมหาพน\\nมหาพรหม\\nมหาภารตะ\\nมหาภิเนษกรมณ์\\nมหาภูต\\nมหาเมฆ\\nมหายาน\\nมหายุค\\nมหาราช\\nมหาฤกษ์\\nมหาละลวย\\nมหาละลาย\\nมหาวงศ์\\nมหาวรรค\\nมหาวิทยาลัย\\nมหาศักราช\\nมหาศาล\\nมหาสงกรานต์\\nมหาสดมภ์\\nมหาสดำ\\nมหาสมุทร\\nมหาสาวก\\nมหาหงส์\\nมหาหิงคุ์\\nมหาอำนาจ\\nมหาอุจ\\nมหาอุด\\nมหาอุปรากร\\nมหาอุปราช\\nมหิ\\nมหิดล\\nมหิธร\\nมหิป\\nมหิงส์\\nมหิทธิ\\nมหินท์\\nมหิมา\\nมหิศร\\nมหิศวร\\nมหิษ\\nมหิษี\\nมหึมา\\nมเหยงค์\\nมเหศ\\nมเหศวร\\nมเหศักดิ์\\nมเหสักข์\\nมเหสิ\\nมเหสี\\nมเหาฬาร\\nมโหรสพ\\nมโหระทึก\\nมโหรี\\nมโหฬาร\\nมไหศวรรย์\\nมอ\\nมอง\\nมองโกลอยด์\\nมองโกเลีย\\nมองคร่อ\\nมอญ\\nมอด\\nม่อต้อ\\nมอเตอร์\\nมอเตอร์ไซค์\\nมอน\\nม่อน\\nมอบ\\nมอม\\nมอมแมม\\nม่อย\\nมอร์ฟีน\\nมอระกู่\\nมอลโทส\\nม่อลอกม่อแลก\\nม่อห้อม\\nม่อฮ่อม\\nมะ\\nมะกรูด\\nมะกล่ำ\\nมะกอก\\nมะก่อง\\nมะกะโรนี\\nมะกา\\nมะเกลือ\\nมะเกี๋ยง\\nมะข่วง\\nมะขวิด\\nมะขาม\\nมะเขือ\\nมะแข่น\\nมะคังแดง\\nมะค่า\\nมะคำไก่\\nมะคำดีควาย\\nมะงั่ว\\nมะงุมมะงาหรา\\nมะซัก\\nมะซาง\\nมะดัน\\nมะดีหวี\\nมะดูก\\nมะเดหวี\\nมะเดื่อ\\nมะต้อง\\nมะตะบะ\\nมะตาด\\nมะตาหะรี\\nมะตึ่ง\\nมะตื๋น\\nมะตูม\\nมะแตก\\nมะโต\\nมะนาว\\nมะปราง\\nมะปริง\\nมะฝ่อ\\nมะพร้าว\\nมะพลับ\\nมะพูด\\nมะแพน\\nมะแพร้ว\\nมะเฟือง\\nมะแฟน\\nมะไฟ\\nมะม่วง\\nมะม่าว\\nมะมี่\\nมะมื่น\\nมะมุด\\nมะเมอ\\nมะเมีย\\nมะเมื่อย\\nมะแม\\nมะยง\\nมะยม\\nมะระ\\nมะริด\\nมะรืน\\nมะรุม\\nมะรุมมะตุ้ม\\nมะเร็ง\\nมะเรื่อง\\nมะโรง\\nมะลอกมะแลก\\nมะละกอ\\nมะลิ\\nมะลื่น\\nมะลืมดำ\\nมะลุลี\\nมะแว้ง\\nมะสัง\\nมะเส็ง\\nมะหวด\\nมะหะหมัด\\nมะหาด\\nมะหิ่ง\\nมะเหงก\\nมะอึก\\nมะฮอกกานี\\nมัก\\nมักกะโรนี\\nมักกะลีผล\\nมักกะสัน\\nมักขะ\\nมั่กขั้ก\\nมักขิกา\\nมัค\\nมัคคะ\\nมัคคุเทศก์\\nมัคนายก\\nมัฆวาน\\nมั่ง\\nมังกง\\nมังกร\\nมังกุ\\nมังคละ\\nมังค่า\\nมังคุด\\nมังตาน\\nมังสวิรัติ\\nมังสะ\\nมังสี\\nมัจจะ\\nมัจจุ\\nมัจฉริยะ\\nมัจฉรี\\nมัจฉะ\\nมัจฉา\\nมัชชะ\\nมัชวิรัติ\\nมัชชาระ\\nมัชฌันติกสมัย\\nมัชฌิม\\nมัชฌิมา\\nมัญจา\\nมัญชิษฐา\\nมัญชุ\\nมัญชุสา\\nมัญชูสา\\nมัญเชฏฐะ\\nมัฏฐะ\\nมัณฑนศิลป์\\nมัณฑนา\\nมัด\\nมัตตะ\\nมัตตัญญู\\nมัตตา\\nมัตติกา\\nมัตถกะ\\nมัตถลุงค์\\nมัตสยะ\\nมัตสยา\\nมัตสระ\\nมัตสริน\\nมัททวะ\\nมัทนะ\\nมัทยะ\\nมัธยฐาน\\nมัธยม\\nมัธยันห์\\nมัธยัสถ์\\nมัน\\nมั่น\\nมันตา\\nมันถะ\\nมันทิระ\\nมันทิราลัย\\nมับ\\nมั้ม\\nมัมมี่\\nมัย\\nมัลละ\\nมัลลิกา\\nมัว\\nมัวซัว\\nมั่ว\\nมัศยา\\nมัสตุ\\nมัสตาร์ด\\nมัสมั่น\\nมัสยิด\\nมัสรู่\\nมัสลิน\\nมัสสุ\\nมา\\nม้า\\nมาก\\nมาคสิระ\\nมาฆบูชา\\nมาฆะ\\nม้าง\\nมางสะ\\nมาณพ\\nมาณวิกา\\nมาด\\nมาดา\\nมาตงค์\\nมาตร\\nมาตรา\\nมาตฤ\\nมาตังคะ\\nมาตา\\nมาตามหัยกะ\\nมาตามหัยกา\\nมาตามหัยยิกา\\nมาติกะ\\nมาติกา\\nมาตุ\\nมาตุจฉา\\nมาตุรงค์\\nมาตุเรศ\\nมาตุละ\\nมาตุลา\\nมาตุลานี\\nมาทะ\\nมาธยมิก\\nมาธยมิกะ\\nมาธุระ\\nมาธุสร\\nมาธูระ\\nมาน\\nม่าน\\nม้าน\\nมานพ\\nมานะ\\nมานัต\\nมานัส\\nมานิต\\nมานี\\nมานุษ\\nมานุษยวิทยา\\nมาโนชญ์\\nมาบ\\nมาภา\\nม้าม\\nม่าย\\nมายา\\nมาร\\nมาราธิราช\\nมารค\\nมารดร\\nมารดา\\nมารยา\\nมารยาท\\nมารศรี\\nมารษา\\nมาริต\\nมารุต\\nมาลย์\\nมาลัย\\nมาลา\\nมาลาตี\\nมาลาเรีย\\nมาลินี\\nมาลี\\nมาลุต\\nมาศ\\nมาส\\nมาสก\\nมาห์\\nม่าห์\\nมาหิส\\nม่าเหมี่ยว\\nมาฬก\\nมิ\\nมิค\\nมิคสัญญี\\nมิ่ง\\nมิจฉา\\nมิด\\nมิตร\\nมิติ\\nมิเตอร์\\nมิถยา\\nมิถุน\\nมิถุนายน\\nมิทธะ\\nมินตรา\\nมินตา\\nมินหม้อ\\nมิ่ม\\nมิ้ม\\nมิไย\\nมิรันตี\\nมิลลิกรัม\\nมิลลิบาร์\\nมิลลิเมตร\\nมิลลิลิตร\\nมิลักขะ\\nมิลักขู\\nมิส\\nมิสกรี\\nมิสกวัน\\nมิสซา\\nมี\\nมี่\\nมีด\\nมีเทน\\nมีน\\nมีนาคม\\nมี่สั้ว\\nมึง\\nมึน\\nมืด\\nมืน\\nมื่น\\nมือ\\nมื้อ\\nมุ\\nมุก\\nมุกดา\\nมุกดาหาร\\nมุกุระ\\nมุข\\nมุขเด็จ\\nมุขยประโยค\\nมุโขโลกนะ\\nมุคคะ\\nมุง\\nมุ่ง\\nมุ้ง\\nมุจฉา\\nมุจนะ\\nมุจลินท์\\nมุญจนะ\\nมุญชะ\\nมุฐิ\\nมุณฑกะ\\nมุณฑะ\\nมุด\\nมุตกิด\\nมุตฆาต\\nมุตตะ\\nมุตตา\\nมุตติ\\nมุตะ\\nมุติ\\nมุททา\\nมุทธชะ\\nมุทธา\\nมุทธาภิเษก\\nมุทรา\\nมุทริกา\\nมุทะลุ\\nมุทา\\nมุทิกา\\nมุทิงค์\\nมุทิตา\\nมุทุ\\nมุทุตา\\nมุ่น\\nมุนิ\\nมุนินทร์\\nมุนี\\nมุบ\\nมุบมิบ\\nมุม\\nมุ้ม\\nมุ่ย\\nมุรธา\\nมุรธาภิเษก\\nมุสละ\\nมุสลิม\\nมุสา\\nมุสิก\\nมุหงิด\\nมุหน่าย\\nมุหุต\\nมุฮัมมัด\\nมูก\\nมูเซอ\\nมูตร\\nมู่ทู่\\nมูน\\nมูมมาม\\nมูรติ\\nมูรธา\\nมูรธาภิเษก\\nมูล\\nมูละ\\nมูลา\\nมูลิกากร\\nมู่ลี่\\nมู่เล่\\nมูสัง\\nมูสิก\\nมูสิกะ\\nมูสิกทันต์\\nเม\\nเม็ก\\nเมกะเฮิรตซ์\\nเมขลา\\nเมฆ\\nเมฆา\\nเมฆินทร์\\nเมฆี\\nเม็ง\\nเม็ด\\nเมตตา\\nเมตไตรย\\nเมตร\\nเมตริก\\nเมตริกตัน\\nเมถุน\\nเมท\\nเมโท\\nเมทนี\\nเมทินี\\nเมทนีดล\\nเมทานอล\\nเมทิลแอลกอฮอล์\\nเมธ\\nเมธา\\nเมธาวี\\nเมธี\\nเมน\\nเม่น\\nเม้น\\nเมนเดลีเวียม\\nเมนทอล\\nเม้ม\\nเมรัย\\nเมริเดียน\\nเมรุ\\nเมล์\\nเมล็ด\\nเมลือง\\nเมษ\\nเมษายน\\nเมห์\\nเมหนะ\\nเมหะ\\nเมะ\\nเมา\\nเม่า\\nเม้า\\nเมารี\\nเมาลี\\nเมาฬี\\nเมาะ\\nเมิง\\nเมิน\\nเมิล\\nเมีย\\nเมียง\\nเมี่ยง\\nเมี้ยน\\nเมือ\\nเมื้อ\\nเมื่อ\\nเมือก\\nเมือง\\nเมือบ\\nเมื่อย\\nแม่\\nแม้\\nแมก\\nแมกนีเซียม\\nแมง\\nแมงกะพรุน\\nแมงกานิน\\nแมงกานีส\\nแมงคา\\nแมงคาเรือง\\nแมงช้าง\\nแมงดา\\nแมงลัก\\nแม่ตะงาว\\nแมน\\nแม่น\\nแม้น\\nแมลง\\nแมลบ\\nแมว\\nแม้ว\\nแมะ\\nโม\\nโม่\\nโม้\\nโมก\\nโมกข์\\nโมกษะ\\nโมฆกรรม\\nโมฆสัญญา\\nโมฆะ\\nโมฆียกรรม\\nโมฆียะ\\nโมง\\nโม่ง\\nโมงครุ่ม\\nโมทนา\\nโมโนแซ็กคาไรด์\\nโมไนย\\nโมเม\\nโมเมนต์\\nโมเย\\nโมรา\\nโมรี\\nโมเรส\\nโมลิบดีนัม\\nโมลี\\nโมเลกุล\\nโมเสก\\nโมเสส\\nโม่ห์\\nโมหะ\\nโมหันธ์\\nโมหาคติ\\nโมโห\\nไม่\\nไม้\\nไมกา\\nไมครอน\\nไมโครกรัม\\nไมโครฟิล์ม\\nไมโครโฟน\\nไมโครมิเตอร์\\nไมโครเมตร\\nไมโครลิตร\\nไมโครเวฟ\\nไมตรี\\nไมยราบ\\nไมล์\\nยก\\nยกกระบัตร\\nยกนะ\\nยง\\nยงโย่\\nยชุรเวท\\nยติ\\nยติภังค์\\nยถากรรม\\nยถาภูตญาณ\\nย่น\\nยนต์\\nยนตร์\\nยม\\nยมก\\nยมโดย\\nยมนา\\nยมล\\nยมะ\\nยรรยง\\nยล\\nยวง\\nยวด\\nยวน\\nยวบ\\nย้วย\\nยวรยาตร\\nยศ\\nยโส\\nยอ\\nย่อ\\nยอก\\nย็อกแย็ก\\nยอง\\nย่อง\\nย้อง\\nยอด\\nยอน\\nย้อน\\nยอบ\\nยอม\\nย่อม\\nย้อม\\nย่อย\\nย้อย\\nย้อแย้\\nยะ\\nย่ะ\\nยะยอบ\\nยะยับ\\nยัก\\nยักข์\\nยักขินี\\nยักษ์\\nยักษา\\nยักษิณี\\nยักษี\\nยัง\\nยั้ง\\nยั่งยืน\\nยัชโญปวีต\\nยัญ\\nยัญญะ\\nยัด\\nยัติภังค์\\nยัน\\nยั่น\\nยันต์\\nยันตร\\nยันตร์\\nยันตรกรรม\\nยั่นตะนี\\nยับ\\nยั่ว\\nยั้ว\\nยั้วเยี้ย\\nยัวรยาตร\\nยัวะ\\nยัษฏิ\\nยา\\nย่า\\nยาก\\nยาคุ\\nยาคู\\nยาง\\nย่าง\\nยางพารา\\nยาจก\\nยาจนา\\nยาไฉน\\nยาด\\nยาดา\\nยาตร\\nยาตรา\\nยาน\\nย่าน\\nย่านพาโหม\\nยานมาศ\\nยานุมาศ\\nยานี\\nยาม\\nย่าม\\nยามะ\\nยามักการ\\nยามา\\nยาย\\nย้าย\\nยายี\\nยาว\\nย้าว\\nยาวกาลิก\\nยาวชีวิก\\nยาสูบ\\nย่าหยา\\nยาหยี\\nยำ\\nย่ำ\\nย้ำ\\nยำเยีย\\nยิก\\nยิง\\nยิ่ง\\nยิฏฐะ\\nยิน\\nยิบ\\nยิบหยี\\nยิปซัม\\nยิปซี\\nยิ้ม\\nยิมนาสติก\\nยิหวา\\nยี\\nยี่\\nยี้\\nยี่ก่า\\nยี่เก\\nยี่เข่ง\\nยี่โถ\\nยีน\\nยี่โป้\\nยี่ภู่\\nยีราฟ\\nยี่สก\\nยี่สง\\nยี่สน\\nยี่สาน\\nยี่สุ่น\\nยี่หระ\\nยี่หร่า\\nยี่ห้อ\\nยี่หุบ\\nยึกยัก\\nยึกยือ\\nยึด\\nยืด\\nยืน\\nยื่น\\nยืม\\nยื้อ\\nยุ\\nยุกกระบัตร\\nยุกดิ\\nยุกติ\\nยุกติธรรม\\nยุกต์\\nยุค\\nยุคนธร\\nยุคล\\nยุคันต์\\nยุคันธร\\nยุคุนธร\\nยุง\\nยุ่ง\\nยุ้ง\\nยุด\\nยุต\\nยุติ\\nยุทธ\\nยุทธ์\\nยุทธนา\\nยุทโธปกรณ์\\nยุบ\\nยุ่บ\\nยุ่บยั่บ\\nยุบล\\nยุพดี\\nยุพเรศ\\nยุพา\\nยุพาน\\nยุพาพาล\\nยุพาพิน\\nยุ่มย่าม\\nยุ่ย\\nยุ้ย\\nยุรยาตร\\nยูรยาตร\\nยุวชน\\nยุวดี\\nยุวราช\\nยุวา\\nยุวาน\\nยู\\nยู่\\nยูง\\nยูโด\\nยูถะ\\nยูถิกา\\nยูริก\\nยูเรนัส\\nยูเรเนียม\\nยูโรเพียม\\nเย\\nเย้\\nเยง\\nเยซู\\nเย็ด\\nเย็น\\nเย็นตาโฟ\\nเย็นเตาโฟ\\nเย็บ\\nเย้ย\\nเยอ\\nเย่อ\\nเยอรมัน\\nเยอว\\nเย่อหยิ่ง\\nเยอะ\\nเยอะแยะ\\nเยา\\nเย้า\\nเยาว์\\nเยาวชน\\nเยาวมาลย์\\nเยาวยอด\\nเยาวราช\\nเยาวเรศ\\nเยาวลักษณ์\\nเยาวพา\\nเยาวพาณี\\nเยาวพาน\\nเยาะ\\nเยิง\\nเยิน\\nเยิ่น\\nเยิ่นเย้อ\\nเยินยอ\\nเยิบ\\nเยิบยาบ\\nเยิ้ม\\nเยีย\\nเยี่ยง\\nเยี่ยงอย่าง\\nเยียงผา\\nเยียดยัด\\nเยียน\\nเยียบ\\nเยี่ยม\\nเยียรบับ\\nเยียรยง\\nเยียว\\nเยี่ยว\\nเยียวยา\\nเยือ\\nเยื่อ\\nเยื้อ\\nเยือก\\nเยือง\\nเยื่อง\\nเยื้อง\\nเยือน\\nเยื้อน\\nแย่\\nแย้\\nแยก\\nแยง\\nแย่ง\\nแย้ง\\nแยงแย่\\nแยงแย้\\nแยบ\\nแย็บ\\nแยม\\nแย้ม\\nแยแส\\nแยะ\\nโย\\nโย้\\nโยก\\nโยกเยก\\nโยคาพจร\\nโยคาวจร\\nโยคเกณฑ์\\nโยคยะ\\nโยคะ\\nโยคิน\\nโยคี\\nโยง\\nโย่ง\\nโย่งเย่ง\\nโยงโย่\\nโยชน์\\nโยชนา\\nโยถิกะ\\nโยทะกา\\nโยธวาทิต\\nโยธา\\nโยธิน\\nโยน\\nโยนก\\nโยนิโส\\nโยนี\\nโยม\\nโยโส\\nใย\\nไย\\nไย่\\nไยดี\\nไยไพ\\nรก\\nรง\\nรงค์\\nรงควัตถุ\\nรงรอง\\nรจนา\\nรจเรข\\nรจเลข\\nรจิต\\nรชตะ\\nรชนิ\\nรชนี\\nรชะ\\nรณรงค์\\nรด\\nรดี\\nรตนะ\\nรตะ\\nรติ\\nรถ\\nรน\\nร่น\\nรบ\\nรบาญ\\nรพี\\nรม\\nร่ม\\nรมณี\\nรมณีย์\\nรมณียสถาน\\nรมย์\\nรมเยศ\\nรยางค์\\nรวก\\nรวง\\nร่วง\\nรวด\\nรวน\\nรวนเร\\nร่วน\\nรวบ\\nรวม\\nร่วม\\nรวย\\nรวิ\\nรวิวาร\\nรวี\\nรศนา\\nรส\\nรสนา\\nรสสุคนธ์\\nรสายนเวท\\nรสิก\\nรหัท\\nรหัส\\nรโห\\nรโหฐาน\\nรอ\\nร่อ\\nรอก\\nรอง\\nร่อง\\nร้อง\\nรองเง็ง\\nร่องแร่ง\\nรอด\\nรอน\\nร่อน\\nร้อน\\nรอบ\\nรอบคอบ\\nรอม\\nรอมชอม\\nรอมร่อ\\nรอย\\nร่อย\\nร้อย\\nร่อแร่\\nระ\\nระกะ\\nระกา\\nระกำ\\nระเกะระกะ\\nระคน\\nระคาง\\nระคาย\\nระแคะ\\nระฆัง\\nระงม\\nระงับ\\nระแง้\\nระโงกหิน\\nระชวย\\nระดม\\nระดะ\\nระดับ\\nระดา\\nระด่าว\\nระดู\\nระเด่น\\nระเดียง\\nระแด\\nระตู\\nระทก\\nระทด\\nระทม\\nระทวย\\nระทา\\nระทึก\\nระแทะ\\nระนาด\\nระนาบ\\nระนาม\\nระนาว\\nระเนน\\nระเนระนาด\\nระเนียด\\nระแนง\\nระแนะ\\nระบบ\\nระบม\\nระบอบ\\nระบัด\\nระบับ\\nระบาด\\nระบาย\\nระบำ\\nระบิล\\nระบือ\\nระบุ\\nระเบง\\nระเบ็ง\\nระเบิด\\nระเบียง\\nระเบียน\\nระเบียบ\\nระแบบ\\nระมัดระวัง\\nระมาด\\nระเมียร\\nระย่อ\\nระย่อม\\nระยะ\\nระยั้ง\\nระยับ\\nระย้า\\nระยาบ\\nระยำ\\nระยิบระยับ\\nระโยง\\nระโยงระยาง\\nระรวย\\nระรอง\\nระร่อน\\nระรัว\\nระราน\\nระร่าย\\nระริก\\nระรี่\\nระรึง\\nระรื่น\\nระรื้น\\nระเร้ง\\nระเริง\\nระเรียง\\nระเรื่อย\\nระแรง\\nระลวง\\nระลอก\\nระลึก\\nระวัง\\nระวาง\\nระวาย\\nระวิง\\nระแวง\\nระแวดระวัง\\nระไว\\nระส่ำระสาย\\nระหกระเหิน\\nระหง\\nระหวย\\nระหว่าง\\nระหองระแหง\\nระหัด\\nระหาย\\nระเห็จ\\nระเหย\\nระเหระหน\\nระเหหน\\nระเหิด\\nระเหินระหก\\nระแหง\\nระโหย\\nระอา\\nระอิดระอา\\nระอุ\\nรัก\\nรักข์\\nรักขิต\\nรักตะ\\nรักบี้\\nรักเร่\\nรักแร้\\nรักษ์\\nรักษา\\nรัง\\nรั้ง\\nรังเกียจ\\nรังแก\\nรังค์\\nรังควาน\\nรังแค\\nรังรอง\\nรังวัด\\nรังสิ\\nรังสี\\nรังสิมันตุ์\\nรังสิมา\\nรัจฉา\\nรัช\\nรัชชูปการ\\nรัชมังคลาภิเษก\\nรัชชุ\\nรัชฎาภิเษก\\nรัชดาภิเษก\\nรัชนะ\\nรัชนี\\nรัญจวน\\nรัฏฐาภิปาลโนบาย\\nรัฐ\\nรัฐประศาสโนบาย\\nรัฐประศาสนศาสตร์\\nรัด\\nรัต\\nรัตกัมพล\\nรัตมณี\\nรัตคน\\nรัตจันทน์\\nรัตตัญญู\\nรัตติ\\nรัตน์\\nรัตนะ\\nรัตนโกสินทร์\\nรัตนโกสินทรศก\\nรัตนชาติ\\nรัตนตรัย\\nรัตนบัลลังก์\\nรัตนวราภรณ์\\nรัตนสิงหาสน์\\nรัตนา\\nรัตนากร\\nรัตนาภรณ์\\nรัตนาวลี\\nรัตมา\\nรัถ\\nรัถยา\\nรัทเทอร์ฟอร์เดียม\\nรัน\\nรั้น\\nรันทด\\nรันทวย\\nรับ\\nรัมณียสถาน\\nรัมภา\\nรัมมี่\\nรัมย์\\nรัย\\nรัว\\nรั่ว\\nรั้ว\\nรัศมิมัต\\nรัศมิมาน\\nรัศมี\\nรัษฎากร\\nรัสเซีย\\nรัสสะ\\nรัสสระ\\nรา\\nร่า\\nร้า\\nราก\\nรากษส\\nรากสาด\\nราคะ\\nราคจริต\\nราคา\\nราคิน\\nราคี\\nราง\\nร่าง\\nร้าง\\nรางจืด\\nรางชาง\\nรางวัล\\nราช\\nราชกิจจานุเบกษา\\nราชนิกุล\\nราชวโรงการ\\nราชญี\\nราชดัด\\nราชพฤกษ์\\nราชมาณพ\\nราชมาษ\\nราชมาส\\nราชย์\\nราชสีห์\\nราชะ\\nราชัน\\nราชันย์\\nราชัย\\nราชา\\nราชาธิปไตย\\nราชาธิราช\\nราชาภิเษก\\nราชายตนะ\\nราชาวดี\\nราชี\\nราชินิกุล\\nราชินีกุล\\nราชินี\\nราชินูปถัมภ์\\nราชูปถัมภ์\\nราชูปโภค\\nราเชน\\nราเชนทร์\\nราเชนทรยาน\\nราโชวาท\\nราไชศวรรย์\\nราญ\\nราญรอน\\nราด\\nราต\\nราตร\\nราตรี\\nราน\\nร่าน\\nร้าน\\nราบ\\nราพณ์\\nราพณาสูร\\nราม\\nรามเกียรติ์\\nรามสูร\\nรามัญ\\nรามา\\nราย\\nร่าย\\nร้าย\\nราว\\nร้าว\\nราวี\\nราศี\\nราษฎร\\nราษฎร์\\nราษตรี\\nราษราตรี\\nราหุ\\nราหู\\nรำ\\nร่ำ\\nรำคาญ\\nรำงับ\\nรำจวน\\nรำบาญ\\nรำพัน\\nรำพาย\\nรำพึง\\nรำเพย\\nรำไพ\\nรำมะนา\\nรำมะนาด\\nรำมะร่อ\\nร่ำรวย\\nร่ำร่ำ\\nรำไร\\nรำลึก\\nรำหัด\\nรำหัส\\nริ\\nริก\\nริดสีดวง\\nริน\\nริ้น\\nริบ\\nริบบิ้น\\nริบรี่\\nริบหรี่\\nริปุ\\nริปู\\nริม\\nริ้ว\\nริษยา\\nรี\\nรี่\\nรี้พล\\nรีด\\nรีดักชัน\\nรีต\\nรีเนียม\\nรีบ\\nรีม\\nรีรอ\\nรี้ริก\\nรึง\\nรึ้ง\\nรื่น\\nรื้น\\nรื้อ\\nรุ\\nรุก\\nรุกข์\\nรุกขชาติ\\nรุกขเทวดา\\nรุกขมูล\\nรุกขา\\nรุกรุย\\nรุ่ง\\nรุ้ง\\nรุงรัง\\nรุ่งริ่ง\\nรุจ\\nรุจา\\nรุจนะ\\nรุจิ\\nรุจี\\nรุจิระ\\nรุจิรา\\nรุด\\nรุต\\nรุทธ์\\nรุทระ\\nรุธิร\\nรุธิระ\\nรุเธียร\\nรุน\\nรุ่น\\nรุบรู่\\nรุม\\nรุ่ม\\nรุ่มร่าม\\nรุย\\nรุ่ย\\nรุรุ\\nรุหะ\\nรู\\nรู่\\nรู้\\nรูจี\\nรูด\\nรูทีเนียม\\nรูบิเดียม\\nรูป\\nรูปิยะ\\nรูปี\\nรูเล็ตต์\\nเร่\\nเรข\\nเรขา\\nเรขาคณิต\\nเร็ง\\nเร่ง\\nเร้ง\\nเรณุ\\nเรณู\\nเรดอน\\nเรดาร์\\nเรเดียม\\nเร้น\\nเรรวน\\nเรไร\\nเร็ว\\nเร่ว\\nเรวดี\\nเรอ\\nเร่อ\\nเรา\\nเร่า\\nเร้า\\nเราะ\\nเริง\\nเริด\\nเริม\\nเริ่ม\\nเริ้ม\\nเริศร้าง\\nเรี่ย\\nเรี้ย\\nเรียก\\nเรียง\\nเรียด\\nเรียน\\nเรียบ\\nเรียม\\nเรี่ยม\\nเรียว\\nเรี่ยว\\nเรี้ยวรก\\nเรือ\\nเรื่อ\\nเรื้อ\\nเรือก\\nเรือง\\nเรื่อง\\nเรื้อง\\nเรืองรอง\\nเรือด\\nเรือน\\nเรื้อน\\nเรื่อย\\nแร\\nแร่\\nแรก\\nแร็กเกต\\nแรง\\nแร่ง\\nแร้ง\\nแรด\\nแร้นแค้น\\nแรม\\nแร้ว\\nแระ\\nโร\\nโร่\\nโรค\\nโรคา\\nโรคาพาธ\\nโรง\\nโรจ\\nโรจน์\\nโรเดียม\\nโรตี\\nโรท\\nโรธ\\nโรม\\nโรมัน\\nโรเมอร์\\nโรย\\nโรเร\\nโรหิณี\\nโรหิต\\nไร\\nไร่\\nไร้\\nไรย์\\nฤกษ์\\nฤกษณะ\\nฤคเวท\\nฤชา\\nฤชุ\\nฤณ\\nฤดี\\nฤดียา\\nฤดู\\nฤต\\nฤติยา\\nฤตุ\\nฤทธา\\nฤทธิ์\\nฤทัย\\nฤษภ\\nฤษยา\\nฤษี\\nฤๅ\\nฤๅดี\\nฤๅทัย\\nฤๅษี\\nฤๅสาย\\nลก\\nล่ก\\nลฆุ\\nลง\\nล่ง\\nลงกา\\nล้งเล้ง\\nลด\\nลดา\\nลดาวัลย์\\nลน\\nล้น\\nลบ\\nลบอง\\nลพ\\nลพุช\\nลม\\nล่ม\\nล้ม\\nลมาด\\nลรรลุง\\nลลนา\\nลลิต\\nลวก\\nลวง\\nล่วง\\nล้วง\\nลวณะ\\nลวด\\nล้วน\\nลวนลาม\\nลวนะ\\nล่วม\\nลวะ\\nลวิตร\\nลหุ\\nลหุกาบัติ\\nล่อ\\nล้อ\\nลอก\\nล็อก\\nล็อกเกต\\nลอกแลก\\nลอการิทึม\\nลอง\\nล่อง\\nลองกอง\\nลองจิจูด\\nลองไน\\nลอด\\nลอตเตอรี่\\nลอน\\nล่อน\\nลอบ\\nลอม\\nล้อม\\nลอมชอม\\nลอมพอก\\nลอย\\nล่อย\\nล่อแล่\\nลอว์เรนเซียม\\nลออ\\nละ\\nล่ะ\\nละคร\\nละติจูด\\nละบม\\nละบอง\\nละบือ\\nละเบ็ง\\nละโบม\\nละม่อม\\nละมั่ง\\nละมาน\\nละม้าย\\nละมุ\\nละมุด\\nละมุน\\nละเมอ\\nละเมาะ\\nละเมิด\\nละเมียด\\nละแมะ\\nละโมก\\nละโมบ\\nละไม\\nละลวย\\nละลอก\\nละล้า\\nละล้าละลัง\\nละลาน\\nละลาบละล้วง\\nละลาย\\nละล้าว\\nละล่ำละลัก\\nละลิบ\\nละลุม\\nละเลง\\nละเล้า\\nละเลาะ\\nละเลิง\\nละเลียด\\nละเลียบ\\nละไล้\\nละว้า\\nละวาด\\nละเวง\\nละแวก\\nละโว้\\nละหมาด\\nละห้อย\\nละหาน\\nละหาร\\nละหุ่ง\\nละเหย\\nละเหี่ย\\nละอง\\nละออง\\nละอาย\\nละเอียด\\nละแอน\\nลัก\\nลักขณะ\\nลักขณา\\nลักขะ\\nลักขี\\nลักจั่น\\nลักปิดลักเปิด\\nลักษณ์\\nลักษณนาม\\nลักษณะ\\nลักษณาการ\\nลักษมณ์\\nลักษมาณา\\nลักษมี\\nลักษะ\\nลัคคะ\\nลัคน์\\nลัคนา\\nลัง\\nลั่ง\\nลังกา\\nลังคี\\nลังถึง\\nลังลอง\\nลังเล\\nลังสาด\\nลัชชา\\nลัชชี\\nลัญจ์\\nลัญจกร\\nลัญฉกร\\nลัญฉน์\\nลัฐิ\\nลัฐิกา\\nลัด\\nลัดา\\nลัทธ์\\nลัทธิ\\nลัน\\nลั่น\\nลันเต\\nลันเตา\\nลันไต\\nลั่นทม\\nลันโทม\\nลับ\\nลัพธ์\\nลัพธิ\\nลัภ\\nลัภนะ\\nลัภย์\\nลัมพ์\\nลัย\\nลา\\nล่า\\nล้า\\nลาก\\nลาง\\nล่าง\\nล้าง\\nลางลิง\\nลางสาด\\nลาช\\nลาชะ\\nลาชา\\nลาญ\\nลาด\\nลาดเลา\\nล้าต้า\\nล่าเตียง\\nลาน\\nล่าน\\nล้าน\\nลาบ\\nลาพอน\\nลาภ\\nลาม\\nล่าม\\nลามก\\nลาย\\nล้าย\\nลายสือ\\nลาลา\\nลาว\\nลาวัณย์\\nลาวา\\nลำ\\nล่ำ\\nล้ำ\\nลำเข็ญ\\nลำแข\\nลำเค็ญ\\nลำเจียก\\nลำดวน\\nลำดับ\\nลำเนา\\nลำบอง\\nลำบาก\\nลำปำ\\nลำพวน\\nลำพอง\\nลำพัง\\nลำพู\\nลำเพ็ญ\\nลำเพา\\nลำแพน\\nลำโพง\\nลำไพ่\\nลำภุขัน\\nลำมะลอก\\nลำยอง\\nลำไย\\nลำลอง\\nล่ำลา\\nลำลาบ\\nลำลึก\\nลำเลาะ\\nลำเลิก\\nลำเลียง\\nลำเวียง\\nลำเอียก\\nลำเอียง\\nลิ\\nลิกขา\\nลิกไนต์\\nลิกู\\nลิเก\\nลิขนะ\\nลิขสิทธิ์\\nลิขิต\\nลิง\\nลิงค์\\nลิด\\nลิต\\nลิตมัส\\nลิตร\\nลิเทียม\\nลิ่น\\nลิ้น\\nลินจง\\nลิ้นจี่\\nลินลา\\nลินสีด\\nลิ่นฮื้อ\\nลินิน\\nลิบ\\nลิปดา\\nลิปสติก\\nลิปิ\\nลิฟต์\\nลิเภา\\nลิ่ม\\nลิ้ม\\nลิมป์\\nลิมปนะ\\nลิลิต\\nลิว\\nลิ่ว\\nลิสง\\nลี\\nลี่\\nลี้\\nลีซอ\\nลีบ\\nลีลา\\nลีลาศ\\nลีฬหา\\nลึก\\nลึงค์\\nลืด\\nลื่น\\nลื้น\\nลืบ\\nลืม\\nลือ\\nลื่อ\\nลื้อ\\nลุ\\nลุก\\nลุง\\nลุ้ง\\nลุ่น\\nลุ้น\\nลุพธ์\\nลุ่ม\\nลุมพี\\nลุมพู\\nลุย\\nลุ่ย\\nลุ้ย\\nลู่\\nลูก\\nลูกระมาศ\\nลูกเอ็น\\nลูขะ\\nลูทีเชียม\\nลูบ\\nเลก\\nเล็ก\\nเลข\\nเลขา\\nเลขาธิการ\\nเลขานุการ\\nเล็ง\\nเล้ง\\nเล่งฮื้อ\\nเลเซอร์\\nเลฑฑุ\\nเลณฑุ\\nเลณะ\\nเล็ด\\nเลน\\nเล็น\\nเล่น\\nเลนส์\\nเล็บ\\nเลบง\\nเลปกร\\nเลปน์\\nเลเป\\nเลเพ\\nเล็ม\\nเล่ม\\nเลย\\nเลว\\nเลวง\\nเลวูโลส\\nเลศ\\nเลษฏุ\\nเล่ห์\\nเล่ห์กระเท่ห์\\nเลหลัง\\nเลหะ\\nเลอ\\nเล่อ\\nเลอะ\\nเลอะเทอะ\\nเละ\\nเละเทะ\\nเลา\\nเล่า\\nเล้า\\nเลากัย\\nเล้าโลม\\nเลาะ\\nเลิก\\nเลิ่กลั่ก\\nเลิง\\nเลิ้ง\\nเลินเล่อ\\nเลิศ\\nเลีย\\nเลียง\\nเลี่ยง\\nเลี้ยง\\nเลียงผา\\nเลียงฝ้าย\\nเลียงมัน\\nเลียน\\nเลี่ยน\\nเลียนไฟ\\nเลียบ\\nเลี่ยม\\nเลียว\\nเลี้ยว\\nเลือก\\nเลือง\\nเลื่อง\\nเลือด\\nเลือน\\nเลื่อน\\nเลื่อม\\nเลื่อย\\nเลื้อย\\nเลื่อยล้า\\nแล\\nแล่\\nแล้\\nแลก\\nแล็กเกอร์\\nแล็กโทส\\nแลง\\nแล่ง\\nแล้ง\\nแลน\\nแล่น\\nแลนทานัม\\nแลบ\\nแล้ว\\nและ\\nโล่\\nโล้\\nโลก\\nโลกเชษฐ์\\nโลกธรรม\\nโลกธาตุ\\nโลกนาถ\\nโลกบาล\\nโลกย์\\nโลกัย\\nโลกวัชชะ\\nโลกวิทู\\nโลกัตถจริยา\\nโลกันตร์\\nโลกา\\nโลกาธิบดี\\nโลกาธิปไตย\\nโลกานุวัตร\\nโลกาภิวัตน์\\nโลกามิส\\nโลกายัต\\nโลกาวินาศ\\nโลกิยะ\\nโลกีย์\\nโลกียวัตร\\nโลกียวิสัย\\nโลกียสุข\\nโลกุตระ\\nโลกุตรธรรม\\nโลกุตรภูมิ\\nโลง\\nโล่ง\\nโล้ง\\nโล่งโจ้ง\\nโล่งโต้ง\\nโล้งโต้ง\\nโลจนะ\\nโลณะ\\nโลด\\nโล่ติ๊น\\nโลโต\\nโลท\\nโลน\\nโล้น\\nโลภ\\nโลม\\nโลมเล้า\\nโลมะ\\nโลมา\\nโลลุป\\nโลเล\\nโลโล\\nโลโล้\\nโลหะ\\nโลหกุมภี\\nโลหัช\\nโลหิต\\nไล่\\nไล้\\nไลย\\nไลลา\\nไล่เลี่ย\\nฦๅ\\nฦๅชา\\nฦๅสาย\\nวก\\nวง\\nวงก์\\nวงกต\\nวงศ์\\nวงศกร\\nวงศา\\nวงษ์\\nวจนะ\\nวจี\\nวชิระ\\nวชิรปาณี\\nวชิรหัตถ์\\nวชิราวุธ\\nวฏะ\\nวฏาการ\\nวณิช\\nวณิชชา\\nวณิชย์\\nวณิชยา\\nวณิพก\\nวดี\\nวทนะ\\nวทัญญุตา\\nวทัญญู\\nวธุกา\\nวธู\\nวน\\nวนศาสตร์\\nวนสณฑ์\\nวนสัณฑ์\\nวนอุทยาน\\nวนัส\\nวนัสบดี\\nวนา\\nวนาดร\\nวนาดอน\\nวนานต์\\nวนาลัย\\nวนาลี\\nวนาวาส\\nวนาศรม\\nวนาสณฑ์\\nวนาสัณฑ์\\nวนิดา\\nวนิพก\\nวเนจร\\nวโนทยาน\\nวยัคฆ์\\nวยากรณ์\\nวรดนู\\nวรทาน\\nวรมหาวิหาร\\nวรงค์\\nวรณะ\\nวรรค\\nวรรคย์\\nวรรช\\nวรรชย์\\nวรรณะ\\nวรรณกรรม\\nวรรณคดี\\nวรรณยุกต์\\nวรรณยุต\\nวรรณศิลป์\\nวรรณนา\\nวรรณพฤติ\\nวรรณึก\\nวรรธกะ\\nวรรธนะ\\nวรรษ\\nวรรษา\\nวรวิหาร\\nวรัญญู\\nวรางคณา\\nวรางคนา\\nวราห์\\nวราหะ\\nวรุณ\\nวโรดม\\nวฤก\\nวลัช\\nวลัญช์\\nวลัญชน์\\nวลัย\\nวลาหก\\nวลี\\nวศค\\nวศะ\\nวศิน\\nวสนะ\\nวสภะ\\nวสละ\\nวสวัดดี\\nวสวัตตี\\nวสะ\\nวสันต์\\nวสันตดิลก\\nวสันตฤดู\\nวสันตวิษุวัต\\nวสา\\nวสี\\nวสุ\\nวสุธา\\nวสุนธรา\\nวสุมดี\\nวหะ\\nวอ\\nวอก\\nวอกแวก\\nว่องไว\\nวอด\\nวอน\\nว่อน\\nว็อบ\\nวอมแวม\\nวอลเลย์บอล\\nวอแว\\nวะ\\nวัก\\nวักกะ\\nวัคคีย์\\nวัคคุ\\nวัคซีน\\nวัง\\nวังก์\\nวังชา\\nวังเวง\\nวังศะ\\nวังสะ\\nวัจจะ\\nวัจกุฎี\\nวัจฉละ\\nวัจน์\\nวัช\\nวัชชะ\\nวัชพืช\\nวัชฌ์\\nวัชระ\\nวัชรปาณี\\nวัชรยาน\\nวัชรอาสน์\\nวัชราสน์\\nวัชรินทร์\\nวัชรี\\nวัชเรนทร์\\nวัฏ\\nวัฏฏะ\\nวัฏจักร\\nวัฏทุกข์\\nวัฏสงสาร\\nวัฏกะ\\nวัฏฏิ\\nวัฒกะ\\nวัฒกี\\nวัฒนธรรม\\nวัฒนะ\\nวัฒนา\\nวัณ\\nวัณโรค\\nวัณฏ์\\nวัณณะ\\nวัณนา\\nวัด\\nวัต\\nวัตต์\\nวัตตา\\nวัตถ์\\nวัตถาภรณ์\\nวัตถาลังการ\\nวัตถุ\\nวัตนะ\\nวัตร\\nวัตสดร\\nวัตสะ\\nวัติ\\nวัทน์\\nวัน\\nวันต์\\nวันทนา\\nวันทนาการ\\nวันทนีย์\\nวันทยหัตถ์\\nวันทยาวุธ\\nวันทา\\nวันทิ\\nวับ\\nวับวาบ\\nวับวาม\\nวับแวบ\\nวับแวม\\nวัปปะ\\nวัมมิกะ\\nวัย\\nวัลก์\\nวัลคุ\\nวัลย์\\nวัลลภ\\nวัลลี\\nวัว\\nวัสสะ\\nวัสโสทก\\nวัสดุ\\nวัสตร์\\nวัสน์\\nวัสนะ\\nวัสสานะ\\nวัสสานฤดู\\nวา\\nว่า\\nว้า\\nว้าเหว่\\nวาก\\nว้าก\\nวากยสัมพันธ์\\nวากยะ\\nวาง\\nว่าง\\nว้าง\\nวาจก\\nวาจา\\nวาจาไปยะ\\nวาจาล\\nวาชเปยะ\\nวาณิช\\nวาณิชกะ\\nวาณิชย์\\nวาณี\\nวาด\\nวาต\\nวาตะ\\nวาตภัย\\nวาท\\nวาทศาสตร์\\nวาทศิลป์\\nวาทกะ\\nวาทนะ\\nวาทย์\\nวาทยกร\\nวาทิต\\nวาทิน\\nวาที\\nวาน\\nวานซืน\\nว่าน\\nวานร\\nวานรินทร์\\nวาเนเดียม\\nวาบ\\nวาปี\\nวาม\\nวามน\\nวามนาวตาร\\nวามะ\\nวาย\\nว่าย\\nว้าย\\nวายะ\\nวาโย\\nวายามะ\\nวายุ\\nวายุกูล\\nวาร\\nวาระ\\nวารสาร\\nวารสารศาสตร์\\nวาริ\\nวารี\\nวาริช\\nวารีช\\nวาริท\\nวาริธร\\nวารุณ\\nวารุณี\\nวาล\\nวาลวีชนี\\nวาล์ว\\nวาลิกา\\nวาลุกา\\nวาว\\nว่าว\\nว้าว่อน\\nว้าวุ่น\\nวาสนะ\\nวาสนา\\nวาสพ\\nวาสะ\\nวาสิน\\nวาสี\\nวาสุกรี\\nวาสุกี\\nวาสุเทพ\\nวาหนะ\\nวาหะ\\nวาหินี\\nวาฬ\\nวิกขัมภ์\\nวิกขัมภนะ\\nวิกเขป\\nวิกรม\\nวิกรัย\\nวิกรานต์\\nวิกฤต\\nวิกฤติ\\nวิกล\\nวิกสิต\\nวิกัต\\nวิกัติ\\nวิกัติการก\\nวิกัป\\nวิกัย\\nวิการ\\nวิกาล\\nวิกาลโภชน์\\nวิคหะ\\nวิเคราะห์\\nวิฆเนศ\\nวิฆเนศวร\\nวิฆาต\\nวิง\\nวิ่ง\\nวิ่งเปี้ยว\\nวิงวอน\\nวิจฉิกะ\\nวิจล\\nวิจักขณ์\\nวิจักษ์\\nวิจักษณ์\\nวิจัย\\nวิจาร\\nวิจารณ์\\nวิจารณญาณ\\nวิจิ\\nวิจิกิจฉา\\nวิจิต\\nวิจิตร\\nวิจิน\\nวิจุณ\\nวิจุรณ\\nวิชชา\\nวิชชุ\\nวิชชุดา\\nวิชชุตา\\nวิชชุลดา\\nวิชญะ\\nวิชน\\nวิชนี\\nวิชย\\nวิชัย\\nวิชา\\nวิชานนะ\\nวิชิต\\nวิเชียร\\nวิญญัตติ\\nวิญญาณ\\nวิญญาณกทรัพย์\\nวิญญู\\nวิฑูรย์\\nวิด\\nวิตก\\nวิตถาร\\nวิตามิน\\nวิถี\\nวิทธะ\\nวิทยฐานะ\\nวิทยา\\nวิทยาคม\\nวิทยาคาร\\nวิทยาลัย\\nวิทยุ\\nวิทยุต\\nวิทวัส\\nวิทัตถิ\\nวิทัศน์\\nวิทารณ์\\nวิทิต\\nวิทู\\nวิทูร\\nวิเทศ\\nวิเทโศบาย\\nวิธ\\nวิธวา\\nวิธาน\\nวิธี\\nวิธุระ\\nวิธู\\nวิธูปนะ\\nวิ่น\\nวินตกะ\\nวินัย\\nวินาที\\nวินายก\\nวินาศ\\nวินิจ\\nวินิจฉัย\\nวินิต\\nวินิบาต\\nวินิปาติก\\nวิเนต\\nวิบัติ\\nวิบาก\\nวิบุล\\nวิบุลย์\\nวิบูล\\nวิบูลย์\\nวิปการ\\nวิปฏิสาร\\nวิปโยค\\nวิประโยค\\nวิปริต\\nวิปลาส\\nวิปวาส\\nวิปักษ์\\nวิปัสสก\\nวิปัสสนา\\nวิปัสสนายานิก\\nวิพากษ์\\nวิพิธทัศนา\\nวิพุธ\\nวิภว\\nวิภวตัณหา\\nวิภังค์\\nวิภัช\\nวิภัตติ\\nวิภา\\nวิภาค\\nวิภาช\\nวิภาดา\\nวิภาวี\\nวิภาษ\\nวิภาส\\nวิภู\\nวิภูษณะ\\nวิภูษา\\nวิภูษิต\\nวิมน\\nวิมล\\nวิมลัก\\nวิมังสา\\nวิมัติ\\nวิมาน\\nวิมุข\\nวิมุต\\nวิมุตติ\\nวิเมลือง\\nวิโมกข์\\nวิโยค\\nวิระ\\nวิรงรอง\\nวิรังรอง\\nวิรัช\\nวิรัต\\nวิรัติ\\nวิราคะ\\nวิราม\\nวิริยภาพ\\nวิริยะ\\nวิรุธ\\nวิรุฬห์\\nวิรุฬหก\\nวิรูป\\nวิรูปักษ์\\nวิเรนทร์\\nวิโรจ\\nวิโรจน์\\nวิโรฒ\\nวิโรธ\\nวิลันดา\\nวิลัย\\nวิลาด\\nวิลาศ\\nวิลาป\\nวิลาวัณย์\\nวิลาส\\nวิลาสินี\\nวิลิปดา\\nวิลิศมาหรา\\nวิเลป\\nวิเลปนะ\\nวิโลกนะ\\nวิโลม\\nวิไล\\nวิไลวรรณ\\nวิวรณ์\\nวิวรรธน์\\nวิวัฏ\\nวิวัฒน์\\nวิวัฒนาการ\\nวิวัน\\nวิวาท\\nวิวาห์\\nวิวาหมงคล\\nวิวาหะ\\nวิวิต\\nวิวิธ\\nวิเวก\\nวิศรุต\\nวิศว\\nวิศวกร\\nวิศวกรรม\\nวิศวกรรมศาสตร์\\nวิศัลย์\\nวิศาขบูชา\\nวิศาขา\\nวิศาล\\nวิศิษฏ์\\nวิศุทธ์\\nวิศุทธิ์\\nวิเศษ\\nวิเศษณ์\\nวิษณุ\\nวิษณุกรรม\\nวิษธร\\nวิษัย\\nวิษาณ\\nวิษุวัต\\nวิสกี้\\nวิสรรชนีย์\\nวิสฤต\\nวิสสุกรรม\\nวิสัชนา\\nวิสัญญี\\nวิสัย\\nวิสัยทัศน์\\nวิสาขบูชา\\nวิสาขะ\\nวิสาขา\\nวิสามัญ\\nวิสามานยนาม\\nวิสาร\\nวิสารทะ\\nวิสาล\\nวิสาสะ\\nวิสาหกิจ\\nวิสิฐ\\nวิสุงคามสีมา\\nวิสุทธ์\\nวิสุทธิ์\\nวิสูตร\\nวิเสท\\nวิหค\\nวิหลั่น\\nวิหาร\\nวิหิงสา\\nวิเหสา\\nวิฬาร\\nวิฬาร์\\nวี\\nวีจิ\\nวีชนี\\nวีณา\\nวี้ด\\nวีรกรรม\\nวีรชน\\nวีรบุรุษ\\nวีรสตรี\\nวี่วัน\\nวี่แวว\\nวีสะ\\nวุ้ง\\nวุฐิ\\nวุฒ\\nวุฒิ\\nวุด\\nวุ่น\\nวุ้น\\nวุบ\\nวุ้ย\\nวุลแฟรม\\nวู้\\nวูดวาด\\nวูบ\\nวู่วาม\\nเว้\\nเวค\\nเวคิน\\nเวคี\\nเวจ\\nเวช\\nเวชยันต์\\nเวฐน์\\nเวณิ\\nเวณิก\\nเวณุ\\nเวตน์\\nเวตร\\nเวตาล\\nเวท\\nเวทคู\\nเวทนา\\nเวทย์\\nเวทัลละ\\nเวทางค์\\nเวทางคศาสตร์\\nเวทานต์\\nเวทานตะ\\nเวทิ\\nเวที\\nเวธะ\\nเวน\\nเว้น\\nเวนไตย\\nเวไนย\\nเวมัต\\nเว้ย\\nเวยยากรณะ\\nเวร\\nเวรมณี\\nเวรี\\nเวโรจน์\\nเวลา\\nเวเลนซี\\nเวศม์\\nเวศย์\\nเวศยา\\nเวสน์\\nเวสภู\\nเวสม์\\nเวสวัณ\\nเวสสะ\\nเวสสันดร\\nเวสสุกรรม\\nเวสสุวัณ\\nเวสารัช\\nเวสิยา\\nเวหน\\nเวหะ\\nเวหา\\nเวหาส\\nเวฬุ\\nเวฬุริยะ\\nเว่อ\\nเว้า\\nเวิก\\nเวิ้ง\\nเวี่ย\\nเวียง\\nเวียด\\nเวียดนาม\\nเวียน\\nเวียร\\nเวี่ยว\\nแว้\\nแวง\\nแว้ง\\nแวด\\nแว้ด\\nแวน\\nแว่น\\nแวนดา\\nแวบ\\nแว็บ\\nแวม\\nแว็ม\\nแวว\\nแว่ว\\nแวะ\\nโว\\nโว่\\nโวการ\\nโว่ง\\nโวทาน\\nโวย\\nโว้ย\\nโว้เว้\\nโวหาร\\nไว\\nไว้\\nไวกูณฐ์\\nไวฑูรย์\\nไวทย์\\nไวน์\\nไวพจน์\\nไวยากรณ์\\nไวยาวัจกร\\nไวยาวัจมัย\\nไวรัส\\nไววรรณ\\nไวษณพ\\nไวโอลิน\\nศก\\nศกุน\\nศกุนต์\\nศกุนิ\\nศกุนี\\nศจี\\nศตะ\\nศตภิษัช\\nศตวรรษ\\nศตพรรษ\\nศตกะ\\nศนิ\\nศพ\\nศมนะ\\nศมะ\\nศยาม\\nศยามล\\nศร\\nศรายุธ\\nศราวรณ์\\nศรรกรา\\nศรวณะ\\nศรวณีย์\\nศรวิษฐา\\nศรัณย์\\nศรัณยู\\nศรัท\\nศรัทธา\\nศรัย\\nศราทธ์\\nศราทธพรต\\nศราพก\\nศราวก\\nศราวณะ\\nศรี\\nศรีตรัง\\nศรุติ\\nศฤคาล\\nศฤงค์\\nศฤงคาร\\nศฤงคาริน\\nศฤงคารี\\nศลิษฏ์\\nศลิษา\\nศวะ\\nศวัส\\nศวา\\nศวาน\\nศศะ\\nศศธร\\nศศพินทุ์\\nศศลักษณ์\\nศศิ\\nศศิน\\nศศี\\nศศิขัณฑ์\\nศศิธร\\nศศิมณฑล\\nศศิวิมล\\nศอ\\nศอก\\nศักดา\\nศักดิ\\nศักดิ์\\nศักดินา\\nศักติ\\nศักย\\nศักยภาพ\\nศักย์\\nศักยะ\\nศักร\\nศักรินทร์\\nศักเรนทร์\\nศักราช\\nศังกร\\nศัตรู\\nศันสนะ\\nศันสนีย์\\nศัพท์\\nศัยยา\\nศัล\\nศัลย์\\nศัลยกรรม\\nศัลยแพทย์\\nศัลยศาสตร์\\nศัสดร\\nศัสตร\\nศัสตรศาสตร์\\nศัสตรา\\nศัสตราวุธ\\nศากตะ\\nศากย\\nศากยะ\\nศากยพุทธ\\nศากยมุนี\\nศาฎก\\nศาณ\\nศานต์\\nศานติ\\nศาป\\nศารท\\nศารทูล\\nศาริกา\\nศาล\\nศาลา\\nศาศวัต\\nศาสดา\\nศาสตร์\\nศาสตรา\\nศาสตราจารย์\\nศาสนา\\nศาสนกิจ\\nศาสนจักร\\nศาสนธรรม\\nศาสนบุคคล\\nศาสนพิธี\\nศาสนวัตถุ\\nศาสนศาสตร์\\nศาสนสถาน\\nศาสนสมบัติ\\nศาสนิกชน\\nศาสนีย์\\nศาสนูปถัมภก\\nศาสน์\\nศิกษก\\nศิการ\\nศิขร\\nศิขริน\\nศิขรี\\nศิขัณฑ์\\nศิคาล\\nศิงขร\\nศิงขริน\\nศิตะ\\nศิถี\\nศิพิระ\\nศิระ\\nศิรประภา\\nศิราภรณ์\\nศิโรรัตน์\\nศิโรเวฐน์\\nศิรา\\nศิรามพุช\\nศิโรราบ\\nศิลป\\nศิลป์\\nศิลปะ\\nศิลปกร\\nศิลปกรรม\\nศิลปกิจ\\nศิลปวัตถุ\\nศิลปวิทยา\\nศิลปศาสตร์\\nศิลปศึกษา\\nศิลปหัตถกรรม\\nศิลปิน\\nศิลปี\\nศิลา\\nศิวะ\\nศิวโมกข์\\nศิวลึงค์\\nศิวเวท\\nศิวาลัย\\nศิศีระ\\nศิษฎิ\\nศิษฏ์\\nศิษย์\\nศิษยานุศิษย์\\nศีขร\\nศีต\\nศีตกาล\\nศีรษะ\\nศีล\\nศึก\\nศึกษา\\nศึกษาธิการ\\nศึกษานิเทศก์\\nศุกร์\\nศุกรวรรณ\\nศุกรวาร\\nศุกระ\\nศุกล\\nศุกลปักษ์\\nศุจิ\\nศุทธะ\\nศุทธิ\\nศุนะ\\nศุนิ\\nศุภกร\\nศุภเคราะห์\\nศุภนิมิต\\nศุภมัสดุ\\nศุภมาตรา\\nศุภมาส\\nศุภอักษร\\nศุภางค์\\nศูกร\\nศุลกากร\\nศุลการักษ์\\nศุลี\\nศุษิร\\nศูทร\\nศูนย์\\nศูนยวาท\\nศูละ\\nศูลิน\\nเศรณี\\nเศรษฐ\\nเศรษฐ์\\nเศรษฐกิจ\\nเศรษฐศาสตร์\\nเศรษฐี\\nเศร้า\\nเศลษ\\nเศวต\\nเศวตร\\nเศวตัมพร\\nเศษ\\nเศาจ\\nเศาร์\\nเศารยะ\\nเศิก\\nเศียร\\nโศก\\nโศกา\\nโศกาดูร\\nโศกาลัย\\nโศกี\\nโศจิ\\nโศธนะ\\nโศภน\\nโศภะ\\nโศภา\\nโศภิต\\nโศภิน\\nโศภิษฐ์\\nโศภี\\nโศรดา\\nโศรตร\\nโศลก\\nไศล\\nไศวะ\\nษมา\\nษัฏ\\nษัฑ\\nษัณ\\nษัษ\\nษัษฐะ\\nษัษฐี\\nโษฑศัน\\nสก\\nสกวาที\\nสกฏะ\\nสกทาคามิผล\\nสกิทาคามิผล\\nสกทาคามิมรรค\\nสกิทาคามิมรรค\\nสกทาคามี\\nสกิทาคามี\\nสกนธ์\\nสกปรก\\nสกรณีย์\\nสกรรจ์\\nสกรรมกริยา\\nสกล\\nสกลมหาสังฆปริณายก\\nสกัด\\nสกา\\nสกาว\\nสกี\\nสกุณ\\nสกุณา\\nสกุณี\\nสกุน\\nสกุนต์\\nสกุล\\nสเกต\\nสแกนเดียม\\nสขะ\\nสง\\nส่ง\\nสงกร\\nสงกรานต์\\nสงกา\\nสงค์\\nสงคร\\nสงคราม\\nสงเคราะห์\\nสงฆ์\\nสงบ\\nสงวน\\nส่งสการ\\nสงสัย\\nสงสาร\\nสงสารวัฏ\\nสงัด\\nสง่า\\nสฐะ\\nสณฑ์\\nสด\\nสดมภ์\\nสดับ\\nสดับปกรณ์\\nสดำ\\nสดุดี\\nสตะ\\nสตน\\nสตภิสชะ\\nสตรอนเชียม\\nสตริกนิน\\nสตรี\\nสตัฟฟ์\\nสตัมภ์\\nสตางค์\\nสติ\\nสติปัฏฐาน\\nสตี\\nสตู\\nสตูป\\nสเต๊ก\\nสถบดี\\nสถล\\nสถวีระ\\nสถาน\\nสถานะ\\nสถานี\\nสถาบัน\\nสถาปนา\\nสถาปนิก\\nสถาปัตยกรรม\\nสถาปัตยกรรมศาสตร์\\nสถาปัตยเรขา\\nสถาปัตยเวท\\nสถาพร\\nสถาวร\\nสถิต\\nสถิตยศาสตร์\\nสถิติ\\nสถิร\\nสถีรวาท\\nสถุล\\nสถูป\\nสทิง\\nสทึง\\nสทุม\\nสธนะ\\nสาธุสะ\\nสน\\nส้น\\nสนทนา\\nสนทรรศ\\nสนทรรศน์\\nสนเทศ\\nสนเท่ห์\\nสนธยา\\nสนธิ\\nสนน\\nสนม\\nสนวน\\nสนอง\\nสนอบ\\nสนอม\\nสนะ\\nสนัด\\nสนั่น\\nสนับ\\nสนับทึบ\\nสนับสนุน\\nสนาน\\nสนาม\\nสนายุ\\nสนิกะ\\nสนิท\\nสนิธ\\nสนิม\\nสนุก\\nสนุกเกอร์\\nสนุข\\nสนุต\\nสนุ่น\\nสบ\\nสบง\\nสบถ\\nสบัน\\nสบาย\\nสบู่\\nสไบ\\nสปริง\\nสปอร์\\nสปาเกตตี\\nสเปกตรัม\\nสเปกโทรสโกป\\nสไปริลลัม\\nสพาบ\\nสภา\\nสภาพ\\nสภาวการณ์\\nสภาวะ\\nสม\\nสมการ\\nสมจารี\\nสมดุล\\nสมมูล\\nส้ม\\nสมญา\\nสมณะ\\nสมณบริขาร\\nสมณศักดิ์\\nสมณสารูป\\nสมเด็จ\\nสมถะ\\nสมถยานิก\\nสมถวิปัสสนา\\nสมนาคุณ\\nสมบัติ\\nสมบุกสมบัน\\nสมบูรณ์\\nสมบูรณาญาสิทธิราชย์\\nสมประดี\\nสมปฤดี\\nสมปฤๅดี\\nส้มป่อย\\nสมปัก\\nสมผุส\\nสมพง\\nสมพงศ์\\nสมพล\\nสมพัตสร\\nสมพาส\\nสมเพช\\nสมโพธน์\\nสมโพธิ\\nสมภพ\\nสมภาร\\nสมโภค\\nสมโภช\\nสมมต\\nสมมติ\\nสมมุติ\\nสมมาตร\\nส้มมือ\\nสมโมท\\nสมโยค\\nสมร\\nสมรด\\nสมรรถ\\nสมรรถนะ\\nสมรรถภาพ\\nสมรส\\nสมฤดี\\nสมฤติ\\nสมวายะ\\nสมเสร็จ\\nสมอ\\nสมอง\\nสมะ\\nสมัคร\\nสมังคี\\nสมัช\\nสมัชชา\\nสมัญญา\\nสมัต\\nสมัน\\nสมันต์\\nสมัย\\nสมา\\nสมาคม\\nสมาจาร\\nสมาชิก\\nสมาทาน\\nสมาธิ\\nสมาน\\nสมานฉันท์\\nสมาบัติ\\nสมาพันธรัฐ\\nสมาส\\nสม่ำเสมอ\\nสมิง\\nสมิต\\nสมิติ\\nสมิทธ์\\nสมิทธิ\\nสมี\\nสมุก\\nสมุจจัย\\nสมุจเฉท\\nสมุฏฐาน\\nสมุด\\nสมุทร\\nสมุทรโคดม\\nสมุทัย\\nสมุน\\nสมุนไพร\\nสมุลแว้ง\\nสมุห\\nสมุห์\\nสมุหกลาโหม\\nสมุหเทศาภิบาล\\nสมุหนาม\\nสมุหนายก\\nสโมธาน\\nสโมสร\\nสยด\\nสยนะ\\nสยบ\\nสยมพร\\nสยมภู\\nสยอง\\nสยอน\\nสยัมวรา\\nสยาม\\nสยามานุสติ\\nสยามินทร์\\nสยาย\\nสยิว\\nสยิ้ว\\nสยุมพร\\nสยุมภู\\nสร\\nสรง\\nสร่ง\\nสรณะ\\nสรณคมน์\\nสรณาคมน์\\nสรณตรัย\\nสรตะ\\nสรทะ\\nสรนุก\\nสรเนาะ\\nสรไน\\nสรเพชญ\\nสรภะ\\nสรภัญญะ\\nสรภู\\nสรม\\nสรร\\nสรรค์\\nสรรพ\\nสรรพคุณ\\nสรรพนาม\\nสรรพสามิต\\nสรรพัชญ\\nสรรพากร\\nสรรพางค์\\nสรรเพชญ\\nสรรเพชุดา\\nสรรเสริญ\\nสรลอน\\nสรเลข\\nสรวง\\nสรวม\\nสรวล\\nสรเสริญ\\nสร้อย\\nสระ\\nสระกอ\\nสระท้อน\\nสระพรั่ง\\nสระอาด\\nสรั่ง\\nสรัสวดี\\nสร่าง\\nสร้าง\\nสราญ\\nสรี้\\nสรีระ\\nสรีรกิจ\\nสรีรธาตุ\\nสรีรวิทยา\\nสรีรศาสตร์\\nสรีรังคาร\\nสรีรางคาร\\nสรุป\\nสโรช\\nสโรชะ\\nสฤก\\nสฤต\\nสฤษฎิ\\nสฤษฎี\\nสฤษฏ์\\nสฤษดิ์\\nสลด\\nสลบ\\nสลวน\\nสลวย\\nสลอด\\nสลอน\\nสลอย\\nสละ\\nสลัก\\nสลัด\\nสลัดได\\nสลับ\\nสลัว\\nสลา\\nสลาก\\nสลาง\\nสล้าง\\nสลาด\\nสลาตัน\\nสลาบ\\nสลาย\\nสลิด\\nสลิล\\nสลึก\\nสลึง\\nสลุต\\nสลุบ\\nสลุมพร\\nสแลง\\nสวการย์\\nสวภาพ\\nสวราชย์\\nสวก\\nส้วง\\nสวด\\nสวน\\nสวนะ\\nสวนาการ\\nส่วน\\nสวนิต\\nสวบ\\nสวม\\nส้วม\\nสวย\\nส่วย\\nส้วย\\nสวยม\\nสวรรค\\nสวรรค์\\nสวรรคต\\nสวรรคาลัย\\nสวรรยา\\nสวระ\\nสวะ\\nสวัสดิ\\nสวัสดิ์\\nสวัสดิการ\\nสวัสดิภาพ\\nสวัสดิมงคล\\nสวัสดี\\nสวัสติ\\nสวาตี\\nสวัสติกะ\\nสวา\\nสวาปาม\\nสวาคตะ\\nสวาง\\nสว่าง\\nสวาด\\nสวาดิ\\nสวาท\\nสว่าน\\nสว้าน\\nสวาบ\\nสวามิ\\nสวามี\\nสวามินี\\nสวาย\\nสวาสดิ์\\nสวาหะ\\nสวิง\\nสวิญญาณกทรัพย์\\nสวิตช์\\nสสาร\\nสสุระ\\nสสุรี\\nสหกรณ์\\nสหการ\\nสหจร\\nสหชาต\\nสหชาติ\\nสหธรรม\\nสหธรรมิก\\nสหประชาชาติ\\nสหพันธ์\\nสหพันธรัฐ\\nสหภาพ\\nสหศึกษา\\nสหัช\\nสหัมบดี\\nสหัส\\nสหัสสะ\\nสหัสธารา\\nสหัสนัยน์\\nสหัสเนตร\\nสหัสรังสี\\nสหัสา\\nสหาย\\nสอ\\nส่อ\\nสอง\\nส่อง\\nส้อง\\nสอด\\nสอน\\nส่อน\\nสอบ\\nสอพลอ\\nส้อม\\nสอย\\nสะ\\nสะกด\\nสะกอ\\nสะกาง\\nสะการะ\\nสะกิด\\nสะกิดสะเกา\\nสะเก็ด\\nสะแก\\nสะคร้อ\\nสะคราญ\\nสะค้าน\\nสะเงาะสะแงะ\\nสะดม\\nสะดวก\\nสะดิ้ง\\nสะดึง\\nสะดือ\\nสะดุ้ง\\nสะดุด\\nสะเด็ด\\nสะเดา\\nสะเดาะ\\nสะตอ\\nสะตาหมัน\\nสะตึ\\nสะตือ\\nสะตุ\\nสะเต๊ะ\\nสะโตก\\nสะทก\\nสะท้อน\\nสะท้าน\\nสะทึก\\nสะเทิน\\nสะเทิ้น\\nสะเทือน\\nสะเทื้อน\\nสะบะ\\nสะบัก\\nสะบักสะบอม\\nสะบัด\\nสะบัดสะบิ้ง\\nสะบั้น\\nสะบันงา\\nสะบ้า\\nสะบู\\nสะแบง\\nสะเปะสะปะ\\nสะพรั่ง\\nสะพรึงกลัว\\nสะพรึบ\\nสะพรึ่บ\\nสะพัก\\nสะพัง\\nสะพัด\\nสะพั้น\\nสะพาน\\nสะพาย\\nสะเพร่า\\nสะโพก\\nสะเภา\\nสะใภ้\\nสะโมง\\nสะระตะ\\nสะระแหน่\\nสะลาง\\nสะลาบ\\nสะลึมสะลือ\\nสะวี้ดสะว้าด\\nสะสม\\nสะสวย\\nสะสาง\\nสะเหล่อ\\nสะอาง\\nสะอาด\\nสะอ้าน\\nสะอิ้ง\\nสะอิดสะเอียน\\nสะอึก\\nสะอื้น\\nสะเอ้ง\\nสะเอว\\nสะเออะ\\nสะโอดสะอง\\nสะไอ\\nสัก\\nสักกะ\\nสักยะ\\nสักกัจจะ\\nสักกายทิฐิ\\nสักการ\\nสักการะ\\nสักขี\\nสักวา\\nสักหลาด\\nสัค\\nสัคคะ\\nสั่ง\\nสังกร\\nสังกรณี\\nสังกรประโยค\\nสังกะตัง\\nสังกะวัง\\nสังกะวาด\\nสังกะสี\\nสังกัด\\nสังกัปปะ\\nสังกา\\nสังการ\\nสังกาศ\\nสังกิเลส\\nสังเกต\\nสังข์\\nสังขกร\\nสังขตธรรม\\nสังขตะ\\nสังขยา\\nสังขลิก\\nสังขลิกา\\nสังขาร\\nสังขารา\\nสังเขป\\nสังค์\\nสังคญาติ\\nสังคม\\nสังคหะ\\nสังคัง\\nสังคายนา\\nสังคายนาย\\nสังคีต\\nสังคีติ\\nสังเค็ด\\nสังเคราะห์\\nสังฆกรรม\\nสังฆการี\\nสังฆเถระ\\nสังฆทาน\\nสังฆนายก\\nสังฆปาโมกข์\\nสังฆภัต\\nสังฆเภท\\nสังฆมณฑล\\nสังฆมนตรี\\nสังฆราช\\nสังฆสภา\\nสังฆาณัติ\\nสังฆาฏิ\\nสังฆาทิเสส\\nสังฆาธิการ\\nสังฆานุสติ\\nสังฆาวาส\\nสังยุตนิกาย\\nสังโยค\\nสังโยชน์\\nสังวร\\nสังวัจฉระ\\nสังวัธยาย\\nสังวาล\\nสังวาส\\nสังเวคะ\\nสังเวช\\nสังเวชนียสถาน\\nสังเวย\\nสังเวียน\\nสังสกฤต\\nสังสการ\\nสังสนทนา\\nสั่งสนทนา\\nสังสรรค์\\nสังสารวัฏ\\nสังสิทธิ\\nสังสุทธ์\\nสังสุทธิ\\nสังหร\\nสังหรณ์\\nสังหาร\\nสังหาริมทรัพย์\\nสังหาริมะ\\nสังหิต\\nสัจ\\nสัจกิริยา\\nสัจจะ\\nสัจญาณ\\nสัจธรรม\\nสัจนิยม\\nสัจพจน์\\nสัชฌะ\\nสัชฌุ\\nสัญจร\\nสัญเจตนา\\nสัญชาตญาณ\\nสัญชาติ\\nสัญฌา\\nสัญญา\\nสัญญาณ\\nสัญญี\\nสัญโญชน์\\nสัญนิยม\\nสัญประกาศ\\nสัญลักษณ์\\nสัฐิ\\nสัณฐาน\\nสัณฐิติ\\nสัณฑ์\\nสัณห์\\nสัด\\nสัดจอง\\nสัต\\nสัตตะ\\nสัตตาหกรณียะ\\nสัตตาหกาลิก\\nสัตมวาร\\nสัตสดก\\nสัตตบงกช\\nสัตตบรรณ\\nสัตตบุษย์\\nสัตตู\\nสัตถันดร\\nสัตถา\\nสัตถิ\\nสัตถุ\\nสัตถุศาสนา\\nสัตบรรณ\\nสัตย์\\nสัตยพรต\\nสัตยวาที\\nสัตยาเคราะห์\\nสัตยาธิษฐาน\\nสัตยาบัน\\nสัตว์\\nสัตวชาติ\\nสัตวบาล\\nสัตวแพทย์\\nสัตววิทยา\\nสัตวา\\nสัทธรรม\\nสัทธา\\nสัทธาจริต\\nสัทธาธิกะ\\nสัทธินทรีย์\\nสัทธิงวิหาริก\\nสัทธิวิหาริก\\nสัทวิทยา\\nสัทศาสตร์\\nสัทอักษร\\nสัน\\nสั่น\\nสั้น\\nสันดาน\\nสันดาป\\nสันโดษ\\nสันต์\\nสันตติ\\nสันตะปาปา\\nสันตะวา\\nสันติ\\nสันตุฏฐี\\nสันถวไมตรี\\nสันถวะ\\nสันถัต\\nสันถาร\\nสันทนะ\\nสันทะ\\nสันทัด\\nสันทัสนะ\\nสันทาน\\nสันทิฐิก\\nสันทิส\\nสันเทหะ\\nสันธาน\\nสันนิธิ\\nสันนิบาต\\nสันนิวาส\\nสันนิษฐาน\\nสันสกฤต\\nสับ\\nสับปลับ\\nสับปลี้\\nสับปะรด\\nสัปคับ\\nสัปดาห์\\nสัปดาหะ\\nสัปดน\\nสัปตศก\\nสัปทน\\nสัปปะ\\nสัปปิ\\nสัปปุริส\\nสัปปุรุษ\\nสัประยุทธ์\\nสัปหงก\\nสัปเหร่อ\\nสัพ\\nสัพพะ\\nสัพพัญญู\\nสัพเพเหระ\\nสัพยอก\\nสัมบูรณ์\\nสัมปชัญญะ\\nสัมปทา\\nสัมปทาน\\nสัมปยุต\\nสัมปโยค\\nสัมประสิทธิ์\\nสัมประหาร\\nสัมปรายภพ\\nสัมปรายิกภพ\\nสัมปัตติ\\nสัมผัปลาป\\nสัมผัปลาปะ\\nสัมผัส\\nสัมพล\\nสัมพหุลา\\nสัมพัจฉรฉินท์\\nสัมพัตสร\\nสัมพัทธ์\\nสัมพันธ์\\nสัมพันธน์\\nสัมพันธภาพ\\nสัมพันธมิตร\\nสัมพันธไมตรี\\nสัมพาหะ\\nสัมพุทธ\\nสัมพุทธะ\\nสัมโพธิ\\nสัมภวะ\\nสัมภเวสี\\nสัมภัต\\nสัมภัตตะ\\nสัมภาระ\\nสัมภาษณ์\\nสัมโภคกาย\\nสัมมนา\\nสัมมัปธาน\\nสัมมา\\nสัมโมทนียกถา\\nสัมฤทธิ\\nสัมฤทธิ์\\nสัมฤทธิศก\\nสัยน์\\nสัลเลข\\nสัสดี\\nสัสตทิฐิ\\nสัสสะ\\nสัสสุ\\nสัสสู\\nสา\\nส่า\\nสาก\\nสากรรจ์\\nสากล\\nสากัจฉา\\nสากัลย์\\nสากิยะ\\nสาเก\\nสาขา\\nสาคร\\nสาคเรศ\\nสาคู\\nสาง\\nส้าง\\nสาชล\\nสาฎก\\nสาฏิก\\nสาณี\\nสาด\\nสาไถย\\nสาทร\\nสาทิส\\nสาทุ\\nสาโท\\nสาธก\\nสาธยะ\\nสาธยาย\\nสาธารณะ\\nสาธารณชน\\nสาธารณประโยชน์\\nสาธารณภัย\\nสาธารณรัฐ\\nสาธารณสถาน\\nสาธารณสมบัติ\\nสาธารณสุข\\nสาธารณูปการ\\nสาธารณูปโภค\\nสาธารณ์\\nสาธิต\\nสาธุ\\nสาน\\nส่าน\\nสานุ\\nสานู\\nสานุศิษย์\\nสาบ\\nสาบสูญ\\nสาบาน\\nสาป\\nสาปไตย\\nสาม\\nสามชุก\\nสามเณร\\nสามเณรี\\nสามนต์\\nสามนตราช\\nสามยทรัพย์\\nสามล\\nสามหาว\\nสามะ\\nสามัคคี\\nสามัญ\\nสามัตถิยะ\\nสามานย์\\nสามานยนาม\\nสามารถ\\nสามิต\\nสามินี\\nสามิภักดิ์\\nสามี\\nสามีจิกรรม\\nสาย\\nส่าย\\nส้าย\\nสายชู\\nสายัณห์\\nสายาห์\\nสาร\\nสารคดี\\nสารธรรม\\nสารนิเทศ\\nสารบบ\\nสารบรรณ\\nสารบัญ\\nสารบาญ\\nสารบาญชี\\nสารประโยชน์\\nสารสนเทศ\\nสารทุกข์\\nสารถี\\nสารท\\nสารพัด\\nสารพัน\\nสารพางค์\\nสารภาพ\\nสารภี\\nสารวัตร\\nสาระ\\nสาระแน\\nสาระพา\\nสาระยำ\\nสาระวารี\\nสาระสะมา\\nสารัตถประโยชน์\\nสารัตถศึกษา\\nสารัตถะ\\nสารัทธ์\\nสารัมภ์\\nสาราณียกร\\nสาราณียธรรม\\nสาราณียะ\\nสารานุกรม\\nสารีริกธาตุ\\nสารูป\\nสาโรช\\nสาละ\\nสาละวน\\nสาลิ\\nสาลิกา\\nสาลินี\\nสาลี\\nสาลี่\\nสาลู\\nสาโลหิต\\nสาว\\nสาวก\\nสาวิกา\\nสาวิตร\\nสาวิตรี\\nสาสน\\nสาสน์\\nสาส์น\\nสาสนา\\nสาสม\\nสาหร่าย\\nสาหรี\\nส่าหรี\\nสาหัส\\nสาเหตุ\\nสาแหรก\\nสำ\\nสำส่อน\\nส่ำ\\nสำคัญ\\nสำซ่าง\\nสำแดง\\nสำทับ\\nสำนวน\\nสำนอง\\nสำนัก\\nสำนาน\\nสำนึก\\nสำนึง\\nสำเนา\\nสำเนียง\\nสำบัด\\nสำปะลอ\\nสำปะหลัง\\nสำปั้น\\nสำปันนี\\nสำเภา\\nสำมะงา\\nสำมะโน\\nสำมะลอ\\nสำมะเลเทเมา\\nสำมะหา\\nสำรด\\nสำรวจ\\nสำรวม\\nสำรวย\\nสำรวล\\nสำรอก\\nสำรอง\\nสำรับ\\nสำราก\\nสำราญ\\nสำริด\\nสำเร็จ\\nสำเรา\\nสำเริง\\nสำโรง\\nสำลัก\\nสำลาน\\nสำลี\\nสำแลง\\nสำหรวด\\nสำหรับ\\nสำหา\\nสำเหนียก\\nสำเหร่\\nสำออย\\nสำอาง\\nสิ\\nสิกข์\\nสิข\\nสิกขมานา\\nสิกขา\\nสิขร\\nสิขรี\\nสิขเรศ\\nสิขา\\nสิขานล\\nสิขี\\nสิคาล\\nสิง\\nสิ่ง\\nสิงขร\\nสิงค์\\nสิงคลิ้ง\\nสิงคลี\\nสิงคาร\\nสิงคาล\\nสิงคี\\nสิงโต\\nสิงห์\\nสิงหนาท\\nสิงหบัญชร\\nสิงหรา\\nสิงหราช\\nสิงหาคม\\nสิงหาสน์\\nสิงหล\\nสิญจน์\\nสิตะ\\nสิตางศุ์\\nสิถิล\\nสิทธ์\\nสิทธัตถะ\\nสิทธา\\nสิทธาจารย์\\nสิทธารถ\\nสิทธิ\\nสิทธิ์\\nสิทธิการิยะ\\nสิธยะ\\nสิน\\nสิ้น\\nสินเทา\\nสินธพ\\nสินธุ\\nสินธุ์\\nสินธุระ\\nสินธู\\nสินเธาว์\\nสินาด\\nสินิทธ์\\nสินี\\nสิเนรุ\\nสิเนหก\\nสิเนหะ\\nสิเนหา\\nสิเน่หา\\nสิบ\\nสิปปะ\\nสิมพลี\\nสิระ\\nสิโรดม\\nสิโรตม์\\nสิริ\\nสิรี\\nสิลา\\nสิว\\nสิ่ว\\nสิวะ\\nสิวาลัย\\nสิวิกา\\nสี\\nสี่\\nสี้\\nสีกา\\nสีกุน\\nสีข้าง\\nสีด\\nสีดอ\\nสีดา\\nสีตลรัศมี\\nสีตโลทก\\nสีโตทก\\nสีทันดร\\nสีมันต์\\nสีมา\\nสีละมัน\\nสีวิกา\\nสีสอ\\nสีสะ\\nสีสา\\nสีสุก\\nสีเสียด\\nสีห์\\nสีหนาท\\nสีหบัญชร\\nสีหราช\\nสีหไสยา\\nสีหไสยาสน์\\nสีหะ\\nสึก\\nสึง\\nสืบ\\nสื่อ\\nสุ\\nสุก\\nสุกข์\\nสุกร\\nสุกรม\\nสุกำศพ\\nสุกียากี้\\nสุข\\nสุขา\\nสุขาภิบาล\\nสุขารมณ์\\nสุขาวดี\\nสุขิน\\nสุขี\\nสุขุม\\nสุขุมาล\\nสุโข\\nสุคต\\nสุคติ\\nสุคนธ\\nสุคนธ์\\nสุคนธชาติ\\nสุคนธรส\\nสุคันธ์\\nสุคันธรส\\nสุงกะ\\nสุงกากร\\nสุงสิง\\nสุงสุมาร\\nสุจริต\\nสุจหนี่\\nสุจิ\\nสุจิต\\nสุจิตร\\nสุชน\\nสุชัมบดี\\nสุชา\\nสุชาดา\\nสุญ\\nสุญญากาศ\\nสุญตา\\nสุญนิยม\\nสุณ\\nสุณิสา\\nสุด\\nสุดา\\nสุต\\nสุตตนิบาต\\nสุตตะ\\nสุตตันตปิฎก\\nสุตตันตะ\\nสุติ\\nสุทธ\\nสุทธ์\\nสุทธาวาส\\nสุทธิ\\nสุทรรศน์\\nสุทัศน์\\nสุธา\\nสุธาโภชน์\\nสุธารส\\nสุธาสินี\\nสุธาสี\\nสุธี\\nสุนทร\\nสุนทรี\\nสุนทรียภาพ\\nสุนทรียศาสตร์\\nสุนทรียะ\\nสุนัข\\nสุนันท์\\nสุโนก\\nสุบดี\\nสุบรรณ\\nสุบิน\\nสุปรีดิ์\\nสุปรีย์\\nสุปาณี\\nสุพพัต\\nสุพรรณ\\nสุพรรณบัฏ\\nสุพรรณภาชน์\\nสุพรรณราช\\nสุพรรณศรี\\nสุพรรณถัน\\nสุพรรณิการ์\\nสุภร\\nสุภัค\\nสุภา\\nสุภาพ\\nสุภาษิต\\nสุม\\nสุ่ม\\nสุมทุม\\nสุมน\\nสุมนะ\\nสุมนัส\\nสุมนา\\nสุ้มเสียง\\nสุมะ\\nสุมาลี\\nสุเมธ\\nสุเมรุ\\nสุรคต\\nสุรเชษฐ์\\nสุรบดี\\nสุรภาพ\\nสุรโลก\\nสุรสีหนาท\\nสุรเสียง\\nสุรงค์\\nสุรังค์\\nสุรภี\\nสุรัติ\\nสุรัสวดี\\nสุรา\\nสุรางค์จำเรียง\\nสุรางคนา\\nสุรางคนางค์\\nสุรารักษ์\\nสุราลัย\\nสุรินทร์\\nสุรินทราหู\\nสุริยะ\\nสุริยกันต์\\nสุริยกานต์\\nสุริยการ\\nสุริยกาล\\nสุริยคติ\\nสุริยคราส\\nสุริยมณฑล\\nสุริยวงศ์\\nสุริยง\\nสุริยา\\nสุริเยนทร์\\nสุริเยศ\\nสุริโย\\nสุริยน\\nสุริยัน\\nสุริยุปราคา\\nสุรีย์\\nสุรุ่ยสุร่าย\\nสุลต่าน\\nสุวคนธ์\\nสุวภาพ\\nสุวรรณ\\nสุวรรณภูมิ\\nสุวะ\\nสุวาน\\nสุวินัย\\nสุวิมล\\nสุษิระ\\nสุสาน\\nสุหนัต\\nสุหร่ง\\nสุหร่าย\\nสุหฤท\\nสุหัท\\nสุเหร่า\\nสู\\nสู่\\nสู้\\nสูง\\nสูจิ\\nสูจิบัตร\\nสูญ\\nสูด\\nสูต\\nสูตร\\nสูติ\\nสูติกรรม\\nสูตินรีเวช\\nสูติบัตร\\nสูติแพทย์\\nสูติศาสตร์\\nสูท\\nสูทกรรม\\nสูทศาสตร์\\nสูบ\\nสูปะ\\nสูร\\nสูรย์\\nสูรยกานต์\\nสูริ\\nสูสี\\nเส\\nเสก\\nเสกขบุคคล\\nเสกขะ\\nเสขบุคคล\\nเสขะ\\nเส็ง\\nเส้ง\\nเส็งเคร็ง\\nเสงี่ยม\\nเสฏฐี\\nเสณี\\nเสด\\nเสด็จ\\nเสตุ\\nเสถียร\\nเสทะ\\nเสโท\\nเสน\\nเส้น\\nเสนง\\nเสน่ง\\nเสน่ห์\\nเสนหา\\nเสน่หา\\nเสนอ\\nเสนะ\\nเสนา\\nเสนาธิการ\\nเสนาบดี\\nเสน่า\\nเสนากุฎ\\nเสนางค์\\nเสนางคนิกร\\nเสนานี\\nเสนาสนะ\\nเสนาะ\\nเสนี\\nเสนีย์\\nเสนียะ\\nเสนียด\\nเสบย\\nเสบียง\\nเสพ\\nเสพย์\\nเสเพล\\nเสภา\\nเสม็ด\\nเสมหะ\\nเสมอ\\nเสมา\\nเสมียน\\nเสมือน\\nเสย\\nเสร็จ\\nเสริด\\nเสริม\\nเสรี\\nเสลด\\nเสลบรรพต\\nเสลา\\nเสลี่ยง\\nเสลือกสลน\\nเสโล\\nเสวก\\nเสวกามาตย์\\nเสวนะ\\nเสวนา\\nเสวย\\nเสวียน\\nเสสรวง\\nเสสรวล\\nเสา\\nเส้า\\nเสาร์\\nเสารภย์\\nเสารี\\nเสาวคนธ์\\nเสาวธาร\\nเสาวภา\\nเสาวภาคย์\\nเสาวภาพ\\nเสาวรภย์\\nเสาวรส\\nเสาวลักษณ์\\nเสาวณิต\\nเสาวนะ\\nเสาวนา\\nเสาวนีย์\\nเสาหฤท\\nเสาะ\\nเสาะแสะ\\nเสิร์จ\\nเสิร์ฟ\\nเสีย\\nเสียง\\nเสี่ยง\\nเสียด\\nเสี้ยน\\nเสียบ\\nเสียม\\nเสี่ยม\\nเสี้ยม\\nเสียว\\nเสี่ยว\\nเสี้ยว\\nเสือ\\nเสื่อ\\nเสื้อ\\nเสือก\\nเสื่อม\\nแส\\nแส่\\nแส้\\nแสก\\nแสง\\nแสด\\nแสดง\\nแสตมป์\\nแสน\\nแสนย์\\nแสนยากร\\nแสนยานุภาพ\\nแสบ\\nแสม\\nแสยก\\nแสยง\\nแสยะ\\nแสรก\\nแสร้ง\\nแสลง\\nแสล้ม\\nแสวง\\nแสะ\\nโสก\\nโสกโดก\\nโสกันต์\\nโสโครก\\nโสณฑ์\\nโสณิ\\nโสณี\\nโสด\\nโสดก\\nโสดม\\nโสดา\\nโสดาบัน\\nโสดาปัตติผล\\nโสดาปัตติมรรค\\nโสต\\nโสตทัศนวัสดุ\\nโสตทัศนอุปกรณ์\\nโสตทัศนูปกรณ์\\nโสตินทรีย์\\nโสตถิ\\nโสทก\\nโสทร\\nโสธก\\nโสธนะ\\nโสน\\nโสภณ\\nโสภา\\nโสภี\\nโสภิณี\\nโสเภณี\\nโสม\\nโสมนัส\\nโสมม\\nโสมย์\\nโสร่ง\\nโสรจ\\nโสรวาร\\nโสโร\\nโสวรรณ\\nโสหุ้ย\\nโสฬส\\nใส\\nใส่\\nไส\\nไส้\\nไสย\\nไสยา\\nไสยาสน์\\nไสร้\\nไสว\\nหก\\nหกคะเมน\\nหง\\nหงก\\nหงส์\\nหงสบาท\\nหงสรถ\\nหงอ\\nหงอก\\nหง่อง\\nหงองแหงง\\nหงอด\\nหงอน\\nหง่อม\\nหงอย\\nหง่อย\\nหงัก\\nหงับ\\nหง่าง\\nหงาย\\nหง่าว\\nหงำ\\nหงิก\\nหงิง\\nหงิม\\nหงึก\\nหงุงหงิง\\nหงุดหงิด\\nหงุบ\\nหงุ่ย\\nหญ้า\\nหญ้าฝรั่น\\nหญ้ายายเภา\\nหญิง\\nหญิบ\\nหด\\nหตะ\\nหทัย\\nหน\\nหนวก\\nหน่วง\\nหนวด\\nหน่วย\\nหน่วยกิต\\nหนอ\\nหน่อ\\nหนอก\\nหนอง\\nหนอน\\nหนอนตายหยาก\\nหน่อย\\nหน็อยแน่\\nหนัก\\nหนัง\\nหนังสติ๊ก\\nหนังสือ\\nหนั่น\\nหนับ\\nหนา\\nหน้า\\nหน่าง\\nหนาด\\nหนาน\\nหนาม\\nหน่าย\\nหนาว\\nหนำ\\nหนำเลี้ยบ\\nหนี\\nหนี้\\nหนีบ\\nหนึก\\nหนึ่ง\\nหนึบ\\nหนืด\\nหนุ\\nหนุน\\nหนุบ\\nหนุ่ม\\nหนุ่ย\\nหนู\\nห่ม\\nหมก\\nหมด\\nหม่น\\nหมวก\\nหมวด\\nหมวน\\nหมอ\\nหม่อ\\nหม้อ\\nหมอก\\nหมอง\\nหม่อง\\nหมอน\\nหม่อน\\nหมอบ\\nหม่อม\\nหมอย\\nหม้อห้อม\\nหมัก\\nหมักหมม\\nหมัด\\nหมัน\\nหมั่น\\nหมั้น\\nหมับ\\nหมา\\nหม่า\\nหมาก\\nหมากฮอส\\nหมาง\\nหมาด\\nหมามุ่ย\\nหมามุ้ย\\nหมาย\\nหม้าย\\nหมาร่า\\nหม่ำ\\nหม้ำ\\nหมิ่น\\nหมี\\nหมี่\\nหมึก\\nหมืน\\nหมื่น\\nหมุด\\nหมุน\\nหมุบ\\nหมุบหมับ\\nหมุบหมิบ\\nหมุ่ย\\nหมุยขาว\\nหมู\\nหมู่\\nหมูหริ่ง\\nหยก\\nหย่ง\\nหยด\\nหยวก\\nหยวบ\\nหยอก\\nหยอกเอิน\\nหย็อกหย็อย\\nหยอง\\nหย็อง\\nหย่อง\\nหย็องกรอด\\nหย็องแหย็ง\\nหยอด\\nหยอน\\nหย่อน\\nหย่อม\\nหย็อมแหย็ม\\nหย็อย\\nหย่อย\\nหยัก\\nหยักไย่\\nหยักเหยา\\nหยัง\\nหยั่ง\\nหยังหยัง\\nหยัด\\nหยัน\\nหยับ\\nหยั่วเมือง\\nหย่า\\nหยากเยื่อ\\nหยากไย่\\nหยาด\\nหยาบ\\nหยาม\\nหยาว\\nหย้าว\\nหยำเป\\nหยำเหยอะ\\nหยำแหยะ\\nหยิก\\nหยิ่ง\\nหยิบ\\nหยิม\\nหยี\\nหยี่\\nหยุกหยิก\\nหยุด\\nหยุ่น\\nหยุบ\\nหยุมหยิม\\nหยูกยา\\nหโยดม\\nหรคุณ\\nหรณะ\\nหรดาล\\nหรดี\\nหรรษ์\\nหรรษา\\nหรอ\\nหรอก\\nหร็อมแหร็ม\\nหรอย\\nหระ\\nหรับ\\nหรา\\nหริ\\nหริ่ง\\nหริณะ\\nหริต\\nหริตกี\\nหรีตกี\\nหรี่\\nหรีด\\nหรือ\\nหรุบ\\nหรุบรู่\\nหรุบหรู่\\nหรุ่ม\\nหรู\\nหรูหรา\\nหฤทัย\\nหฤทย์\\nหฤษฎ์\\nหฤษฎี\\nหฤหรรษ์\\nหฤโหด\\nหลง\\nหลงใหล\\nหลงจู๊\\nหลด\\nหลน\\nหล่น\\nหลบ\\nหล่ม\\nหลวง\\nหลวม\\nหลอ\\nหล่อ\\nหลอก\\nหลอด\\nหลอน\\nหล็อน\\nหล่อน\\nหลอม\\nหละ\\nหละหลวม\\nหลัก\\nหลัง\\nหลั่ง\\nหลัด\\nหลั่น\\nหลับ\\nหลัว\\nหลา\\nหล้า\\nหลาก\\nหลาน\\nหลาบ\\nหลาม\\nหลาย\\nหลาว\\nหลิ่ง\\nหลิท\\nหลิน\\nหลิม\\nหลิว\\nหลิ่ว\\nหลี\\nหลีก\\nหลีโก\\nหลีบ\\nหลีฮื้อ\\nหลืบ\\nหลุกหลิก\\nหลุด\\nหลุน\\nหลุบ\\nหลุม\\nหลุมพอ\\nหลุมพี\\nหลู่\\nหวง\\nห่วง\\nห้วง\\nหวด\\nหวน\\nห้วน\\nหวย\\nห้วย\\nหวอ\\nหวอด\\nหวะ\\nหวัง\\nหวัด\\nหวั่น\\nหวันยิหวา\\nหวัว\\nหวัวร่อ\\nหวัวเราะ\\nหวา\\nหว่า\\nหว้า\\nหวาก\\nหว่าง\\nหวาด\\nหวาน\\nหว่าน\\nหวาม\\nหวาย\\nหวำ\\nหวิด\\nหวิว\\nหวี\\nหวี่\\nหวีด\\nหวือ\\nหวุดหวิด\\nหวูด\\nหอ\\nห่อ\\nห้อ\\nหอก\\nหอง\\nห้อง\\nหอน\\nห่อน\\nหอบ\\nหอม\\nห้อม\\nหอย\\nห้อย\\nหะ\\nหะยี\\nหะหาย\\nหัก\\nหัจญ์\\nหัจญี\\nหัช\\nหัฏฐะ\\nหัด\\nหัต\\nหัตถ์\\nหัตถกรรม\\nหัตถการ\\nหัตถกิจ\\nหัตถบาส\\nหัตถพันธ์\\nหัตถาภรณ์\\nหัตถศาสตร์\\nหัตถศิลป์\\nหัตถศึกษา\\nหัตถาจารย์\\nหัตถินี\\nหัตถี\\nหัน\\nหั่น\\nหั้น\\nหันตรา\\nหับ\\nหัย\\nหัว\\nหัวร่อ\\nหัวเราะ\\nหัส\\nหัสดิน\\nหัสดี\\nหัสต์\\nหัสตะ\\nหา\\nห่า\\nห้า\\nหาก\\nหาง\\nห่าง\\nห้าง\\nหาญ\\nหาด\\nห่าน\\nหาบ\\nหาม\\nห่าม\\nห้าม\\nหาย\\nหายใจ\\nหายนะ\\nหาร\\nหารือ\\nหาว\\nห้าว\\nหาสะ\\nหำ\\nห้ำ\\nหิ้ง\\nหิงคุ\\nหิงสา\\nหิงห้อย\\nหิ่งห้อย\\nหิ่งหาย\\nหิด\\nหิต\\nหิตานุหิตประโยชน์\\nหิน\\nหิมพาน\\nหิมพานต์\\nหิมวัต\\nหิมวันต์\\nหิมวา\\nหิมะ\\nหิมาลัย\\nหิรัญ\\nหิรัญญิการ์\\nหิรัญบัฏ\\nหิรัณย์\\nหิรัณยรัศมี\\nหิริ\\nหิว\\nหิ้ว\\nหี\\nหีด\\nหีนยาน\\nหีบ\\nหึ\\nหึง\\nหึ่ง\\nหึงสา\\nหืด\\nหืน\\nหื่น\\nหือ\\nหื้อ\\nหุง\\nหุน\\nหุ่น\\nหุ้น\\nหุนหัน\\nหุบ\\nหุ้ม\\nหุยฮา\\nหู\\nหู่\\nหูก\\nหูด\\nเห\\nเห่\\nเหง\\nเหง่ง\\nเหงา\\nเหง้า\\nเหงื่อ\\nเหงือก\\nเห็จ\\nเห็ด\\nเหติ\\nเหตุ\\nเห็น\\nเหน่ง\\nเหนงนายพราน\\nเหน็ดเหนื่อย\\nเหน็บ\\nเหน่อ\\nเห็นอ้ม\\nเหนอะ\\nเหนอะหนะ\\nเหน้า\\nเหนาะ\\nเหนียง\\nเหนี่ยง\\nเหนี่ยน\\nเหนียม\\nเหนียว\\nเหนี่ยว\\nเหนือ\\nเหนื่อย\\nเห็บ\\nเหม\\nเหม่\\nเหม็ง\\nเหม่ง\\nเหม็น\\nเหมวดี\\nเหม่อ\\nเหมันต์\\nเหมันตฤดู\\nเหมา\\nเหมายัน\\nเหมาะ\\nเหมียว\\nเหมี่ยว\\nเหมือง\\nเหมือด\\nเหมือน\\nเหมื่อย\\nเหย\\nเหยง\\nเหย่อย\\nเหยา\\nเหย่า\\nเหย้า\\nเหยาะ\\nเหยาะแหยะ\\nเหยิง\\nเหยิบ\\nเหยียด\\nเหยียบ\\nเหยี่ยว\\nเหยื่อ\\nเหยือก\\nเหรอ\\nเหรอะ\\nเหรัญญิก\\nเหรา\\nเหราะ\\nเหรียญ\\nเหล่\\nเหล็ก\\nเหลน\\nเหลว\\nเหลอ\\nเหลา\\nเหล่า\\nเหล้า\\nเหลาะแหละ\\nเหลิง\\nเหลิงเจิ้ง\\nเหลียน\\nเหลี่ยม\\nเหลียว\\nเหลือ\\nเหลือก\\nเหลือง\\nเหลือบ\\nเหลือม\\nเหลื่อม\\nเหว\\nเหว่\\nเหวง\\nเหวย\\nเหวอะ\\nเหวอะหวะ\\nเหวี่ยง\\nเห่อ\\nเหอะ\\nเหะ\\nเหะหะ\\nเหา\\nเห่า\\nเหาะ\\nเหิน\\nเหิม\\nเหี้ย\\nเหียง\\nเหียน\\nเหี้ยน\\nเหี้ยม\\nเหี่ยว\\nเหื่อ\\nเหือด\\nแห\\nแห่\\nแห้\\nแหก\\nแหง\\nแหง่\\nแห่ง\\nแห้ง\\nแหงแก๋\\nแหง่ง\\nแหงน\\nแหน\\nแห้น\\nแหนง\\nแหนบ\\nแหนม\\nแหบ\\nแหม\\nแหม่\\nแหม่ม\\nแหมะ\\nแหย\\nแหย่\\nแหยง\\nแหย่ง\\nแหยม\\nแหย็ม\\nแหยะ\\nแหล่\\nแหลก\\nแหล่ง\\nแหลน\\nแหลม\\nแหละ\\nแหว\\nแห้ว\\nแหวก\\nแหว่ง\\nแหวด\\nแหวน\\nแหวะ\\nแหะ\\nโห่\\nโหง\\nโหด\\nโหน\\nโหนก\\nโหน่ง\\nโหม\\nโหม่ง\\nโหมด\\nโหย\\nโหยกเหยก\\nโหยง\\nโหย่ง\\nโหร\\nโหรง\\nโหรงเหรง\\nโหรดาจารย์\\nโหระพา\\nโหรา\\nโหราจารย์\\nโหราศาสตร์\\nโหล\\nโหล่\\nโหลงโจ้ง\\nโหว\\nโหว่\\nโหว้\\nโหวกเหวก\\nโหวง\\nโหวด\\nโหวต\\nให้\\nใหญ่\\nใหม่\\nไห\\nไห่\\nไห้\\nไหน\\nไหม\\nไหม้\\nไหรณย์\\nไหล\\nไหล่\\nไหว\\nไหว้\\nไหหลำ\\nอก\\nอกตเวทิตา\\nอกตเวที\\nอกตัญญุตา\\nอกตัญญู\\nอกนิษฐ์\\nอกรณีย์\\nอกรรมกริยา\\nอกัปปิยวัตถุ\\nอกัปปิยะ\\nอกุศล\\nอคติ\\nอคาธ\\nอโฆษะ\\nองก์\\nองค์\\nองคชาต\\nองคมนตรี\\nองครักษ์\\nองคาพยพ\\nองคุลี\\nองศ์\\nองศา\\nองอาจ\\nองุ่น\\nอจลา\\nอจินตา\\nอจินไตย\\nอจิระ\\nอเจลก\\nอเจละ\\nอชะ\\nอชิน\\nอชินี\\nอชิระ\\nอฏวี\\nอณิ\\nอณู\\nอโณทัย\\nอด\\nอดิถี\\nอดิเทพ\\nอดิเรก\\nอดิศร\\nอดิศวร\\nอดิศัย\\nอดีต\\nอดุล\\nอดุลย์\\nอติ\\nอติชาต\\nอติมานะ\\nอติราช\\nอติเรก\\nอติสาร\\nอถรรพเวท\\nอาถรรพเวท\\nอทระ\\nอทินนาทาน\\nอธรรม\\nอธิ\\nอธิกมาส\\nอธิกรณ์\\nอธิกวาร\\nอธิกสุรทิน\\nอธิการ\\nอธิคม\\nอธิฏฐาน\\nอธิบดี\\nอธิบาย\\nอธิป\\nอธิปไตย\\nอธิมาตร\\nอธิมุตติ\\nอธิโมกข์\\nอธิราช\\nอธิวาส\\nอธิวาสนะ\\nอธิศีล\\nอธิษฐาน\\nอธึก\\nอ้น\\nอนงค์\\nอนงคณะ\\nอนงคเลขา\\nอนธการ\\nอนนต์\\nอนยะ\\nอนรรฆ\\nอนรรถ\\nอนล\\nอนวัช\\nอนัญ\\nอนัตตา\\nอนันต์\\nอนันตริยกรรม\\nอนัม\\nอนาคต\\nอนาคามิผล\\nอนาคามิมรรค\\nอนาคามี\\nอนาจาร\\nอนาถ\\nอนาถา\\nอนาทร\\nอนาธิปไตย\\nอนามัย\\nอนามิกา\\nอนารยชน\\nอนารยธรรม\\nอนารยะ\\nอนาลัย\\nอนำ\\nอนิจ\\nอนิจจัง\\nอนิจจา\\nอนิฏฐารมณ์\\nอนิยต\\nอนิยม\\nอนิล\\nอนิวรรต\\nอนิวรรตน์\\nอนีกะ\\nอนีจะ\\nอนึก\\nอนึ่ง\\nอนุ\\nอนุกร\\nอนุกรม\\nอนุกรรมการ\\nอนุกระเบียด\\nอนุกาชาด\\nอนุการ\\nอนุกูล\\nอนุคามิก\\nอนุเคราะห์\\nอนุจร\\nอนุช\\nอนุชน\\nอนุชา\\nอนุชาต\\nอนุชิต\\nอนุญาต\\nอนุญาโตตุลาการ\\nอนุตร\\nอนุเถระ\\nอนุทิน\\nอนุบท\\nอนุบาล\\nอนุประโยค\\nอนุปริญญา\\nอนุปสัมบัน\\nอนุปัสนา\\nอนุพงศ์\\nอนุพัทธ์\\nอนุพันธ์\\nอนุโพธ\\nอนุภรรยา\\nอนุภริยา\\nอนุภาค\\nอนุภาษ\\nอนุมัติ\\nอนุมาตรา\\nอนุมาน\\nอนุมูล\\nอนุโมทนา\\nอนุโยค\\nอนุรักษ์\\nอนุรักษนิยม\\nอนุราช\\nอนุราธ\\nอนุราธะ\\nอนุราธา\\nอนุรูป\\nอนุโลม\\nอนุวงศ์\\nอนุวรรตน์\\nอนุวัต\\nอนุวัตน์\\nอนุวัตร\\nอนุวัติ\\nอนุวาต\\nอนุศาสก\\nอนุศาสน์\\nอนุศาสนาจารย์\\nอนุศิษฏ์\\nอนุสติ\\nอนุสนธิ\\nอนุสร\\nอนุสรณ์\\nอนุสัญญา\\nอนุสัย\\nอนุสาวรีย์\\nอนุสาสนี\\nอเนก\\nอเนกคุณ\\nอเนกรรถประโยค\\nอเนจอนาถ\\nอโนชา\\nอโนดาต\\nอบ\\nอบเชย\\nอบาย\\nอปจายนธรรม\\nอปจายนมัย\\nอปมงคล\\nอปยศ\\nอประไมย\\nอปรัณณชาติ\\nอปรา\\nอปราชัย\\nอปราชิต\\nอปริมาณ\\nอปลักษณ์\\nอปโลกน์\\nอปวาท\\nอเปหิ\\nอพพะ\\nอพยพ\\nอภัพ\\nอภัย\\nอภิ\\nอภิฆาต\\nอภิชฌา\\nอภิชน\\nอภิชนาธิปไตย\\nอภิชัย\\nอภิชาต\\nอภิชิต\\nอภิญญา\\nอภิญญาณ\\nอภิธรรม\\nอภิธาน\\nอภิไธย\\nอภินันท์\\nอภินันทนาการ\\nอภินัย\\nอภินิหาร\\nอภิเนษกรมณ์\\nอภิบาล\\nอภิปรัชญา\\nอภิปราย\\nอภิมหาอำนาจ\\nอภิมานะ\\nอภิมุข\\nอภิรดี\\nอภิรติ\\nอภิรมย์\\nอภิรักษ์\\nอภิราม\\nอภิรุต\\nอภิรุม\\nอภิรูป\\nอภิลักขิต\\nอภิลักขิตสมัย\\nอภิเลปน์\\nอภิวันท์\\nอภิวาท\\nอภิวาทน์\\nอภิเษก\\nอภิสมโพธิ\\nอภิสมัย\\nอภิสมาจาร\\nอภิสัมโพธิ\\nอภิสัมโพธิญาณ\\nอภิสิต\\nอภิสิทธิ์\\nอภูตะ\\nอม\\nอมพะนำ\\nอ้ม\\nอมตธรรม\\nอมตบท\\nอมตะ\\nอมนุษย์\\nอมร\\nอมรา\\nอมราวดี\\nอมรินทร์\\nอมเรนทร์\\nอมเรศ\\nอมฤต\\nอมัตร\\nอมาตย์\\nอมาวสี\\nอมาวสุ\\nอมาวาสี\\nอมิตร\\nอเมริกัน\\nอย่า\\nอยาก\\nอย่าง\\nอยุทธ์\\nอยู่\\nอร\\nอรชร\\nอรชุน\\nอรดี\\nอรติ\\nอรทัย\\nอรไท\\nอรนุช\\nอรพินท์\\nอรพิม\\nอรรค\\nอรรฆ\\nอรรฆย์\\nอรรจน์\\nอรรณพ\\nอรรถ\\nอรรถกถา\\nอรรถกถาจารย์\\nอรรถาธิบาย\\nอรรธ\\nอรสุม\\nอรหะ\\nอรหัง\\nอรหัต\\nอรหัตผล\\nอรหัตมรรค\\nอรหัน\\nอรหันต์\\nอรหันตฆาต\\nอร่อย\\nอรัญ\\nอรัญญิก\\nอรัญวาส\\nอรัญวาสี\\nอรัณย์\\nอราดี\\nอร่าม\\nอริ\\nอรินทร์\\nอริน\\nอริยกะ\\nอริยทรัพย์\\nอริยบุคคล\\nอริยผล\\nอริยมรรค\\nอริยสัจ\\nอริยะ\\nอรุณ\\nอรุโณทัย\\nอรุ่ม\\nอรูป\\nอลงกต\\nอลงกรณ์\\nอลงการ\\nอลวน\\nอลเวง\\nอลหม่าน\\nอล่องฉ่อง\\nอลักเอลื่อ\\nอลังการ\\nอลัชชี\\nอล่างฉ่าง\\nอลิงค์\\nอลึงค์\\nอลึ่งฉึ่ง\\nอโลหะ\\nอ้วก\\nอวกาศ\\nอวจร\\nอวชัย\\nอวชาต\\nอวด\\nอวตาร\\nอวน\\nอ้วน\\nอวบ\\nอวมงคล\\nอวย\\nอวยวะ\\nอวรรค\\nอวรุทธ์\\nอวรุทธก\\nอวล\\nอวสาน\\nอวหาร\\nอวัยวะ\\nอวัสดา\\nอวาจี\\nอวิจี\\nอวิชชา\\nอวิญญาณกทรัพย์\\nอวิญญู\\nอวิรุทธ์\\nอวิโรธน์\\nอวิโรธนะ\\nอวิหิงสา\\nอวีจิ\\nอเวจี\\nอโศก\\nอสงไขย\\nอสนี\\nอัสนี\\nอสนีบาต\\nอสภะ\\nอสมการ\\nอสมมาตร\\nอสรพิษ\\nอสังหาริมทรัพย์\\nอสังหาริมะ\\nอสัญกรรม\\nอสัญญี\\nอสัญแดหวา\\nอสัตถพฤกษ์\\nอัสสัตถพฤกษ์\\nอสัตย์\\nอสัมภิน\\nอสัมภินพงศ์\\nอสัมภินวงศ์\\nอสิ\\nอสิธารา\\nอสิต\\nอสิเลสะ\\nอสีตยานุพยัญชนะ\\nอสีติ\\nอสุ\\nอสุจิ\\nอสุนีบาต\\nอสุภ\\nอสุรกาย\\nอสุรา\\nอสุรี\\nอสุเรศ\\nอสูร\\nอเสกขบุคคล\\nอเสกขะ\\nอเสขบุคคล\\nอเสขะ\\nอหังการ\\nอหิ\\nอหิงสา\\nอหิวาต์\\nอหิวาตกโรค\\nอหึงสา\\nอเหตุกทิฐิ\\nอโหสิ\\nออ\\nอ้อ\\nอ๋อ\\nออก\\nออกซิเจน\\nออกซิเดชัน\\nออกไซด์\\nออกญา\\nอ่อง\\nอ๋อง\\nอ้องแอ้ง\\nออเซาะ\\nออด\\nอ๊อด\\nอ๊อดแอ๊ด\\nอ่อน\\nอ้อน\\nออนซ์\\nออนซอน\\nอ้อนแอ้น\\nออฟฟิศ\\nออม\\nอ่อม\\nอ้อม\\nออมชอม\\nออมซอม\\nอ้อมแอ้ม\\nอ่อย\\nอ้อย\\nอ๋อย\\nอ้อยส้อย\\nอ้อยอิ่ง\\nออสเมียม\\nอ้อแอ้\\nอ๊ะ\\nอะคร้าว\\nอะเคื้อ\\nอะแจ\\nอะเซทิลีน\\nอะดรีนาลิน\\nอะดุง\\nอะตอม\\nอะมีบา\\nอะเมริเซียม\\nอะร้าอร่าม\\nอะไร\\nอะลุ่มอล่วย\\nอะลุ้มอล่วย\\nอะลูมิเนียม\\nอะหม\\nอะไหล่\\nอัก\\nอั้ก\\nอั๊ก\\nอักกะ\\nอักโกธะ\\nอักขรวิธี\\nอักขรวิบัติ\\nอักขรสมัย\\nอักขระ\\nอักขรานุกรม\\nอักขะ\\nอักโข\\nอักโขภิณี\\nอักโขเภณี\\nอักษร\\nอักษะ\\nอักเษาหิณี\\nอักเสบ\\nอักอ่วน\\nอัคคะ\\nอัคคิ\\nอัคคี\\nอัคนิ\\nอัคนี\\nอัคร\\nอัครชายา\\nอัครมเหสี\\nอัครราชทูต\\nอัครสมณทูต\\nอัง\\nอังก์\\nอังกนะ\\nอังกฤษ\\nอังกะลุง\\nอังกา\\nอังกาบ\\nอังกุระ\\nอังกุศ\\nอังกูร\\nอังคณะ\\nอังคณา\\nอังคาร\\nอังคาส\\nอังคีรส\\nอังคุฐ\\nอังคุตรนิกาย\\nอังฆาต\\nอังแพลม\\nอั้งยี่\\nอั้งโล่\\nอังศุ\\nอังศุก\\nอังศุธร\\nอังศุมาลี\\nอังสกุฏ\\nอังสตรอม\\nอังสนา\\nอังสภาระ\\nอังสะ\\nอังสา\\nอัจกลับ\\nอัจจิ\\nอัจจิมา\\nอัจจุตะ\\nอัจฉรา\\nอัจฉริยบุคคล\\nอัจฉริยภาพ\\nอัจฉริยลักษณ์\\nอัจฉริยลักษณะ\\nอัจฉริยะ\\nอัจนา\\nอัชฌัตติก\\nอัชฌา\\nอัชฌาจาร\\nอัชฌาศัย\\nอัชฌาสัย\\nอัญเดียรถีย์\\nอัญมณี\\nอัญขยม\\nอัญชนะ\\nอัญชลี\\nอัญชัน\\nอัญชุลี\\nอัญเชิญ\\nอัญญะ\\nอัญดิตถีย์\\nอัญเดียรถีย์\\nอัญประกาศ\\nอัญรูป\\nอัฏ\\nอัฏฐบาน\\nอัฏฐะ\\nอัฏฐังคิกมรรค\\nอัฏนา\\nอัฐ\\nอัฐฬส\\nอัฐเคราะห์\\nอัฐทิศ\\nอัฐบริขาร\\nอัฐบาน\\nอัฐม\\nอัฐมี\\nอัฐศก\\nอัฐิ\\nอัฒจันทร์\\nอัฒภาค\\nอัฒมาส\\nอัฒรัตติ\\nอัณฑโกส\\nอัณฑชะ\\nอัณฑะ\\nอัณณพ\\nอัด\\nอัดแจ\\nอัต\\nอัตชีวประวัติ\\nอัตนัย\\nอัตภาพ\\nอัตวินิบาตกรรม\\nอัตคัด\\nอัตตโนบท\\nอัตตา\\nอัตตาธิปไตย\\nอัตถ์\\nอัตถะ\\nอัตโนมัติ\\nอัตรชะ\\nอัตรา\\nอัตลัด\\nอัททา\\nอัทธ์\\nอัทธา\\nอัทธาน\\nอัทธายุ\\nอัธยาตมวิทยา\\nอัธยาย\\nอัธยาศัย\\nอัน\\nอั้น\\nอั๋น\\nอันดร\\nอันดับ\\nอันตกะ\\nอันตกาล\\nอันตะ\\nอันตคุณ\\nอันตรภาค\\nอันตรวาสก\\nอันตรธาน\\nอันตรา\\nอันตราย\\nอันตรายิกธรรม\\nอันติกะ\\nอันติมสัจ\\nอันติมะ\\nอันเต\\nอันโต\\nอันเตปุริก\\nอันเตวาสิก\\nอันแถ้ง\\nอันโทล\\nอันธการ\\nอันธพาล\\nอันธิกา\\nอันเวส\\nอับ\\nอับปาง\\nอัปปะ\\nอัปเปหิ\\nอัปภาคย์\\nอัปมงคล\\nอัปยศ\\nอัประมาณ\\nอัประไมย\\nอัปราชัย\\nอัปรีย์\\nอัปลักษณ์\\nอัปสร\\nอัพพุท\\nอัพโพหาริก\\nอัพภันดร\\nอัพภาน\\nอัพภาส\\nอัพภูตธรรม\\nอัพยากฤต\\nอัมพฤกษ์\\nอัมพาต\\nอัมพวัน\\nอัมพวา\\nอัมพร\\nอัมพา\\nอัมพิละ\\nอัมพุ\\nอัมพุช\\nอัมพุชินี\\nอัมพุท\\nอัยกา\\nอัยการ\\nอัยกี\\nอัยยะ\\nอัยยิกา\\nอัลกุรอาน\\nอัลตราไวโอเลต\\nอั่ว\\nอัศจรรย์\\nอัศเจรีย์\\nอัศว\\nอัศวเมธ\\nอัศวยุช\\nอัศวานึก\\nอัศวิน\\nอัศวินี\\nอัษฎมงคล\\nอัษฏมงคล\\nอัษฎางคิกมรรค\\nอัษฎายุธ\\nอัษฎาวุธ\\nอัสสะ\\nอัสดร\\nอัสกัณ\\nอัสดง\\nอัสดงคต\\nอัสมิมานะ\\nอัสสนี\\nอัสสานึก\\nอัสสาสะ\\nอัสสุ\\nอา\\nอ่า\\nอ้า\\nอ๋า\\nอากร\\nอากังขา\\nอากัป\\nอาการ\\nอากาศ\\nอากูล\\nอาเกียรณ์\\nอาขยาต\\nอาขยาน\\nอาคเนย์\\nอาคม\\nอาครหายณี\\nอาคันตุกะ\\nอาคันตุกภัต\\nอาคันตุกวัตร\\nอาคาร\\nอาฆาต\\nอ่าง\\nอ้าง\\nอางขนาง\\nอ้างว้าง\\nอาจ\\nอาจม\\nอาจริยวัตร\\nอาจริยวาท\\nอาจาด\\nอาจาร\\nอาจารย์\\nอาจารี\\nอาจิณ\\nอาเจียน\\nอาชญา\\nอาชวะ\\nอาชา\\nอาชาไนย\\nอาชีพ\\nอาชีวศึกษา\\nอาชีวะ\\nอาชีวก\\nอาญา\\nอาฏานา\\nอาณัติ\\nอาณา\\nอาด\\nอาดูร\\nอาดุลย์\\nอาดูลย์\\nอาเด๊ะ\\nอาตมภาพ\\nอาตมัน\\nอาตมา\\nอาถรรพ์\\nอาถรรพณ์\\nอาทร\\nอาทิ\\nอาทิจจวาร\\nอาทิตย์\\nอาทิตยมณฑล\\nอาทิตยวาร\\nอาทีนพ\\nอาทีนวะ\\nอาทึก\\nอาเทศ\\nอาเทสนา\\nอาธรรม\\nอาธรรม์\\nอาธาน\\nอาธาร\\nอาน\\nอ่าน\\nอานน\\nอานนท์\\nอานันท์\\nอานันทนะ\\nอานัม\\nอานาปานะ\\nอานาปานัสสติ\\nอานิสงส์\\nอานุภาพ\\nอานุภาวะ\\nอาบ\\nอาบัติ\\nอาบัน\\nอาปณกะ\\nอาปณะ\\nอาปะ\\nอาโป\\nอาปานะ\\nอาพัทธ์\\nอาพันธ์\\nอาพันธนะ\\nอาพาธ\\nอาเพศ\\nอาภรณ์\\nอาภัพ\\nอาภัสระ\\nอาภา\\nอาภาส\\nอามลกะ\\nอามัย\\nอามิษ\\nอามิส\\nอาย\\nอ้าย\\nอายตนะ\\nอายตะ\\nอายน\\nอายัด\\nอายัต\\nอายัน\\nอายาจนะ\\nอายานะ\\nอายุ\\nอายุตกะ\\nอายุธ\\nอายุรกรรม\\nอายุรแพทย์\\nอายุรเวช\\nอายุรเวท\\nอายุศาสตร์\\nอายุษ\\nอาร์กอน\\nอารดี\\nอารติ\\nอาร์ต\\nอารทรา\\nอาร์ม\\nอารมณ์\\nอารยชน\\nอารยชาติ\\nอารยธรรม\\nอารยประเทศ\\nอารยะ\\nอารยัน\\nอาระ\\nอารักขา\\nอารักษ์\\nอารัญ\\nอารัณย์\\nอารัญญิก\\nอารัณยกะ\\nอารัติ\\nอารัมภ์\\nอารัมภกถา\\nอารัมภบท\\nอารัมภะ\\nอาราธน์\\nอาราธนา\\nอาราม\\nอารามิก\\nอารี\\nอารุม\\nอาลปนะ\\nอาละวาด\\nอาลักษณ์\\nอาลัย\\nอาลัว\\nอาลี\\nอาโลก\\nอาว\\nอ่าว\\nอ้าว\\nอาวรณ์\\nอาวัชนาการ\\nอาวัล\\nอาวาส\\nอาวาสิก\\nอาวาหมงคล\\nอาวาหะ\\nอาวุต\\nอาวุธ\\nอาวุโส\\nอาเวค\\nอาศรม\\nอาศรมบท\\nอาศเลษา\\nอาศัย\\nอาศิรพจน์\\nอาศิรพาท\\nอาศิรวาท\\nอาศุ\\nอาเศียรพจน์\\nอาเศียรพาท\\nอาเศียรวาท\\nอาษาฒ\\nอาสน\\nอาสน์\\nอาสนะ\\nอาสนศาลา\\nอาสัญ\\nอาสัตย์\\nอาสา\\nอาสาฬห์\\nอาสาฬหบูชา\\nอาสาฬหะ\\nอาสิญจ์\\nอาสิน\\nอาหม\\nอาหรับ\\nอาหาร\\nอาฬหก\\nอำ\\nอ่ำ\\nอ้ำ\\nอำแดง\\nอำนนต์\\nอำนรรฆ\\nอำนวย\\nอำนาจ\\nอำนาถ\\nอำนิฐ\\nอำนิษฐ์\\nอำปลัง\\nอำพน\\nอำพล\\nอำพะนำ\\nอำพัน\\nอำไพ\\nอำเภอ\\nอำมร\\nอำมฤคโชค\\nอำมฤต\\nอำมหิต\\nอำมาตย์\\nอำมาตยาธิปไตย\\nอำยวน\\nอำรุง\\nอำลา\\nอำอวม\\nอ้ำอึ้ง\\nอิก\\nอิง\\nอิงค์\\nอิงอร\\nอิจฉา\\nอิฉัน\\nอิชยา\\nอิฏฐารมณ์\\nอิฐ\\nอิฐผล\\nอิด\\nอิตถี\\nอิตเทรียม\\nอิตเทอร์เบียม\\nอิติวุตตกะ\\nอิทธิ\\nอิน\\nอินซูลิน\\nอินเดีย\\nอินเดียนแดง\\nอินเดียม\\nอินท์\\nอินทขีล\\nอินทนิล\\nอินทผลัม\\nอินทร์\\nอินทรธนู\\nอินทรวงศ์\\nอินทรวิเชียร\\nอินทรศักดิ์\\nอินทราณี\\nอินทราภิเษก\\nอินทรายุธ\\nอินทรี\\nอินทรีย์\\nอินทรียสังวร\\nอินทีวร\\nอินทุ\\nอินฟราเรด\\nอินัง\\nอิ่ม\\nอิมัลชัน\\nอิริเดียม\\nอิริยา\\nอิริยาบถ\\nอิรุพเพท\\nอิเล็กตรอน\\nอิเล็กทรอนิกส์\\nอิเล็กโทน\\nอิศร\\nอิศวร\\nอิษฏ์\\nอิษฏี\\nอิส\\nอิสตรี\\nอิสัตรี\\nอิสรภาพ\\nอิสระ\\nอิสริยยศ\\nอิสริยะ\\nอิสริยาภรณ์\\nอิสลาม\\nอิสสา\\nอิสิ\\nอิสี\\nอิหม่าม\\nอิหลักอิเหลื่อ\\nอี\\nอี่\\nอี้\\nอี๊\\nอี๋\\nอี๋อ๋อ\\nอีก\\nอีก้อ\\nอีก๋อย\\nอีโก้ง\\nอีจู้\\nอี๊ด\\nอีเต้อ\\nอีโต้\\nอีทุบ\\nอีเทอร์\\nอีนุงตุงนัง\\nอีนูน\\nอีโน\\nอีแปะ\\nอีโปง\\nอีเพา\\nอีมู\\nอีรม\\nอีลุ้ม\\nอีลุ่ยฉุยแฉก\\nอีเลิ้ง\\nอีศ\\nอีศวร\\nอีส\\nอีสาน\\nอีสุกอีใส\\nอีหรอบ\\nอีหลักอีเหลื่อ\\nอีหลี\\nอีหลุกขลุกขลัก\\nอีหลุกขลุกขลุ่ย\\nอีเห็น\\nอีเหน็บ\\nอีเหนียว\\nอีเหละเขละขละ\\nอีเหละเขะขะ\\nอีโหน่อีเหน่\\nอีโหลกโขลกเขลก\\nอีแอ่น\\nอึ\\nอึก\\nอึ้ก\\nอึ๊ก\\nอึกทึก\\nอึกอัก\\nอึง\\nอึ่ง\\nอึ้ง\\nอึด\\nอึดตะปือ\\nอึ้ดทึ่ด\\nอึน\\nอืด\\nอื่น\\nอื้น\\nอือ\\nอื้อ\\nอื้อฮือ\\nอุ\\nอุก\\nอุกกา\\nอุกกาบาต\\nอุกฤษฏ์\\nอุกลาบาต\\nอุค\\nอุคระ\\nอุคหนิมิต\\nอุโฆษ\\nอุ้ง\\nอุจ\\nอุจจาระ\\nอุจฉุ\\nอุจเฉท\\nอุจเฉททิฐิ\\nอุจาด\\nอุชุ\\nอุฏฐาการ\\nอุณหภูมิ\\nอุณหะ\\nอุณหาหาร\\nอุณหิส\\nอุณา\\nอุณาโลม\\nอุด\\nอุดเตา\\nอุดม\\nอุดมการณ์\\nอุดมคติ\\nอุดมศึกษา\\nอุดร\\nอุดหนุน\\nอุตดม\\nอุตตมะ\\nอุตมภาพ\\nอุตมางค์\\nอุตดร\\nอุตรกุรุทวีป\\nอุตตรายัน\\nอุตรนิกาย\\nอุตรผลคุนี\\nอุตตรผลคุนี\\nอุตรภัทรบท\\nอุตตรภัทรบท\\nอุตตรภัททะ\\nอุตราภิมุข\\nอุตราวรรต\\nอุตราวัฏ\\nอุตราษาฒ\\nอุตตราสาฬหะ\\nอุตราสงค์\\nอุตตานภาพ\\nอุตพิด\\nอุตรา\\nอุตริ\\nอุตริมนุสธรรม\\nอุตลุด\\nอุตส่าห์\\nอุตสาหกรรม\\nอุตสาหะ\\nอุตุ\\nอุตุนิยม\\nอุตุนิยมวิทยา\\nอุทก\\nอุทกธาร\\nอุทกธารา\\nอุทกภัย\\nอุทกวิทยา\\nอุทกศาสตร์\\nอุทธรณ์\\nอุทธัจ\\nอุทยาน\\nอุทร\\nอุทริยะ\\nอุทลุม\\nอุทัช\\nอุทัย\\nอุทาน\\nอุทาร\\nอุทาหรณ์\\nอุทิศ\\nอุทุมพร\\nอุเทศ\\nอุเทสิกเจดีย์\\nอุธัจ\\nอุ่น\\nอุบ\\nอุบล\\nอุบะ\\nอุบ๊ะ\\nอุบัติ\\nอุบาท\\nอุบาทว์\\nอุบาย\\nอุบาสก\\nอุบาสิกา\\nอุเบกขา\\nอุโบสถ\\nอุปกรณ์\\nอุปกรม\\nอุปการ\\nอุปการะ\\nอุปการี\\nอุปกิเลส\\nอุปจาร\\nอุปถัมภ์\\nอุปถัมภก\\nอุปทม\\nอุปทูต\\nอุปเทศ\\nอุปเท่ห์\\nอุปธิ\\nอุปนัย\\nอุปนิกขิต\\nอุปนิษัท\\nอุปนิสัย\\nอุปบัติ\\nอุปปาติกะ\\nอุปพัทธ์\\nอุปพันธ์\\nอุปโภค\\nอุปมา\\nอุปมาน\\nอุปไมย\\nอุปยุวราช\\nอุปรากร\\nอุปราคา\\nอุปราช\\nอุปริ\\nอุปริมปริยาย\\nอุปโลกน์\\nอุปเวท\\nอุปสมบท\\nอุปสมบัน\\nอุปสัมบัน\\nอุปสรรค\\nอุปสัมปทา\\nอุปฮาด\\nอุปัชฌาย์\\nอุปัชฌายวัตร\\nอุปัชฌายะ\\nอุปัฏฐาก\\nอุปัฏฐานะ\\nอุปัทวะ\\nอุปัทวันตราย\\nอุปาทาน\\nอุปาหนา\\nอุภัย\\nอุ้ม\\nอุมงค์\\nอุโมงค์\\nอุย\\nอุ่ย\\nอุ้ย\\nอุ๊ย\\nอุยยาน\\nอุยยาม\\nอุรณะ\\nอุรพี\\nอุระ\\nอุรังอุตัง\\nอุรัจฉัท\\nอุรัจฉทะ\\nอุรา\\nอุรุ\\nอุไร\\nอุลกมณี\\nอุลโลจ\\nอุลามก\\nอุลิด\\nอุโลก\\nอุแว้\\nอุษณกร\\nอุษณกาล\\nอุษณรัศมี\\nอุษณรุจี\\nอุษณาการ\\nอุษณีษ์\\nอุษมะ\\nอุษมัน\\nอุษา\\nอุษาโยค\\nอุสภ\\nอุสส่าห์\\nอุสสาหะ\\nอุสา\\nอุสุ\\nอุสุภ\\nอุสุภราช\\nอุสุม\\nอุหรับ\\nอุหลบ\\nอุเหม่\\nอุฬาร\\nอู\\nอู่\\nอู้\\nอูฐ\\nอูด\\nอูม\\nอูย\\nอูรุ\\nอู๋อี๋\\nเอ\\nเอ้\\nเอ๊\\nเอก\\nเอกเขนก\\nเอกซเรย์\\nเอกรรถประโยค\\nเอกัคตา\\nเอกังสพยากรณ์\\nเอกังสวาที\\nเอกา\\nเอ้กา\\nเอกาธิปไตย\\nเอเคอร์\\nเอง\\nเอ็ง\\nเอ๋ง\\nเอ็ด\\nเอ็ดตะโร\\nเอดส์\\nเอตทัคคะ\\nเอ้เต\\nเอทิล\\nเอน\\nเอ็น\\nเอนไซม์\\nเอ็นดู\\nเอ็นอ่อน\\nเอม\\nเอ็มบริโอ\\nเอย\\nเอ่ย\\nเอ๊ย\\nเอ๋ย\\nเอร็ดอร่อย\\nเอราวัณ\\nเอว\\nเอ๊ว\\nเอวัง\\nเอฬกะ\\nเอฬา\\nเออ\\nเอ่อ\\nเออร์เบียม\\nเอ้อระเหย\\nเอ้อเร้อ\\nเอ้อเฮอ\\nเอ๊ะ\\nเอะใจ\\nเอะอะ\\nเอะอะมะเทิ่ง\\nเอา\\nเอาทาร\\nเอาทารย์\\nเอารส\\nเอาฬาร\\nเอาะลาย\\nเอิก\\nเอิกเกริก\\nเอิ้น\\nเอิบ\\nเอียง\\nเอี้ยง\\nเอียด\\nเอี๊ยด\\nเอียน\\nเอี่ยน\\nเอี่ยม\\nเอี๊ยม\\nเอี้ยมจุ๊น\\nเอี้ยมเฟี้ยม\\nเอี่ยว\\nเอี้ยว\\nเอื้อ\\nเอื๊อก\\nเอื้อง\\nเอือด\\nเอือน\\nเอื้อน\\nเอือม\\nเอื้อม\\nเอื่อย\\nเอื้อย\\nแอ\\nแอ้\\nแอ๋\\nแอก\\nแอกทิเนียม\\nแอ่ง\\nแอ้งแม้ง\\nแอด\\nแอ้ด\\nแอ๊ด\\nแอ่น\\nแอนติเจน\\nแอนติบอดี\\nแอนติอิเล็กตรอน\\nแอโนด\\nแอบ\\nแอม\\nแอ้ม\\nแอมแปร์\\nแอมมิเตอร์\\nแอมโมเนีย\\nแอร่ม\\nแอลกอฮอล์\\nแอลฟา\\nแอว\\nแอ่ว\\nแอ้วแซ่ว\\nแอสทาทีน\\nแอสไพริน\\nแอสฟัลต์\\nแอหนัง\\nแออัด\\nโอ\\nโอ่\\nโอ้\\nโอ๋\\nโอก\\nโอ้ก\\nโอ้กอ้าก\\nโอ๊ก\\nโอกาส\\nโอฆชล\\nโอฆสงสาร\\nโอฆะ\\nโอ่ง\\nโองการ\\nโองโขดง\\nโอชะ\\nโอชา\\nโอโซน\\nโอฐ\\nโอด\\nโอ๊ต\\nโอตตัปปะ\\nโอทนะ\\nโอน\\nโอบ\\nโอปปาติกะ\\nโอภา\\nโอภาส\\nโอม\\nโอย\\nโอ๊ย\\nโอรส\\nโอละพ่อ\\nโอลิมปิก\\nโอวาท\\nโอษฐ์\\nโอษฐชะ\\nโอษฐภัย\\nโอสถ\\nโอห์ม\\nโอหัง\\nโอฬาร\\nโอฬาริก\\nโอฬารึก\\nโอ้เอ้\\nโอเอซิส\\nโอ้โฮ\\nไอ\\nไอ้\\nไอโซโทป\\nไอน์สไตเนียม\\nไอยรา\\nไอยเรศ\\nไอราพต\\nไอราวัณ\\nไอราวัต\\nไอศกรีม\\nไอศวรรย์\\nไอศุริยสมบัติ\\nไอศูรย์\\nไอออน\\nไอโอดีน\\nฮกเกี้ยน\\nฮด\\nฮวงซุ้ย\\nฮวน\\nฮ้วนหมู\\nฮวบ\\nฮ่อ\\nฮ้อ\\nฮอกกี้\\nฮอด\\nฮ่อม\\nฮ่อยจ๊อ\\nฮอร์โมน\\nฮอลแลนด์\\nฮอลันดา\\nฮะ\\nฮะเบส\\nฮะเรีย\\nฮัก\\nฮังเล\\nฮัจญ์\\nฮัจญะฮ์\\nฮัจญี\\nฮั่น\\nฮั้ว\\nฮา\\nฮ้า\\nฮ่างหลวง\\nฮาจญ์\\nฮาม\\nฮาเร็ม\\nฮาห์เนียม\\nฮิจเราะห์\\nฮินดู\\nฮิปโปโปเตมัส\\nฮิสทีเรีย\\nฮีเลียม\\nฮึ\\nฮึก\\nฮึด\\nฮึดฮัด\\nฮึ่ม\\nฮึย\\nฮึ่ย\\nฮืดฮาด\\nฮือ\\nฮื่อ\\nฮื้อ\\nฮื้อฉี่\\nฮุด\\nฮุบ\\nฮุยเลฮุย\\nฮู้\\nฮูก\\nฮูม\\nเฮ\\nเฮฮา\\nเฮกตาร์\\nเฮกโตกรัม\\nเฮกโตเมตร\\nเฮกโตลิตร\\nเฮง\\nเฮ็ด\\nเฮโมโกลบิน\\nเฮย\\nเฮ่ย\\nเฮ้ย\\nเฮโรอีน\\nเฮลิคอปเตอร์\\nเฮโล\\nเฮละโล\\nเฮ้ว\\nเฮอ\\nเฮ่อ\\nเฮ้อ\\nเฮอริเคน\\nเฮิรตซ์\\nเฮี้ยน\\nเฮี้ยบ\\nเฮี้ยว\\nเฮือก\\nเฮือน\\nแฮ\\nแฮ่\\nแฮก\\nแฮ่กึ๊น\\nแฮนด์บอล\\nแฮฟเนียม\\nแฮม\\nแฮะ\\nโฮ\\nโฮก\\nโฮ่ง\\nโฮ้ง\\nโฮเต็ล\\nโฮลเมียม\\nโฮะ\\nไฮ้\\nไฮโกรมิเตอร์\\nไฮดรา\\nไฮโดร\\nไฮโดรคาร์บอน\\nไฮโดรเจน\\nไฮโดรมิเตอร์\\nไฮไฟ\\nไฮโล\\nไฮฮี\\n\"\n              .split(/[\\r\\n]+/)\n              .filter(function (w) {\n                return w.length > 1;\n              })\n      this.addWords(words, false)\n    }\n    if(finalize){\n      this.finalizeDict();\n    }\n  },\n\n  dictSeek: function (l, r, ch, strOffset, pos) {\n    var ans = null;\n    while (l <= r) {\n      var m = Math.floor((l + r) / 2),\n        dict_item = this.dict[m],\n        len = dict_item.length;\n      if (len <= strOffset) {\n        l = m + 1;\n      } else {\n        var ch_ = dict_item[strOffset];\n        if (ch_ < ch) {\n          l = m + 1;\n        } else if (ch_ > ch) {\n          r = m - 1;\n        } else {\n          ans = m;\n          if (pos == LEFT) {\n            r = m - 1;\n          } else {\n            l = m + 1;\n          }\n        }\n      }\n    }\n    return ans;\n  },\n\n  isFinal: function (acceptor) {\n    return this.dict[acceptor.l].length == acceptor.strOffset;\n  },\n\n  createAcceptor: function () {\n    return {\n      l: 0,\n      r: this.dict.length - 1,\n      strOffset: 0,\n      isFinal: false,\n      dict: this,\n      transit: function (ch) {\n        return this.dict.transit(this, ch);\n      },\n      isError: false,\n      tag: \"DICT\",\n      w: 1,\n      type: \"DICT\"\n    };\n  },\n\n  transit: function (acceptor, ch) {\n    var l = this.dictSeek(acceptor.l,\n      acceptor.r,\n      ch,\n      acceptor.strOffset,\n      LEFT);\n    if (l !== null) {\n      var r = this.dictSeek(l,\n        acceptor.r,\n        ch,\n        acceptor.strOffset,\n        RIGHT);\n      acceptor.l = l;\n      acceptor.r = r;\n      acceptor.strOffset++;\n      acceptor.isFinal = this.isFinal(acceptor);\n    } else {\n      acceptor.isError = true;\n    }\n    return acceptor;\n  },\n\n  sortuniq: function(a){\n    return a.sort().filter(function(item, pos, arr){\n      return !pos || item != arr[pos - 1];\n    })\n  },\n\n  flatten: function(a){\n    //[[1,2],[3]] -> [1,2,3]\n    return [].concat.apply([], a);\n  }\n};\nmodule.exports = WordcutDict;\n\n}).call(this,\"/dist/tmp\")\n},{\"glob\":16,\"path\":22}],3:[function(require,module,exports){\nvar WordRule = {\n  createAcceptor: function(tag) {\n    if (tag[\"WORD_RULE\"])\n      return null;\n\n    return {strOffset: 0,\n            isFinal: false,\n            transit: function(ch) {\n              var lch = ch.toLowerCase();\n              if (lch >= \"a\" && lch <= \"z\") {\n                this.isFinal = true;\n                this.strOffset++;\n              } else {\n                this.isError = true;\n              }\n              return this;\n            },\n            isError: false,\n            tag: \"WORD_RULE\",\n            type: \"WORD_RULE\",\n            w: 1};\n  }\n};\n\nvar NumberRule = {\n  createAcceptor: function(tag) {\n    if (tag[\"NUMBER_RULE\"])\n      return null;\n\n    return {strOffset: 0,\n            isFinal: false,\n            transit: function(ch) {\n              if (ch >= \"0\" && ch <= \"9\") {\n                this.isFinal = true;\n                this.strOffset++;\n              } else {\n                this.isError = true;\n              }\n              return this;\n            },\n            isError: false,\n            tag: \"NUMBER_RULE\",\n            type: \"NUMBER_RULE\",\n            w: 1};\n  }\n};\n\nvar SpaceRule = {\n  tag: \"SPACE_RULE\",\n  createAcceptor: function(tag) {\n\n    if (tag[\"SPACE_RULE\"])\n      return null;\n\n    return {strOffset: 0,\n            isFinal: false,\n            transit: function(ch) {\n              if (ch == \" \" || ch == \"\\t\" || ch == \"\\r\" || ch == \"\\n\" ||\n                  ch == \"\\u00A0\" || ch==\"\\u2003\"//nbsp and emsp\n                 ) {\n                this.isFinal = true;\n                this.strOffset++;\n              } else {\n                this.isError = true;\n              }\n              return this;\n            },\n            isError: false,\n            tag: SpaceRule.tag,\n            w: 1,\n            type: \"SPACE_RULE\"};\n  }\n}\n\nvar SingleSymbolRule = {\n  tag: \"SINSYM\",\n  createAcceptor: function(tag) {\n    return {strOffset: 0,\n            isFinal: false,\n            transit: function(ch) {\n              if (this.strOffset == 0 && ch.match(/^[\\@\\(\\)\\/\\,\\-\\.\"`]$/)) {\n                this.isFinal = true;\n                this.strOffset++;\n              } else {\n                this.isError = true;\n              }\n              return this;\n            },\n            isError: false,\n            tag: \"SINSYM\",\n            w: 1,\n            type: \"SINSYM\"};\n  }\n}\n\n\nvar LatinRules = [WordRule, SpaceRule, SingleSymbolRule, NumberRule];\n\nmodule.exports = LatinRules;\n\n},{}],4:[function(require,module,exports){\nvar _ = require(\"underscore\")\n  , WordcutCore = require(\"./wordcut_core\");\nvar PathInfoBuilder = {\n\n  /*\n    buildByPartAcceptors: function(path, acceptors, i) {\n    var \n    var genInfos = partAcceptors.reduce(function(genInfos, acceptor) {\n      \n    }, []);\n    \n    return genInfos;\n  } \n  */\n\n  buildByAcceptors: function(path, finalAcceptors, i) {\n    var self = this;\n    var infos = finalAcceptors.map(function(acceptor) {\n      var p = i - acceptor.strOffset + 1\n        , _info = path[p];            \n      \n      var info = {p: p, \n                  mw: _info.mw + (acceptor.mw === undefined ? 0 : acceptor.mw),\n                  w: acceptor.w + _info.w,\n                  unk: (acceptor.unk ? acceptor.unk : 0) + _info.unk, \n                  type: acceptor.type};\n\n      if (acceptor.type == \"PART\") {\n        for(var j = p + 1; j <= i; j++) {\n          path[j].merge = p;\n        }\n        info.merge = p;\n      }\n\n      return info;\n    });\n    return infos.filter(function(info) { return info; });\n  },\n  \n  fallback: function(path, leftBoundary, text, i) {\n    var _info = path[leftBoundary];\n    if (text[i].match(/[\\u0E48-\\u0E4E]/)) {\n      if (leftBoundary != 0) \n        leftBoundary = path[leftBoundary].p;\n      return {p: leftBoundary,\n              mw: 0,\n              w: 1 + _info.w,\n              unk: 1 + _info.unk,\n              type: \"UNK\"};      \n/*    } else if(leftBoundary > 0 && path[leftBoundary].type !== \"UNK\") {\n      leftBoundary = path[leftBoundary].p;\n      return {p: leftBoundary,\n              w: 1 + _info.w,\n              unk: 1 + _info.unk,\n              type: \"UNK\"};            */\n    } else {      \n      return {p: leftBoundary,\n              mw: _info.mw,\n              w: 1 + _info.w,\n              unk: 1 + _info.unk,\n              type: \"UNK\"};\n    }\n  },\n  \n  build: function(path, finalAcceptors, i, leftBoundary, text) {\n    var basicPathInfos = this.buildByAcceptors(path, finalAcceptors, i);\n    if (basicPathInfos.length > 0) {\n      return basicPathInfos;\n    } else {\n      return [this.fallback(path, leftBoundary, text, i)];\n    }\n  }\n};\n\nmodule.exports = function() {\n  return _.clone(PathInfoBuilder);\n}\n\n},{\"./wordcut_core\":8,\"underscore\":25}],5:[function(require,module,exports){\nvar _ = require(\"underscore\");\n\n\nvar PathSelector = {\n  selectPath: function(paths) {\n    var path = paths.reduce(function(selectedPath, path) {\n      if (selectedPath == null) {        \n        return path;\n      } else {\n        if (path.unk < selectedPath.unk) \n          return path;        \n        if (path.unk == selectedPath.unk) {\n          if (path.mw < selectedPath.mw)\n            return path\n          if (path.mw == selectedPath.mw) {\n            if (path.w < selectedPath.w) \n              return path;\n          }\n        }\n        return selectedPath;\n      }\n    }, null);\n    return path;\n  },\n  \n  createPath: function() {\n    return [{p:null, w:0, unk:0, type: \"INIT\", mw:0}];\n  }\n};\n\nmodule.exports = function() {\n  return _.clone(PathSelector);\n};\n\n},{\"underscore\":25}],6:[function(require,module,exports){\nfunction isMatch(pat, offset, ch) {\n  if (pat.length <= offset)\n    return false;\n  var _ch = pat[offset];\n  return _ch == ch ||\n         (_ch.match(/[กข]/) && ch.match(/[ก-ฮ]/)) ||\n         (_ch.match(/[มบ]/) && ch.match(/[ก-ฮ]/)) ||\n         (_ch.match(/\\u0E49/) && ch.match(/[\\u0E48-\\u0E4B]/));\n}\n\nvar Rule0 = {\n  pat: \"เหก็ม\",\n  createAcceptor: function(tag) {\n    return {strOffset: 0,\n            isFinal: false,\n            transit: function(ch) {\n              if (isMatch(Rule0.pat, this.strOffset,ch)) {                 \n                this.isFinal = (this.strOffset + 1 == Rule0.pat.length);                \n                this.strOffset++;\n              } else {              \n                this.isError = true;             \n              }\n              return this;\n            },\n            isError: false,\n            tag: \"THAI_RULE\",\n            type: \"THAI_RULE\", \n            w: 1};                        \n  }\n};\n\nvar PartRule = {\n  createAcceptor: function(tag) {\n    return {strOffset: 0,\n            patterns: [\n              \"แก\", \"เก\", \"ก้\", \"กก์\", \"กา\", \"กี\", \"กิ\", \"กืก\"  \n            ],\n            isFinal: false,\n            transit: function(ch) {\n              var offset = this.strOffset;\n              this.patterns = this.patterns.filter(function(pat) {\n                return isMatch(pat, offset, ch);\n              });\n              \n              if (this.patterns.length > 0) {\n                var len = 1 + offset;\n                this.isFinal = this.patterns.some(function(pat) {\n                  return pat.length == len; \n                });\n                this.strOffset++;\n              } else {              \n                this.isError = true;             \n              }\n              return this;\n            },\n            isError: false,\n            tag: \"PART\",\n            type: \"PART\", \n            unk: 1,\n            w: 1};                        \n  }\n};\n\nvar ThaiRules = [Rule0, PartRule];\n\nmodule.exports = ThaiRules;\n\n},{}],7:[function(require,module,exports){\nvar sys = require(\"sys\")\n  , WordcutDict = require(\"./dict\")\n  , WordcutCore = require(\"./wordcut_core\")\n  , PathInfoBuilder = require(\"./path_info_builder\")\n  , PathSelector = require(\"./path_selector\")\n  , Acceptors = require(\"./acceptors\")\n  , latinRules = require(\"./latin_rules\")\n  , thaiRules = require(\"./thai_rules\")\n  , _ = require(\"underscore\");\n\n\nvar Wordcut = Object.create(WordcutCore);\nWordcut.defaultPathInfoBuilder = PathInfoBuilder;\nWordcut.defaultPathSelector = PathSelector;\nWordcut.defaultAcceptors = Acceptors;\nWordcut.defaultLatinRules = latinRules;\nWordcut.defaultThaiRules = thaiRules;\nWordcut.defaultDict = WordcutDict;\n\n\nWordcut.initNoDict = function(dict_path) {\n  var self = this;\n  self.pathInfoBuilder = new self.defaultPathInfoBuilder;\n  self.pathSelector = new self.defaultPathSelector;\n  self.acceptors = new self.defaultAcceptors;\n  self.defaultLatinRules.forEach(function(rule) {\n    self.acceptors.creators.push(rule);\n  });\n  self.defaultThaiRules.forEach(function(rule) {\n    self.acceptors.creators.push(rule);\n  });\n};\n\nWordcut.init = function(dict_path, withDefault, additionalWords) {\n  withDefault = withDefault || false;\n  this.initNoDict();\n  var dict = _.clone(this.defaultDict);\n  dict.init(dict_path, withDefault, additionalWords);\n  this.acceptors.creators.push(dict);\n};\n\nmodule.exports = Wordcut;\n\n},{\"./acceptors\":1,\"./dict\":2,\"./latin_rules\":3,\"./path_info_builder\":4,\"./path_selector\":5,\"./thai_rules\":6,\"./wordcut_core\":8,\"sys\":28,\"underscore\":25}],8:[function(require,module,exports){\nvar WordcutCore = {\n\n  buildPath: function(text) {\n    var self = this\n      , path = self.pathSelector.createPath()\n      , leftBoundary = 0;\n    self.acceptors.reset();\n    for (var i = 0; i < text.length; i++) {\n      var ch = text[i];\n      self.acceptors.transit(ch);\n\n      var possiblePathInfos = self\n        .pathInfoBuilder\n        .build(path,\n               self.acceptors.getFinalAcceptors(),\n               i,\n               leftBoundary,\n               text);\n      var selectedPath = self.pathSelector.selectPath(possiblePathInfos)\n\n      path.push(selectedPath);\n      if (selectedPath.type !== \"UNK\") {\n        leftBoundary = i;\n      }\n    }\n    return path;\n  },\n\n  pathToRanges: function(path) {\n    var e = path.length - 1\n     , ranges = [];\n\n    while (e > 0) {\n      var info = path[e]\n       , s = info.p;\n\n      if (info.merge !== undefined && ranges.length > 0) {\n        var r = ranges[ranges.length - 1];\n        r.s = info.merge;\n        s = r.s;\n      } else {\n        ranges.push({s:s, e:e});\n      }\n      e = s;\n    }\n    return ranges.reverse();\n  },\n\n  rangesToText: function(text, ranges, delimiter) {\n    return ranges.map(function(r) {\n      return text.substring(r.s, r.e);\n    }).join(delimiter);\n  },\n\n  cut: function(text, delimiter) {\n    var path = this.buildPath(text)\n      , ranges = this.pathToRanges(path);\n    return this\n      .rangesToText(text, ranges,\n                    (delimiter === undefined ? \"|\" : delimiter));\n  },\n\n  cutIntoRanges: function(text, noText) {\n    var path = this.buildPath(text)\n      , ranges = this.pathToRanges(path);\n\n    if (!noText) {\n      ranges.forEach(function(r) {\n        r.text = text.substring(r.s, r.e);\n      });\n    }\n    return ranges;\n  },\n\n  cutIntoArray: function(text) {\n    var path = this.buildPath(text)\n      , ranges = this.pathToRanges(path);\n    \n    return ranges.map(function(r) {\n      return text.substring(r.s, r.e)\n    });\n  }\n};\n\nmodule.exports = WordcutCore;\n\n},{}],9:[function(require,module,exports){\n// http://wiki.commonjs.org/wiki/Unit_Testing/1.0\n//\n// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!\n//\n// Originally from narwhal.js (http://narwhaljs.org)\n// Copyright (c) 2009 Thomas Robinson <280north.com>\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the 'Software'), to\n// deal in the Software without restriction, including without limitation the\n// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n// sell copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\n// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// when used in node, this will actually load the util module we depend on\n// versus loading the builtin util module as happens otherwise\n// this is a bug in node module loading as far as I am concerned\nvar util = require('util/');\n\nvar pSlice = Array.prototype.slice;\nvar hasOwn = Object.prototype.hasOwnProperty;\n\n// 1. The assert module provides functions that throw\n// AssertionError's when particular conditions are not met. The\n// assert module must conform to the following interface.\n\nvar assert = module.exports = ok;\n\n// 2. The AssertionError is defined in assert.\n// new assert.AssertionError({ message: message,\n//                             actual: actual,\n//                             expected: expected })\n\nassert.AssertionError = function AssertionError(options) {\n  this.name = 'AssertionError';\n  this.actual = options.actual;\n  this.expected = options.expected;\n  this.operator = options.operator;\n  if (options.message) {\n    this.message = options.message;\n    this.generatedMessage = false;\n  } else {\n    this.message = getMessage(this);\n    this.generatedMessage = true;\n  }\n  var stackStartFunction = options.stackStartFunction || fail;\n\n  if (Error.captureStackTrace) {\n    Error.captureStackTrace(this, stackStartFunction);\n  }\n  else {\n    // non v8 browsers so we can have a stacktrace\n    var err = new Error();\n    if (err.stack) {\n      var out = err.stack;\n\n      // try to strip useless frames\n      var fn_name = stackStartFunction.name;\n      var idx = out.indexOf('\\n' + fn_name);\n      if (idx >= 0) {\n        // once we have located the function frame\n        // we need to strip out everything before it (and its line)\n        var next_line = out.indexOf('\\n', idx + 1);\n        out = out.substring(next_line + 1);\n      }\n\n      this.stack = out;\n    }\n  }\n};\n\n// assert.AssertionError instanceof Error\nutil.inherits(assert.AssertionError, Error);\n\nfunction replacer(key, value) {\n  if (util.isUndefined(value)) {\n    return '' + value;\n  }\n  if (util.isNumber(value) && !isFinite(value)) {\n    return value.toString();\n  }\n  if (util.isFunction(value) || util.isRegExp(value)) {\n    return value.toString();\n  }\n  return value;\n}\n\nfunction truncate(s, n) {\n  if (util.isString(s)) {\n    return s.length < n ? s : s.slice(0, n);\n  } else {\n    return s;\n  }\n}\n\nfunction getMessage(self) {\n  return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' +\n         self.operator + ' ' +\n         truncate(JSON.stringify(self.expected, replacer), 128);\n}\n\n// At present only the three keys mentioned above are used and\n// understood by the spec. Implementations or sub modules can pass\n// other keys to the AssertionError's constructor - they will be\n// ignored.\n\n// 3. All of the following functions must throw an AssertionError\n// when a corresponding condition is not met, with a message that\n// may be undefined if not provided.  All assertion methods provide\n// both the actual and expected values to the assertion error for\n// display purposes.\n\nfunction fail(actual, expected, message, operator, stackStartFunction) {\n  throw new assert.AssertionError({\n    message: message,\n    actual: actual,\n    expected: expected,\n    operator: operator,\n    stackStartFunction: stackStartFunction\n  });\n}\n\n// EXTENSION! allows for well behaved errors defined elsewhere.\nassert.fail = fail;\n\n// 4. Pure assertion tests whether a value is truthy, as determined\n// by !!guard.\n// assert.ok(guard, message_opt);\n// This statement is equivalent to assert.equal(true, !!guard,\n// message_opt);. To test strictly for the value true, use\n// assert.strictEqual(true, guard, message_opt);.\n\nfunction ok(value, message) {\n  if (!value) fail(value, true, message, '==', assert.ok);\n}\nassert.ok = ok;\n\n// 5. The equality assertion tests shallow, coercive equality with\n// ==.\n// assert.equal(actual, expected, message_opt);\n\nassert.equal = function equal(actual, expected, message) {\n  if (actual != expected) fail(actual, expected, message, '==', assert.equal);\n};\n\n// 6. The non-equality assertion tests for whether two objects are not equal\n// with != assert.notEqual(actual, expected, message_opt);\n\nassert.notEqual = function notEqual(actual, expected, message) {\n  if (actual == expected) {\n    fail(actual, expected, message, '!=', assert.notEqual);\n  }\n};\n\n// 7. The equivalence assertion tests a deep equality relation.\n// assert.deepEqual(actual, expected, message_opt);\n\nassert.deepEqual = function deepEqual(actual, expected, message) {\n  if (!_deepEqual(actual, expected)) {\n    fail(actual, expected, message, 'deepEqual', assert.deepEqual);\n  }\n};\n\nfunction _deepEqual(actual, expected) {\n  // 7.1. All identical values are equivalent, as determined by ===.\n  if (actual === expected) {\n    return true;\n\n  } else if (util.isBuffer(actual) && util.isBuffer(expected)) {\n    if (actual.length != expected.length) return false;\n\n    for (var i = 0; i < actual.length; i++) {\n      if (actual[i] !== expected[i]) return false;\n    }\n\n    return true;\n\n  // 7.2. If the expected value is a Date object, the actual value is\n  // equivalent if it is also a Date object that refers to the same time.\n  } else if (util.isDate(actual) && util.isDate(expected)) {\n    return actual.getTime() === expected.getTime();\n\n  // 7.3 If the expected value is a RegExp object, the actual value is\n  // equivalent if it is also a RegExp object with the same source and\n  // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).\n  } else if (util.isRegExp(actual) && util.isRegExp(expected)) {\n    return actual.source === expected.source &&\n           actual.global === expected.global &&\n           actual.multiline === expected.multiline &&\n           actual.lastIndex === expected.lastIndex &&\n           actual.ignoreCase === expected.ignoreCase;\n\n  // 7.4. Other pairs that do not both pass typeof value == 'object',\n  // equivalence is determined by ==.\n  } else if (!util.isObject(actual) && !util.isObject(expected)) {\n    return actual == expected;\n\n  // 7.5 For all other Object pairs, including Array objects, equivalence is\n  // determined by having the same number of owned properties (as verified\n  // with Object.prototype.hasOwnProperty.call), the same set of keys\n  // (although not necessarily the same order), equivalent values for every\n  // corresponding key, and an identical 'prototype' property. Note: this\n  // accounts for both named and indexed properties on Arrays.\n  } else {\n    return objEquiv(actual, expected);\n  }\n}\n\nfunction isArguments(object) {\n  return Object.prototype.toString.call(object) == '[object Arguments]';\n}\n\nfunction objEquiv(a, b) {\n  if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b))\n    return false;\n  // an identical 'prototype' property.\n  if (a.prototype !== b.prototype) return false;\n  // if one is a primitive, the other must be same\n  if (util.isPrimitive(a) || util.isPrimitive(b)) {\n    return a === b;\n  }\n  var aIsArgs = isArguments(a),\n      bIsArgs = isArguments(b);\n  if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))\n    return false;\n  if (aIsArgs) {\n    a = pSlice.call(a);\n    b = pSlice.call(b);\n    return _deepEqual(a, b);\n  }\n  var ka = objectKeys(a),\n      kb = objectKeys(b),\n      key, i;\n  // having the same number of owned properties (keys incorporates\n  // hasOwnProperty)\n  if (ka.length != kb.length)\n    return false;\n  //the same set of keys (although not necessarily the same order),\n  ka.sort();\n  kb.sort();\n  //~~~cheap key test\n  for (i = ka.length - 1; i >= 0; i--) {\n    if (ka[i] != kb[i])\n      return false;\n  }\n  //equivalent values for every corresponding key, and\n  //~~~possibly expensive deep test\n  for (i = ka.length - 1; i >= 0; i--) {\n    key = ka[i];\n    if (!_deepEqual(a[key], b[key])) return false;\n  }\n  return true;\n}\n\n// 8. The non-equivalence assertion tests for any deep inequality.\n// assert.notDeepEqual(actual, expected, message_opt);\n\nassert.notDeepEqual = function notDeepEqual(actual, expected, message) {\n  if (_deepEqual(actual, expected)) {\n    fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);\n  }\n};\n\n// 9. The strict equality assertion tests strict equality, as determined by ===.\n// assert.strictEqual(actual, expected, message_opt);\n\nassert.strictEqual = function strictEqual(actual, expected, message) {\n  if (actual !== expected) {\n    fail(actual, expected, message, '===', assert.strictEqual);\n  }\n};\n\n// 10. The strict non-equality assertion tests for strict inequality, as\n// determined by !==.  assert.notStrictEqual(actual, expected, message_opt);\n\nassert.notStrictEqual = function notStrictEqual(actual, expected, message) {\n  if (actual === expected) {\n    fail(actual, expected, message, '!==', assert.notStrictEqual);\n  }\n};\n\nfunction expectedException(actual, expected) {\n  if (!actual || !expected) {\n    return false;\n  }\n\n  if (Object.prototype.toString.call(expected) == '[object RegExp]') {\n    return expected.test(actual);\n  } else if (actual instanceof expected) {\n    return true;\n  } else if (expected.call({}, actual) === true) {\n    return true;\n  }\n\n  return false;\n}\n\nfunction _throws(shouldThrow, block, expected, message) {\n  var actual;\n\n  if (util.isString(expected)) {\n    message = expected;\n    expected = null;\n  }\n\n  try {\n    block();\n  } catch (e) {\n    actual = e;\n  }\n\n  message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +\n            (message ? ' ' + message : '.');\n\n  if (shouldThrow && !actual) {\n    fail(actual, expected, 'Missing expected exception' + message);\n  }\n\n  if (!shouldThrow && expectedException(actual, expected)) {\n    fail(actual, expected, 'Got unwanted exception' + message);\n  }\n\n  if ((shouldThrow && actual && expected &&\n      !expectedException(actual, expected)) || (!shouldThrow && actual)) {\n    throw actual;\n  }\n}\n\n// 11. Expected to throw an error:\n// assert.throws(block, Error_opt, message_opt);\n\nassert.throws = function(block, /*optional*/error, /*optional*/message) {\n  _throws.apply(this, [true].concat(pSlice.call(arguments)));\n};\n\n// EXTENSION! This is annoying to write outside this module.\nassert.doesNotThrow = function(block, /*optional*/message) {\n  _throws.apply(this, [false].concat(pSlice.call(arguments)));\n};\n\nassert.ifError = function(err) { if (err) {throw err;}};\n\nvar objectKeys = Object.keys || function (obj) {\n  var keys = [];\n  for (var key in obj) {\n    if (hasOwn.call(obj, key)) keys.push(key);\n  }\n  return keys;\n};\n\n},{\"util/\":28}],10:[function(require,module,exports){\n'use strict';\nmodule.exports = balanced;\nfunction balanced(a, b, str) {\n  if (a instanceof RegExp) a = maybeMatch(a, str);\n  if (b instanceof RegExp) b = maybeMatch(b, str);\n\n  var r = range(a, b, str);\n\n  return r && {\n    start: r[0],\n    end: r[1],\n    pre: str.slice(0, r[0]),\n    body: str.slice(r[0] + a.length, r[1]),\n    post: str.slice(r[1] + b.length)\n  };\n}\n\nfunction maybeMatch(reg, str) {\n  var m = str.match(reg);\n  return m ? m[0] : null;\n}\n\nbalanced.range = range;\nfunction range(a, b, str) {\n  var begs, beg, left, right, result;\n  var ai = str.indexOf(a);\n  var bi = str.indexOf(b, ai + 1);\n  var i = ai;\n\n  if (ai >= 0 && bi > 0) {\n    begs = [];\n    left = str.length;\n\n    while (i >= 0 && !result) {\n      if (i == ai) {\n        begs.push(i);\n        ai = str.indexOf(a, i + 1);\n      } else if (begs.length == 1) {\n        result = [ begs.pop(), bi ];\n      } else {\n        beg = begs.pop();\n        if (beg < left) {\n          left = beg;\n          right = bi;\n        }\n\n        bi = str.indexOf(b, i + 1);\n      }\n\n      i = ai < bi && ai >= 0 ? ai : bi;\n    }\n\n    if (begs.length) {\n      result = [ left, right ];\n    }\n  }\n\n  return result;\n}\n\n},{}],11:[function(require,module,exports){\nvar concatMap = require('concat-map');\nvar balanced = require('balanced-match');\n\nmodule.exports = expandTop;\n\nvar escSlash = '\\0SLASH'+Math.random()+'\\0';\nvar escOpen = '\\0OPEN'+Math.random()+'\\0';\nvar escClose = '\\0CLOSE'+Math.random()+'\\0';\nvar escComma = '\\0COMMA'+Math.random()+'\\0';\nvar escPeriod = '\\0PERIOD'+Math.random()+'\\0';\n\nfunction numeric(str) {\n  return parseInt(str, 10) == str\n    ? parseInt(str, 10)\n    : str.charCodeAt(0);\n}\n\nfunction escapeBraces(str) {\n  return str.split('\\\\\\\\').join(escSlash)\n            .split('\\\\{').join(escOpen)\n            .split('\\\\}').join(escClose)\n            .split('\\\\,').join(escComma)\n            .split('\\\\.').join(escPeriod);\n}\n\nfunction unescapeBraces(str) {\n  return str.split(escSlash).join('\\\\')\n            .split(escOpen).join('{')\n            .split(escClose).join('}')\n            .split(escComma).join(',')\n            .split(escPeriod).join('.');\n}\n\n\n// Basically just str.split(\",\"), but handling cases\n// where we have nested braced sections, which should be\n// treated as individual members, like {a,{b,c},d}\nfunction parseCommaParts(str) {\n  if (!str)\n    return [''];\n\n  var parts = [];\n  var m = balanced('{', '}', str);\n\n  if (!m)\n    return str.split(',');\n\n  var pre = m.pre;\n  var body = m.body;\n  var post = m.post;\n  var p = pre.split(',');\n\n  p[p.length-1] += '{' + body + '}';\n  var postParts = parseCommaParts(post);\n  if (post.length) {\n    p[p.length-1] += postParts.shift();\n    p.push.apply(p, postParts);\n  }\n\n  parts.push.apply(parts, p);\n\n  return parts;\n}\n\nfunction expandTop(str) {\n  if (!str)\n    return [];\n\n  // I don't know why Bash 4.3 does this, but it does.\n  // Anything starting with {} will have the first two bytes preserved\n  // but *only* at the top level, so {},a}b will not expand to anything,\n  // but a{},b}c will be expanded to [a}c,abc].\n  // One could argue that this is a bug in Bash, but since the goal of\n  // this module is to match Bash's rules, we escape a leading {}\n  if (str.substr(0, 2) === '{}') {\n    str = '\\\\{\\\\}' + str.substr(2);\n  }\n\n  return expand(escapeBraces(str), true).map(unescapeBraces);\n}\n\nfunction identity(e) {\n  return e;\n}\n\nfunction embrace(str) {\n  return '{' + str + '}';\n}\nfunction isPadded(el) {\n  return /^-?0\\d/.test(el);\n}\n\nfunction lte(i, y) {\n  return i <= y;\n}\nfunction gte(i, y) {\n  return i >= y;\n}\n\nfunction expand(str, isTop) {\n  var expansions = [];\n\n  var m = balanced('{', '}', str);\n  if (!m || /\\$$/.test(m.pre)) return [str];\n\n  var isNumericSequence = /^-?\\d+\\.\\.-?\\d+(?:\\.\\.-?\\d+)?$/.test(m.body);\n  var isAlphaSequence = /^[a-zA-Z]\\.\\.[a-zA-Z](?:\\.\\.-?\\d+)?$/.test(m.body);\n  var isSequence = isNumericSequence || isAlphaSequence;\n  var isOptions = m.body.indexOf(',') >= 0;\n  if (!isSequence && !isOptions) {\n    // {a},b}\n    if (m.post.match(/,.*\\}/)) {\n      str = m.pre + '{' + m.body + escClose + m.post;\n      return expand(str);\n    }\n    return [str];\n  }\n\n  var n;\n  if (isSequence) {\n    n = m.body.split(/\\.\\./);\n  } else {\n    n = parseCommaParts(m.body);\n    if (n.length === 1) {\n      // x{{a,b}}y ==> x{a}y x{b}y\n      n = expand(n[0], false).map(embrace);\n      if (n.length === 1) {\n        var post = m.post.length\n          ? expand(m.post, false)\n          : [''];\n        return post.map(function(p) {\n          return m.pre + n[0] + p;\n        });\n      }\n    }\n  }\n\n  // at this point, n is the parts, and we know it's not a comma set\n  // with a single entry.\n\n  // no need to expand pre, since it is guaranteed to be free of brace-sets\n  var pre = m.pre;\n  var post = m.post.length\n    ? expand(m.post, false)\n    : [''];\n\n  var N;\n\n  if (isSequence) {\n    var x = numeric(n[0]);\n    var y = numeric(n[1]);\n    var width = Math.max(n[0].length, n[1].length)\n    var incr = n.length == 3\n      ? Math.abs(numeric(n[2]))\n      : 1;\n    var test = lte;\n    var reverse = y < x;\n    if (reverse) {\n      incr *= -1;\n      test = gte;\n    }\n    var pad = n.some(isPadded);\n\n    N = [];\n\n    for (var i = x; test(i, y); i += incr) {\n      var c;\n      if (isAlphaSequence) {\n        c = String.fromCharCode(i);\n        if (c === '\\\\')\n          c = '';\n      } else {\n        c = String(i);\n        if (pad) {\n          var need = width - c.length;\n          if (need > 0) {\n            var z = new Array(need + 1).join('0');\n            if (i < 0)\n              c = '-' + z + c.slice(1);\n            else\n              c = z + c;\n          }\n        }\n      }\n      N.push(c);\n    }\n  } else {\n    N = concatMap(n, function(el) { return expand(el, false) });\n  }\n\n  for (var j = 0; j < N.length; j++) {\n    for (var k = 0; k < post.length; k++) {\n      var expansion = pre + N[j] + post[k];\n      if (!isTop || isSequence || expansion)\n        expansions.push(expansion);\n    }\n  }\n\n  return expansions;\n}\n\n\n},{\"balanced-match\":10,\"concat-map\":13}],12:[function(require,module,exports){\n\n},{}],13:[function(require,module,exports){\nmodule.exports = function (xs, fn) {\n    var res = [];\n    for (var i = 0; i < xs.length; i++) {\n        var x = fn(xs[i], i);\n        if (isArray(x)) res.push.apply(res, x);\n        else res.push(x);\n    }\n    return res;\n};\n\nvar isArray = Array.isArray || function (xs) {\n    return Object.prototype.toString.call(xs) === '[object Array]';\n};\n\n},{}],14:[function(require,module,exports){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n  this._events = this._events || {};\n  this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n  if (!isNumber(n) || n < 0 || isNaN(n))\n    throw TypeError('n must be a positive number');\n  this._maxListeners = n;\n  return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n  var er, handler, len, args, i, listeners;\n\n  if (!this._events)\n    this._events = {};\n\n  // If there is no 'error' event listener then throw.\n  if (type === 'error') {\n    if (!this._events.error ||\n        (isObject(this._events.error) && !this._events.error.length)) {\n      er = arguments[1];\n      if (er instanceof Error) {\n        throw er; // Unhandled 'error' event\n      }\n      throw TypeError('Uncaught, unspecified \"error\" event.');\n    }\n  }\n\n  handler = this._events[type];\n\n  if (isUndefined(handler))\n    return false;\n\n  if (isFunction(handler)) {\n    switch (arguments.length) {\n      // fast cases\n      case 1:\n        handler.call(this);\n        break;\n      case 2:\n        handler.call(this, arguments[1]);\n        break;\n      case 3:\n        handler.call(this, arguments[1], arguments[2]);\n        break;\n      // slower\n      default:\n        len = arguments.length;\n        args = new Array(len - 1);\n        for (i = 1; i < len; i++)\n          args[i - 1] = arguments[i];\n        handler.apply(this, args);\n    }\n  } else if (isObject(handler)) {\n    len = arguments.length;\n    args = new Array(len - 1);\n    for (i = 1; i < len; i++)\n      args[i - 1] = arguments[i];\n\n    listeners = handler.slice();\n    len = listeners.length;\n    for (i = 0; i < len; i++)\n      listeners[i].apply(this, args);\n  }\n\n  return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n  var m;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events)\n    this._events = {};\n\n  // To avoid recursion in the case that type === \"newListener\"! Before\n  // adding it to the listeners, first emit \"newListener\".\n  if (this._events.newListener)\n    this.emit('newListener', type,\n              isFunction(listener.listener) ?\n              listener.listener : listener);\n\n  if (!this._events[type])\n    // Optimize the case of one listener. Don't need the extra array object.\n    this._events[type] = listener;\n  else if (isObject(this._events[type]))\n    // If we've already got an array, just append.\n    this._events[type].push(listener);\n  else\n    // Adding the second element, need to change to array.\n    this._events[type] = [this._events[type], listener];\n\n  // Check for listener leak\n  if (isObject(this._events[type]) && !this._events[type].warned) {\n    var m;\n    if (!isUndefined(this._maxListeners)) {\n      m = this._maxListeners;\n    } else {\n      m = EventEmitter.defaultMaxListeners;\n    }\n\n    if (m && m > 0 && this._events[type].length > m) {\n      this._events[type].warned = true;\n      console.error('(node) warning: possible EventEmitter memory ' +\n                    'leak detected. %d listeners added. ' +\n                    'Use emitter.setMaxListeners() to increase limit.',\n                    this._events[type].length);\n      if (typeof console.trace === 'function') {\n        // not supported in IE 10\n        console.trace();\n      }\n    }\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  var fired = false;\n\n  function g() {\n    this.removeListener(type, g);\n\n    if (!fired) {\n      fired = true;\n      listener.apply(this, arguments);\n    }\n  }\n\n  g.listener = listener;\n  this.on(type, g);\n\n  return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n  var list, position, length, i;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events || !this._events[type])\n    return this;\n\n  list = this._events[type];\n  length = list.length;\n  position = -1;\n\n  if (list === listener ||\n      (isFunction(list.listener) && list.listener === listener)) {\n    delete this._events[type];\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n\n  } else if (isObject(list)) {\n    for (i = length; i-- > 0;) {\n      if (list[i] === listener ||\n          (list[i].listener && list[i].listener === listener)) {\n        position = i;\n        break;\n      }\n    }\n\n    if (position < 0)\n      return this;\n\n    if (list.length === 1) {\n      list.length = 0;\n      delete this._events[type];\n    } else {\n      list.splice(position, 1);\n    }\n\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n  var key, listeners;\n\n  if (!this._events)\n    return this;\n\n  // not listening for removeListener, no need to emit\n  if (!this._events.removeListener) {\n    if (arguments.length === 0)\n      this._events = {};\n    else if (this._events[type])\n      delete this._events[type];\n    return this;\n  }\n\n  // emit removeListener for all listeners on all events\n  if (arguments.length === 0) {\n    for (key in this._events) {\n      if (key === 'removeListener') continue;\n      this.removeAllListeners(key);\n    }\n    this.removeAllListeners('removeListener');\n    this._events = {};\n    return this;\n  }\n\n  listeners = this._events[type];\n\n  if (isFunction(listeners)) {\n    this.removeListener(type, listeners);\n  } else {\n    // LIFO order\n    while (listeners.length)\n      this.removeListener(type, listeners[listeners.length - 1]);\n  }\n  delete this._events[type];\n\n  return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n  var ret;\n  if (!this._events || !this._events[type])\n    ret = [];\n  else if (isFunction(this._events[type]))\n    ret = [this._events[type]];\n  else\n    ret = this._events[type].slice();\n  return ret;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n  var ret;\n  if (!emitter._events || !emitter._events[type])\n    ret = 0;\n  else if (isFunction(emitter._events[type]))\n    ret = 1;\n  else\n    ret = emitter._events[type].length;\n  return ret;\n};\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\n\n},{}],15:[function(require,module,exports){\n(function (process){\nexports.alphasort = alphasort\nexports.alphasorti = alphasorti\nexports.setopts = setopts\nexports.ownProp = ownProp\nexports.makeAbs = makeAbs\nexports.finish = finish\nexports.mark = mark\nexports.isIgnored = isIgnored\nexports.childrenIgnored = childrenIgnored\n\nfunction ownProp (obj, field) {\n  return Object.prototype.hasOwnProperty.call(obj, field)\n}\n\nvar path = require(\"path\")\nvar minimatch = require(\"minimatch\")\nvar isAbsolute = require(\"path-is-absolute\")\nvar Minimatch = minimatch.Minimatch\n\nfunction alphasorti (a, b) {\n  return a.toLowerCase().localeCompare(b.toLowerCase())\n}\n\nfunction alphasort (a, b) {\n  return a.localeCompare(b)\n}\n\nfunction setupIgnores (self, options) {\n  self.ignore = options.ignore || []\n\n  if (!Array.isArray(self.ignore))\n    self.ignore = [self.ignore]\n\n  if (self.ignore.length) {\n    self.ignore = self.ignore.map(ignoreMap)\n  }\n}\n\nfunction ignoreMap (pattern) {\n  var gmatcher = null\n  if (pattern.slice(-3) === '/**') {\n    var gpattern = pattern.replace(/(\\/\\*\\*)+$/, '')\n    gmatcher = new Minimatch(gpattern)\n  }\n\n  return {\n    matcher: new Minimatch(pattern),\n    gmatcher: gmatcher\n  }\n}\n\nfunction setopts (self, pattern, options) {\n  if (!options)\n    options = {}\n\n  // base-matching: just use globstar for that.\n  if (options.matchBase && -1 === pattern.indexOf(\"/\")) {\n    if (options.noglobstar) {\n      throw new Error(\"base matching requires globstar\")\n    }\n    pattern = \"**/\" + pattern\n  }\n\n  self.silent = !!options.silent\n  self.pattern = pattern\n  self.strict = options.strict !== false\n  self.realpath = !!options.realpath\n  self.realpathCache = options.realpathCache || Object.create(null)\n  self.follow = !!options.follow\n  self.dot = !!options.dot\n  self.mark = !!options.mark\n  self.nodir = !!options.nodir\n  if (self.nodir)\n    self.mark = true\n  self.sync = !!options.sync\n  self.nounique = !!options.nounique\n  self.nonull = !!options.nonull\n  self.nosort = !!options.nosort\n  self.nocase = !!options.nocase\n  self.stat = !!options.stat\n  self.noprocess = !!options.noprocess\n\n  self.maxLength = options.maxLength || Infinity\n  self.cache = options.cache || Object.create(null)\n  self.statCache = options.statCache || Object.create(null)\n  self.symlinks = options.symlinks || Object.create(null)\n\n  setupIgnores(self, options)\n\n  self.changedCwd = false\n  var cwd = process.cwd()\n  if (!ownProp(options, \"cwd\"))\n    self.cwd = cwd\n  else {\n    self.cwd = options.cwd\n    self.changedCwd = path.resolve(options.cwd) !== cwd\n  }\n\n  self.root = options.root || path.resolve(self.cwd, \"/\")\n  self.root = path.resolve(self.root)\n  if (process.platform === \"win32\")\n    self.root = self.root.replace(/\\\\/g, \"/\")\n\n  self.nomount = !!options.nomount\n\n  // disable comments and negation unless the user explicitly\n  // passes in false as the option.\n  options.nonegate = options.nonegate === false ? false : true\n  options.nocomment = options.nocomment === false ? false : true\n  deprecationWarning(options)\n\n  self.minimatch = new Minimatch(pattern, options)\n  self.options = self.minimatch.options\n}\n\n// TODO(isaacs): remove entirely in v6\n// exported to reset in tests\nexports.deprecationWarned\nfunction deprecationWarning(options) {\n  if (!options.nonegate || !options.nocomment) {\n    if (process.noDeprecation !== true && !exports.deprecationWarned) {\n      var msg = 'glob WARNING: comments and negation will be disabled in v6'\n      if (process.throwDeprecation)\n        throw new Error(msg)\n      else if (process.traceDeprecation)\n        console.trace(msg)\n      else\n        console.error(msg)\n\n      exports.deprecationWarned = true\n    }\n  }\n}\n\nfunction finish (self) {\n  var nou = self.nounique\n  var all = nou ? [] : Object.create(null)\n\n  for (var i = 0, l = self.matches.length; i < l; i ++) {\n    var matches = self.matches[i]\n    if (!matches || Object.keys(matches).length === 0) {\n      if (self.nonull) {\n        // do like the shell, and spit out the literal glob\n        var literal = self.minimatch.globSet[i]\n        if (nou)\n          all.push(literal)\n        else\n          all[literal] = true\n      }\n    } else {\n      // had matches\n      var m = Object.keys(matches)\n      if (nou)\n        all.push.apply(all, m)\n      else\n        m.forEach(function (m) {\n          all[m] = true\n        })\n    }\n  }\n\n  if (!nou)\n    all = Object.keys(all)\n\n  if (!self.nosort)\n    all = all.sort(self.nocase ? alphasorti : alphasort)\n\n  // at *some* point we statted all of these\n  if (self.mark) {\n    for (var i = 0; i < all.length; i++) {\n      all[i] = self._mark(all[i])\n    }\n    if (self.nodir) {\n      all = all.filter(function (e) {\n        return !(/\\/$/.test(e))\n      })\n    }\n  }\n\n  if (self.ignore.length)\n    all = all.filter(function(m) {\n      return !isIgnored(self, m)\n    })\n\n  self.found = all\n}\n\nfunction mark (self, p) {\n  var abs = makeAbs(self, p)\n  var c = self.cache[abs]\n  var m = p\n  if (c) {\n    var isDir = c === 'DIR' || Array.isArray(c)\n    var slash = p.slice(-1) === '/'\n\n    if (isDir && !slash)\n      m += '/'\n    else if (!isDir && slash)\n      m = m.slice(0, -1)\n\n    if (m !== p) {\n      var mabs = makeAbs(self, m)\n      self.statCache[mabs] = self.statCache[abs]\n      self.cache[mabs] = self.cache[abs]\n    }\n  }\n\n  return m\n}\n\n// lotta situps...\nfunction makeAbs (self, f) {\n  var abs = f\n  if (f.charAt(0) === '/') {\n    abs = path.join(self.root, f)\n  } else if (isAbsolute(f) || f === '') {\n    abs = f\n  } else if (self.changedCwd) {\n    abs = path.resolve(self.cwd, f)\n  } else {\n    abs = path.resolve(f)\n  }\n  return abs\n}\n\n\n// Return true, if pattern ends with globstar '**', for the accompanying parent directory.\n// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents\nfunction isIgnored (self, path) {\n  if (!self.ignore.length)\n    return false\n\n  return self.ignore.some(function(item) {\n    return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path))\n  })\n}\n\nfunction childrenIgnored (self, path) {\n  if (!self.ignore.length)\n    return false\n\n  return self.ignore.some(function(item) {\n    return !!(item.gmatcher && item.gmatcher.match(path))\n  })\n}\n\n}).call(this,require('_process'))\n},{\"_process\":24,\"minimatch\":20,\"path\":22,\"path-is-absolute\":23}],16:[function(require,module,exports){\n(function (process){\n// Approach:\n//\n// 1. Get the minimatch set\n// 2. For each pattern in the set, PROCESS(pattern, false)\n// 3. Store matches per-set, then uniq them\n//\n// PROCESS(pattern, inGlobStar)\n// Get the first [n] items from pattern that are all strings\n// Join these together.  This is PREFIX.\n//   If there is no more remaining, then stat(PREFIX) and\n//   add to matches if it succeeds.  END.\n//\n// If inGlobStar and PREFIX is symlink and points to dir\n//   set ENTRIES = []\n// else readdir(PREFIX) as ENTRIES\n//   If fail, END\n//\n// with ENTRIES\n//   If pattern[n] is GLOBSTAR\n//     // handle the case where the globstar match is empty\n//     // by pruning it out, and testing the resulting pattern\n//     PROCESS(pattern[0..n] + pattern[n+1 .. $], false)\n//     // handle other cases.\n//     for ENTRY in ENTRIES (not dotfiles)\n//       // attach globstar + tail onto the entry\n//       // Mark that this entry is a globstar match\n//       PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true)\n//\n//   else // not globstar\n//     for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)\n//       Test ENTRY against pattern[n]\n//       If fails, continue\n//       If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])\n//\n// Caveat:\n//   Cache all stats and readdirs results to minimize syscall.  Since all\n//   we ever care about is existence and directory-ness, we can just keep\n//   `true` for files, and [children,...] for directories, or `false` for\n//   things that don't exist.\n\nmodule.exports = glob\n\nvar fs = require('fs')\nvar minimatch = require('minimatch')\nvar Minimatch = minimatch.Minimatch\nvar inherits = require('inherits')\nvar EE = require('events').EventEmitter\nvar path = require('path')\nvar assert = require('assert')\nvar isAbsolute = require('path-is-absolute')\nvar globSync = require('./sync.js')\nvar common = require('./common.js')\nvar alphasort = common.alphasort\nvar alphasorti = common.alphasorti\nvar setopts = common.setopts\nvar ownProp = common.ownProp\nvar inflight = require('inflight')\nvar util = require('util')\nvar childrenIgnored = common.childrenIgnored\nvar isIgnored = common.isIgnored\n\nvar once = require('once')\n\nfunction glob (pattern, options, cb) {\n  if (typeof options === 'function') cb = options, options = {}\n  if (!options) options = {}\n\n  if (options.sync) {\n    if (cb)\n      throw new TypeError('callback provided to sync glob')\n    return globSync(pattern, options)\n  }\n\n  return new Glob(pattern, options, cb)\n}\n\nglob.sync = globSync\nvar GlobSync = glob.GlobSync = globSync.GlobSync\n\n// old api surface\nglob.glob = glob\n\nglob.hasMagic = function (pattern, options_) {\n  var options = util._extend({}, options_)\n  options.noprocess = true\n\n  var g = new Glob(pattern, options)\n  var set = g.minimatch.set\n  if (set.length > 1)\n    return true\n\n  for (var j = 0; j < set[0].length; j++) {\n    if (typeof set[0][j] !== 'string')\n      return true\n  }\n\n  return false\n}\n\nglob.Glob = Glob\ninherits(Glob, EE)\nfunction Glob (pattern, options, cb) {\n  if (typeof options === 'function') {\n    cb = options\n    options = null\n  }\n\n  if (options && options.sync) {\n    if (cb)\n      throw new TypeError('callback provided to sync glob')\n    return new GlobSync(pattern, options)\n  }\n\n  if (!(this instanceof Glob))\n    return new Glob(pattern, options, cb)\n\n  setopts(this, pattern, options)\n  this._didRealPath = false\n\n  // process each pattern in the minimatch set\n  var n = this.minimatch.set.length\n\n  // The matches are stored as {<filename>: true,...} so that\n  // duplicates are automagically pruned.\n  // Later, we do an Object.keys() on these.\n  // Keep them as a list so we can fill in when nonull is set.\n  this.matches = new Array(n)\n\n  if (typeof cb === 'function') {\n    cb = once(cb)\n    this.on('error', cb)\n    this.on('end', function (matches) {\n      cb(null, matches)\n    })\n  }\n\n  var self = this\n  var n = this.minimatch.set.length\n  this._processing = 0\n  this.matches = new Array(n)\n\n  this._emitQueue = []\n  this._processQueue = []\n  this.paused = false\n\n  if (this.noprocess)\n    return this\n\n  if (n === 0)\n    return done()\n\n  for (var i = 0; i < n; i ++) {\n    this._process(this.minimatch.set[i], i, false, done)\n  }\n\n  function done () {\n    --self._processing\n    if (self._processing <= 0)\n      self._finish()\n  }\n}\n\nGlob.prototype._finish = function () {\n  assert(this instanceof Glob)\n  if (this.aborted)\n    return\n\n  if (this.realpath && !this._didRealpath)\n    return this._realpath()\n\n  common.finish(this)\n  this.emit('end', this.found)\n}\n\nGlob.prototype._realpath = function () {\n  if (this._didRealpath)\n    return\n\n  this._didRealpath = true\n\n  var n = this.matches.length\n  if (n === 0)\n    return this._finish()\n\n  var self = this\n  for (var i = 0; i < this.matches.length; i++)\n    this._realpathSet(i, next)\n\n  function next () {\n    if (--n === 0)\n      self._finish()\n  }\n}\n\nGlob.prototype._realpathSet = function (index, cb) {\n  var matchset = this.matches[index]\n  if (!matchset)\n    return cb()\n\n  var found = Object.keys(matchset)\n  var self = this\n  var n = found.length\n\n  if (n === 0)\n    return cb()\n\n  var set = this.matches[index] = Object.create(null)\n  found.forEach(function (p, i) {\n    // If there's a problem with the stat, then it means that\n    // one or more of the links in the realpath couldn't be\n    // resolved.  just return the abs value in that case.\n    p = self._makeAbs(p)\n    fs.realpath(p, self.realpathCache, function (er, real) {\n      if (!er)\n        set[real] = true\n      else if (er.syscall === 'stat')\n        set[p] = true\n      else\n        self.emit('error', er) // srsly wtf right here\n\n      if (--n === 0) {\n        self.matches[index] = set\n        cb()\n      }\n    })\n  })\n}\n\nGlob.prototype._mark = function (p) {\n  return common.mark(this, p)\n}\n\nGlob.prototype._makeAbs = function (f) {\n  return common.makeAbs(this, f)\n}\n\nGlob.prototype.abort = function () {\n  this.aborted = true\n  this.emit('abort')\n}\n\nGlob.prototype.pause = function () {\n  if (!this.paused) {\n    this.paused = true\n    this.emit('pause')\n  }\n}\n\nGlob.prototype.resume = function () {\n  if (this.paused) {\n    this.emit('resume')\n    this.paused = false\n    if (this._emitQueue.length) {\n      var eq = this._emitQueue.slice(0)\n      this._emitQueue.length = 0\n      for (var i = 0; i < eq.length; i ++) {\n        var e = eq[i]\n        this._emitMatch(e[0], e[1])\n      }\n    }\n    if (this._processQueue.length) {\n      var pq = this._processQueue.slice(0)\n      this._processQueue.length = 0\n      for (var i = 0; i < pq.length; i ++) {\n        var p = pq[i]\n        this._processing--\n        this._process(p[0], p[1], p[2], p[3])\n      }\n    }\n  }\n}\n\nGlob.prototype._process = function (pattern, index, inGlobStar, cb) {\n  assert(this instanceof Glob)\n  assert(typeof cb === 'function')\n\n  if (this.aborted)\n    return\n\n  this._processing++\n  if (this.paused) {\n    this._processQueue.push([pattern, index, inGlobStar, cb])\n    return\n  }\n\n  //console.error('PROCESS %d', this._processing, pattern)\n\n  // Get the first [n] parts of pattern that are all strings.\n  var n = 0\n  while (typeof pattern[n] === 'string') {\n    n ++\n  }\n  // now n is the index of the first one that is *not* a string.\n\n  // see if there's anything else\n  var prefix\n  switch (n) {\n    // if not, then this is rather simple\n    case pattern.length:\n      this._processSimple(pattern.join('/'), index, cb)\n      return\n\n    case 0:\n      // pattern *starts* with some non-trivial item.\n      // going to readdir(cwd), but not include the prefix in matches.\n      prefix = null\n      break\n\n    default:\n      // pattern has some string bits in the front.\n      // whatever it starts with, whether that's 'absolute' like /foo/bar,\n      // or 'relative' like '../baz'\n      prefix = pattern.slice(0, n).join('/')\n      break\n  }\n\n  var remain = pattern.slice(n)\n\n  // get the list of entries.\n  var read\n  if (prefix === null)\n    read = '.'\n  else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) {\n    if (!prefix || !isAbsolute(prefix))\n      prefix = '/' + prefix\n    read = prefix\n  } else\n    read = prefix\n\n  var abs = this._makeAbs(read)\n\n  //if ignored, skip _processing\n  if (childrenIgnored(this, read))\n    return cb()\n\n  var isGlobStar = remain[0] === minimatch.GLOBSTAR\n  if (isGlobStar)\n    this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb)\n  else\n    this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb)\n}\n\nGlob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) {\n  var self = this\n  this._readdir(abs, inGlobStar, function (er, entries) {\n    return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb)\n  })\n}\n\nGlob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) {\n\n  // if the abs isn't a dir, then nothing can match!\n  if (!entries)\n    return cb()\n\n  // It will only match dot entries if it starts with a dot, or if\n  // dot is set.  Stuff like @(.foo|.bar) isn't allowed.\n  var pn = remain[0]\n  var negate = !!this.minimatch.negate\n  var rawGlob = pn._glob\n  var dotOk = this.dot || rawGlob.charAt(0) === '.'\n\n  var matchedEntries = []\n  for (var i = 0; i < entries.length; i++) {\n    var e = entries[i]\n    if (e.charAt(0) !== '.' || dotOk) {\n      var m\n      if (negate && !prefix) {\n        m = !e.match(pn)\n      } else {\n        m = e.match(pn)\n      }\n      if (m)\n        matchedEntries.push(e)\n    }\n  }\n\n  //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries)\n\n  var len = matchedEntries.length\n  // If there are no matched entries, then nothing matches.\n  if (len === 0)\n    return cb()\n\n  // if this is the last remaining pattern bit, then no need for\n  // an additional stat *unless* the user has specified mark or\n  // stat explicitly.  We know they exist, since readdir returned\n  // them.\n\n  if (remain.length === 1 && !this.mark && !this.stat) {\n    if (!this.matches[index])\n      this.matches[index] = Object.create(null)\n\n    for (var i = 0; i < len; i ++) {\n      var e = matchedEntries[i]\n      if (prefix) {\n        if (prefix !== '/')\n          e = prefix + '/' + e\n        else\n          e = prefix + e\n      }\n\n      if (e.charAt(0) === '/' && !this.nomount) {\n        e = path.join(this.root, e)\n      }\n      this._emitMatch(index, e)\n    }\n    // This was the last one, and no stats were needed\n    return cb()\n  }\n\n  // now test all matched entries as stand-ins for that part\n  // of the pattern.\n  remain.shift()\n  for (var i = 0; i < len; i ++) {\n    var e = matchedEntries[i]\n    var newPattern\n    if (prefix) {\n      if (prefix !== '/')\n        e = prefix + '/' + e\n      else\n        e = prefix + e\n    }\n    this._process([e].concat(remain), index, inGlobStar, cb)\n  }\n  cb()\n}\n\nGlob.prototype._emitMatch = function (index, e) {\n  if (this.aborted)\n    return\n\n  if (this.matches[index][e])\n    return\n\n  if (isIgnored(this, e))\n    return\n\n  if (this.paused) {\n    this._emitQueue.push([index, e])\n    return\n  }\n\n  var abs = this._makeAbs(e)\n\n  if (this.nodir) {\n    var c = this.cache[abs]\n    if (c === 'DIR' || Array.isArray(c))\n      return\n  }\n\n  if (this.mark)\n    e = this._mark(e)\n\n  this.matches[index][e] = true\n\n  var st = this.statCache[abs]\n  if (st)\n    this.emit('stat', e, st)\n\n  this.emit('match', e)\n}\n\nGlob.prototype._readdirInGlobStar = function (abs, cb) {\n  if (this.aborted)\n    return\n\n  // follow all symlinked directories forever\n  // just proceed as if this is a non-globstar situation\n  if (this.follow)\n    return this._readdir(abs, false, cb)\n\n  var lstatkey = 'lstat\\0' + abs\n  var self = this\n  var lstatcb = inflight(lstatkey, lstatcb_)\n\n  if (lstatcb)\n    fs.lstat(abs, lstatcb)\n\n  function lstatcb_ (er, lstat) {\n    if (er)\n      return cb()\n\n    var isSym = lstat.isSymbolicLink()\n    self.symlinks[abs] = isSym\n\n    // If it's not a symlink or a dir, then it's definitely a regular file.\n    // don't bother doing a readdir in that case.\n    if (!isSym && !lstat.isDirectory()) {\n      self.cache[abs] = 'FILE'\n      cb()\n    } else\n      self._readdir(abs, false, cb)\n  }\n}\n\nGlob.prototype._readdir = function (abs, inGlobStar, cb) {\n  if (this.aborted)\n    return\n\n  cb = inflight('readdir\\0'+abs+'\\0'+inGlobStar, cb)\n  if (!cb)\n    return\n\n  //console.error('RD %j %j', +inGlobStar, abs)\n  if (inGlobStar && !ownProp(this.symlinks, abs))\n    return this._readdirInGlobStar(abs, cb)\n\n  if (ownProp(this.cache, abs)) {\n    var c = this.cache[abs]\n    if (!c || c === 'FILE')\n      return cb()\n\n    if (Array.isArray(c))\n      return cb(null, c)\n  }\n\n  var self = this\n  fs.readdir(abs, readdirCb(this, abs, cb))\n}\n\nfunction readdirCb (self, abs, cb) {\n  return function (er, entries) {\n    if (er)\n      self._readdirError(abs, er, cb)\n    else\n      self._readdirEntries(abs, entries, cb)\n  }\n}\n\nGlob.prototype._readdirEntries = function (abs, entries, cb) {\n  if (this.aborted)\n    return\n\n  // if we haven't asked to stat everything, then just\n  // assume that everything in there exists, so we can avoid\n  // having to stat it a second time.\n  if (!this.mark && !this.stat) {\n    for (var i = 0; i < entries.length; i ++) {\n      var e = entries[i]\n      if (abs === '/')\n        e = abs + e\n      else\n        e = abs + '/' + e\n      this.cache[e] = true\n    }\n  }\n\n  this.cache[abs] = entries\n  return cb(null, entries)\n}\n\nGlob.prototype._readdirError = function (f, er, cb) {\n  if (this.aborted)\n    return\n\n  // handle errors, and cache the information\n  switch (er.code) {\n    case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205\n    case 'ENOTDIR': // totally normal. means it *does* exist.\n      this.cache[this._makeAbs(f)] = 'FILE'\n      break\n\n    case 'ENOENT': // not terribly unusual\n    case 'ELOOP':\n    case 'ENAMETOOLONG':\n    case 'UNKNOWN':\n      this.cache[this._makeAbs(f)] = false\n      break\n\n    default: // some unusual error.  Treat as failure.\n      this.cache[this._makeAbs(f)] = false\n      if (this.strict) {\n        this.emit('error', er)\n        // If the error is handled, then we abort\n        // if not, we threw out of here\n        this.abort()\n      }\n      if (!this.silent)\n        console.error('glob error', er)\n      break\n  }\n\n  return cb()\n}\n\nGlob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) {\n  var self = this\n  this._readdir(abs, inGlobStar, function (er, entries) {\n    self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb)\n  })\n}\n\n\nGlob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) {\n  //console.error('pgs2', prefix, remain[0], entries)\n\n  // no entries means not a dir, so it can never have matches\n  // foo.txt/** doesn't match foo.txt\n  if (!entries)\n    return cb()\n\n  // test without the globstar, and with every child both below\n  // and replacing the globstar.\n  var remainWithoutGlobStar = remain.slice(1)\n  var gspref = prefix ? [ prefix ] : []\n  var noGlobStar = gspref.concat(remainWithoutGlobStar)\n\n  // the noGlobStar pattern exits the inGlobStar state\n  this._process(noGlobStar, index, false, cb)\n\n  var isSym = this.symlinks[abs]\n  var len = entries.length\n\n  // If it's a symlink, and we're in a globstar, then stop\n  if (isSym && inGlobStar)\n    return cb()\n\n  for (var i = 0; i < len; i++) {\n    var e = entries[i]\n    if (e.charAt(0) === '.' && !this.dot)\n      continue\n\n    // these two cases enter the inGlobStar state\n    var instead = gspref.concat(entries[i], remainWithoutGlobStar)\n    this._process(instead, index, true, cb)\n\n    var below = gspref.concat(entries[i], remain)\n    this._process(below, index, true, cb)\n  }\n\n  cb()\n}\n\nGlob.prototype._processSimple = function (prefix, index, cb) {\n  // XXX review this.  Shouldn't it be doing the mounting etc\n  // before doing stat?  kinda weird?\n  var self = this\n  this._stat(prefix, function (er, exists) {\n    self._processSimple2(prefix, index, er, exists, cb)\n  })\n}\nGlob.prototype._processSimple2 = function (prefix, index, er, exists, cb) {\n\n  //console.error('ps2', prefix, exists)\n\n  if (!this.matches[index])\n    this.matches[index] = Object.create(null)\n\n  // If it doesn't exist, then just mark the lack of results\n  if (!exists)\n    return cb()\n\n  if (prefix && isAbsolute(prefix) && !this.nomount) {\n    var trail = /[\\/\\\\]$/.test(prefix)\n    if (prefix.charAt(0) === '/') {\n      prefix = path.join(this.root, prefix)\n    } else {\n      prefix = path.resolve(this.root, prefix)\n      if (trail)\n        prefix += '/'\n    }\n  }\n\n  if (process.platform === 'win32')\n    prefix = prefix.replace(/\\\\/g, '/')\n\n  // Mark this as a match\n  this._emitMatch(index, prefix)\n  cb()\n}\n\n// Returns either 'DIR', 'FILE', or false\nGlob.prototype._stat = function (f, cb) {\n  var abs = this._makeAbs(f)\n  var needDir = f.slice(-1) === '/'\n\n  if (f.length > this.maxLength)\n    return cb()\n\n  if (!this.stat && ownProp(this.cache, abs)) {\n    var c = this.cache[abs]\n\n    if (Array.isArray(c))\n      c = 'DIR'\n\n    // It exists, but maybe not how we need it\n    if (!needDir || c === 'DIR')\n      return cb(null, c)\n\n    if (needDir && c === 'FILE')\n      return cb()\n\n    // otherwise we have to stat, because maybe c=true\n    // if we know it exists, but not what it is.\n  }\n\n  var exists\n  var stat = this.statCache[abs]\n  if (stat !== undefined) {\n    if (stat === false)\n      return cb(null, stat)\n    else {\n      var type = stat.isDirectory() ? 'DIR' : 'FILE'\n      if (needDir && type === 'FILE')\n        return cb()\n      else\n        return cb(null, type, stat)\n    }\n  }\n\n  var self = this\n  var statcb = inflight('stat\\0' + abs, lstatcb_)\n  if (statcb)\n    fs.lstat(abs, statcb)\n\n  function lstatcb_ (er, lstat) {\n    if (lstat && lstat.isSymbolicLink()) {\n      // If it's a symlink, then treat it as the target, unless\n      // the target does not exist, then treat it as a file.\n      return fs.stat(abs, function (er, stat) {\n        if (er)\n          self._stat2(f, abs, null, lstat, cb)\n        else\n          self._stat2(f, abs, er, stat, cb)\n      })\n    } else {\n      self._stat2(f, abs, er, lstat, cb)\n    }\n  }\n}\n\nGlob.prototype._stat2 = function (f, abs, er, stat, cb) {\n  if (er) {\n    this.statCache[abs] = false\n    return cb()\n  }\n\n  var needDir = f.slice(-1) === '/'\n  this.statCache[abs] = stat\n\n  if (abs.slice(-1) === '/' && !stat.isDirectory())\n    return cb(null, false, stat)\n\n  var c = stat.isDirectory() ? 'DIR' : 'FILE'\n  this.cache[abs] = this.cache[abs] || c\n\n  if (needDir && c !== 'DIR')\n    return cb()\n\n  return cb(null, c, stat)\n}\n\n}).call(this,require('_process'))\n},{\"./common.js\":15,\"./sync.js\":17,\"_process\":24,\"assert\":9,\"events\":14,\"fs\":12,\"inflight\":18,\"inherits\":19,\"minimatch\":20,\"once\":21,\"path\":22,\"path-is-absolute\":23,\"util\":28}],17:[function(require,module,exports){\n(function (process){\nmodule.exports = globSync\nglobSync.GlobSync = GlobSync\n\nvar fs = require('fs')\nvar minimatch = require('minimatch')\nvar Minimatch = minimatch.Minimatch\nvar Glob = require('./glob.js').Glob\nvar util = require('util')\nvar path = require('path')\nvar assert = require('assert')\nvar isAbsolute = require('path-is-absolute')\nvar common = require('./common.js')\nvar alphasort = common.alphasort\nvar alphasorti = common.alphasorti\nvar setopts = common.setopts\nvar ownProp = common.ownProp\nvar childrenIgnored = common.childrenIgnored\n\nfunction globSync (pattern, options) {\n  if (typeof options === 'function' || arguments.length === 3)\n    throw new TypeError('callback provided to sync glob\\n'+\n                        'See: https://github.com/isaacs/node-glob/issues/167')\n\n  return new GlobSync(pattern, options).found\n}\n\nfunction GlobSync (pattern, options) {\n  if (!pattern)\n    throw new Error('must provide pattern')\n\n  if (typeof options === 'function' || arguments.length === 3)\n    throw new TypeError('callback provided to sync glob\\n'+\n                        'See: https://github.com/isaacs/node-glob/issues/167')\n\n  if (!(this instanceof GlobSync))\n    return new GlobSync(pattern, options)\n\n  setopts(this, pattern, options)\n\n  if (this.noprocess)\n    return this\n\n  var n = this.minimatch.set.length\n  this.matches = new Array(n)\n  for (var i = 0; i < n; i ++) {\n    this._process(this.minimatch.set[i], i, false)\n  }\n  this._finish()\n}\n\nGlobSync.prototype._finish = function () {\n  assert(this instanceof GlobSync)\n  if (this.realpath) {\n    var self = this\n    this.matches.forEach(function (matchset, index) {\n      var set = self.matches[index] = Object.create(null)\n      for (var p in matchset) {\n        try {\n          p = self._makeAbs(p)\n          var real = fs.realpathSync(p, self.realpathCache)\n          set[real] = true\n        } catch (er) {\n          if (er.syscall === 'stat')\n            set[self._makeAbs(p)] = true\n          else\n            throw er\n        }\n      }\n    })\n  }\n  common.finish(this)\n}\n\n\nGlobSync.prototype._process = function (pattern, index, inGlobStar) {\n  assert(this instanceof GlobSync)\n\n  // Get the first [n] parts of pattern that are all strings.\n  var n = 0\n  while (typeof pattern[n] === 'string') {\n    n ++\n  }\n  // now n is the index of the first one that is *not* a string.\n\n  // See if there's anything else\n  var prefix\n  switch (n) {\n    // if not, then this is rather simple\n    case pattern.length:\n      this._processSimple(pattern.join('/'), index)\n      return\n\n    case 0:\n      // pattern *starts* with some non-trivial item.\n      // going to readdir(cwd), but not include the prefix in matches.\n      prefix = null\n      break\n\n    default:\n      // pattern has some string bits in the front.\n      // whatever it starts with, whether that's 'absolute' like /foo/bar,\n      // or 'relative' like '../baz'\n      prefix = pattern.slice(0, n).join('/')\n      break\n  }\n\n  var remain = pattern.slice(n)\n\n  // get the list of entries.\n  var read\n  if (prefix === null)\n    read = '.'\n  else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) {\n    if (!prefix || !isAbsolute(prefix))\n      prefix = '/' + prefix\n    read = prefix\n  } else\n    read = prefix\n\n  var abs = this._makeAbs(read)\n\n  //if ignored, skip processing\n  if (childrenIgnored(this, read))\n    return\n\n  var isGlobStar = remain[0] === minimatch.GLOBSTAR\n  if (isGlobStar)\n    this._processGlobStar(prefix, read, abs, remain, index, inGlobStar)\n  else\n    this._processReaddir(prefix, read, abs, remain, index, inGlobStar)\n}\n\n\nGlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) {\n  var entries = this._readdir(abs, inGlobStar)\n\n  // if the abs isn't a dir, then nothing can match!\n  if (!entries)\n    return\n\n  // It will only match dot entries if it starts with a dot, or if\n  // dot is set.  Stuff like @(.foo|.bar) isn't allowed.\n  var pn = remain[0]\n  var negate = !!this.minimatch.negate\n  var rawGlob = pn._glob\n  var dotOk = this.dot || rawGlob.charAt(0) === '.'\n\n  var matchedEntries = []\n  for (var i = 0; i < entries.length; i++) {\n    var e = entries[i]\n    if (e.charAt(0) !== '.' || dotOk) {\n      var m\n      if (negate && !prefix) {\n        m = !e.match(pn)\n      } else {\n        m = e.match(pn)\n      }\n      if (m)\n        matchedEntries.push(e)\n    }\n  }\n\n  var len = matchedEntries.length\n  // If there are no matched entries, then nothing matches.\n  if (len === 0)\n    return\n\n  // if this is the last remaining pattern bit, then no need for\n  // an additional stat *unless* the user has specified mark or\n  // stat explicitly.  We know they exist, since readdir returned\n  // them.\n\n  if (remain.length === 1 && !this.mark && !this.stat) {\n    if (!this.matches[index])\n      this.matches[index] = Object.create(null)\n\n    for (var i = 0; i < len; i ++) {\n      var e = matchedEntries[i]\n      if (prefix) {\n        if (prefix.slice(-1) !== '/')\n          e = prefix + '/' + e\n        else\n          e = prefix + e\n      }\n\n      if (e.charAt(0) === '/' && !this.nomount) {\n        e = path.join(this.root, e)\n      }\n      this.matches[index][e] = true\n    }\n    // This was the last one, and no stats were needed\n    return\n  }\n\n  // now test all matched entries as stand-ins for that part\n  // of the pattern.\n  remain.shift()\n  for (var i = 0; i < len; i ++) {\n    var e = matchedEntries[i]\n    var newPattern\n    if (prefix)\n      newPattern = [prefix, e]\n    else\n      newPattern = [e]\n    this._process(newPattern.concat(remain), index, inGlobStar)\n  }\n}\n\n\nGlobSync.prototype._emitMatch = function (index, e) {\n  var abs = this._makeAbs(e)\n  if (this.mark)\n    e = this._mark(e)\n\n  if (this.matches[index][e])\n    return\n\n  if (this.nodir) {\n    var c = this.cache[this._makeAbs(e)]\n    if (c === 'DIR' || Array.isArray(c))\n      return\n  }\n\n  this.matches[index][e] = true\n  if (this.stat)\n    this._stat(e)\n}\n\n\nGlobSync.prototype._readdirInGlobStar = function (abs) {\n  // follow all symlinked directories forever\n  // just proceed as if this is a non-globstar situation\n  if (this.follow)\n    return this._readdir(abs, false)\n\n  var entries\n  var lstat\n  var stat\n  try {\n    lstat = fs.lstatSync(abs)\n  } catch (er) {\n    // lstat failed, doesn't exist\n    return null\n  }\n\n  var isSym = lstat.isSymbolicLink()\n  this.symlinks[abs] = isSym\n\n  // If it's not a symlink or a dir, then it's definitely a regular file.\n  // don't bother doing a readdir in that case.\n  if (!isSym && !lstat.isDirectory())\n    this.cache[abs] = 'FILE'\n  else\n    entries = this._readdir(abs, false)\n\n  return entries\n}\n\nGlobSync.prototype._readdir = function (abs, inGlobStar) {\n  var entries\n\n  if (inGlobStar && !ownProp(this.symlinks, abs))\n    return this._readdirInGlobStar(abs)\n\n  if (ownProp(this.cache, abs)) {\n    var c = this.cache[abs]\n    if (!c || c === 'FILE')\n      return null\n\n    if (Array.isArray(c))\n      return c\n  }\n\n  try {\n    return this._readdirEntries(abs, fs.readdirSync(abs))\n  } catch (er) {\n    this._readdirError(abs, er)\n    return null\n  }\n}\n\nGlobSync.prototype._readdirEntries = function (abs, entries) {\n  // if we haven't asked to stat everything, then just\n  // assume that everything in there exists, so we can avoid\n  // having to stat it a second time.\n  if (!this.mark && !this.stat) {\n    for (var i = 0; i < entries.length; i ++) {\n      var e = entries[i]\n      if (abs === '/')\n        e = abs + e\n      else\n        e = abs + '/' + e\n      this.cache[e] = true\n    }\n  }\n\n  this.cache[abs] = entries\n\n  // mark and cache dir-ness\n  return entries\n}\n\nGlobSync.prototype._readdirError = function (f, er) {\n  // handle errors, and cache the information\n  switch (er.code) {\n    case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205\n    case 'ENOTDIR': // totally normal. means it *does* exist.\n      this.cache[this._makeAbs(f)] = 'FILE'\n      break\n\n    case 'ENOENT': // not terribly unusual\n    case 'ELOOP':\n    case 'ENAMETOOLONG':\n    case 'UNKNOWN':\n      this.cache[this._makeAbs(f)] = false\n      break\n\n    default: // some unusual error.  Treat as failure.\n      this.cache[this._makeAbs(f)] = false\n      if (this.strict)\n        throw er\n      if (!this.silent)\n        console.error('glob error', er)\n      break\n  }\n}\n\nGlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) {\n\n  var entries = this._readdir(abs, inGlobStar)\n\n  // no entries means not a dir, so it can never have matches\n  // foo.txt/** doesn't match foo.txt\n  if (!entries)\n    return\n\n  // test without the globstar, and with every child both below\n  // and replacing the globstar.\n  var remainWithoutGlobStar = remain.slice(1)\n  var gspref = prefix ? [ prefix ] : []\n  var noGlobStar = gspref.concat(remainWithoutGlobStar)\n\n  // the noGlobStar pattern exits the inGlobStar state\n  this._process(noGlobStar, index, false)\n\n  var len = entries.length\n  var isSym = this.symlinks[abs]\n\n  // If it's a symlink, and we're in a globstar, then stop\n  if (isSym && inGlobStar)\n    return\n\n  for (var i = 0; i < len; i++) {\n    var e = entries[i]\n    if (e.charAt(0) === '.' && !this.dot)\n      continue\n\n    // these two cases enter the inGlobStar state\n    var instead = gspref.concat(entries[i], remainWithoutGlobStar)\n    this._process(instead, index, true)\n\n    var below = gspref.concat(entries[i], remain)\n    this._process(below, index, true)\n  }\n}\n\nGlobSync.prototype._processSimple = function (prefix, index) {\n  // XXX review this.  Shouldn't it be doing the mounting etc\n  // before doing stat?  kinda weird?\n  var exists = this._stat(prefix)\n\n  if (!this.matches[index])\n    this.matches[index] = Object.create(null)\n\n  // If it doesn't exist, then just mark the lack of results\n  if (!exists)\n    return\n\n  if (prefix && isAbsolute(prefix) && !this.nomount) {\n    var trail = /[\\/\\\\]$/.test(prefix)\n    if (prefix.charAt(0) === '/') {\n      prefix = path.join(this.root, prefix)\n    } else {\n      prefix = path.resolve(this.root, prefix)\n      if (trail)\n        prefix += '/'\n    }\n  }\n\n  if (process.platform === 'win32')\n    prefix = prefix.replace(/\\\\/g, '/')\n\n  // Mark this as a match\n  this.matches[index][prefix] = true\n}\n\n// Returns either 'DIR', 'FILE', or false\nGlobSync.prototype._stat = function (f) {\n  var abs = this._makeAbs(f)\n  var needDir = f.slice(-1) === '/'\n\n  if (f.length > this.maxLength)\n    return false\n\n  if (!this.stat && ownProp(this.cache, abs)) {\n    var c = this.cache[abs]\n\n    if (Array.isArray(c))\n      c = 'DIR'\n\n    // It exists, but maybe not how we need it\n    if (!needDir || c === 'DIR')\n      return c\n\n    if (needDir && c === 'FILE')\n      return false\n\n    // otherwise we have to stat, because maybe c=true\n    // if we know it exists, but not what it is.\n  }\n\n  var exists\n  var stat = this.statCache[abs]\n  if (!stat) {\n    var lstat\n    try {\n      lstat = fs.lstatSync(abs)\n    } catch (er) {\n      return false\n    }\n\n    if (lstat.isSymbolicLink()) {\n      try {\n        stat = fs.statSync(abs)\n      } catch (er) {\n        stat = lstat\n      }\n    } else {\n      stat = lstat\n    }\n  }\n\n  this.statCache[abs] = stat\n\n  var c = stat.isDirectory() ? 'DIR' : 'FILE'\n  this.cache[abs] = this.cache[abs] || c\n\n  if (needDir && c !== 'DIR')\n    return false\n\n  return c\n}\n\nGlobSync.prototype._mark = function (p) {\n  return common.mark(this, p)\n}\n\nGlobSync.prototype._makeAbs = function (f) {\n  return common.makeAbs(this, f)\n}\n\n}).call(this,require('_process'))\n},{\"./common.js\":15,\"./glob.js\":16,\"_process\":24,\"assert\":9,\"fs\":12,\"minimatch\":20,\"path\":22,\"path-is-absolute\":23,\"util\":28}],18:[function(require,module,exports){\n(function (process){\nvar wrappy = require('wrappy')\nvar reqs = Object.create(null)\nvar once = require('once')\n\nmodule.exports = wrappy(inflight)\n\nfunction inflight (key, cb) {\n  if (reqs[key]) {\n    reqs[key].push(cb)\n    return null\n  } else {\n    reqs[key] = [cb]\n    return makeres(key)\n  }\n}\n\nfunction makeres (key) {\n  return once(function RES () {\n    var cbs = reqs[key]\n    var len = cbs.length\n    var args = slice(arguments)\n\n    // XXX It's somewhat ambiguous whether a new callback added in this\n    // pass should be queued for later execution if something in the\n    // list of callbacks throws, or if it should just be discarded.\n    // However, it's such an edge case that it hardly matters, and either\n    // choice is likely as surprising as the other.\n    // As it happens, we do go ahead and schedule it for later execution.\n    try {\n      for (var i = 0; i < len; i++) {\n        cbs[i].apply(null, args)\n      }\n    } finally {\n      if (cbs.length > len) {\n        // added more in the interim.\n        // de-zalgo, just in case, but don't call again.\n        cbs.splice(0, len)\n        process.nextTick(function () {\n          RES.apply(null, args)\n        })\n      } else {\n        delete reqs[key]\n      }\n    }\n  })\n}\n\nfunction slice (args) {\n  var length = args.length\n  var array = []\n\n  for (var i = 0; i < length; i++) array[i] = args[i]\n  return array\n}\n\n}).call(this,require('_process'))\n},{\"_process\":24,\"once\":21,\"wrappy\":29}],19:[function(require,module,exports){\nif (typeof Object.create === 'function') {\n  // implementation from standard node.js 'util' module\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    ctor.prototype = Object.create(superCtor.prototype, {\n      constructor: {\n        value: ctor,\n        enumerable: false,\n        writable: true,\n        configurable: true\n      }\n    });\n  };\n} else {\n  // old school shim for old browsers\n  module.exports = function inherits(ctor, superCtor) {\n    ctor.super_ = superCtor\n    var TempCtor = function () {}\n    TempCtor.prototype = superCtor.prototype\n    ctor.prototype = new TempCtor()\n    ctor.prototype.constructor = ctor\n  }\n}\n\n},{}],20:[function(require,module,exports){\nmodule.exports = minimatch\nminimatch.Minimatch = Minimatch\n\nvar path = { sep: '/' }\ntry {\n  path = require('path')\n} catch (er) {}\n\nvar GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}\nvar expand = require('brace-expansion')\n\nvar plTypes = {\n  '!': { open: '(?:(?!(?:', close: '))[^/]*?)'},\n  '?': { open: '(?:', close: ')?' },\n  '+': { open: '(?:', close: ')+' },\n  '*': { open: '(?:', close: ')*' },\n  '@': { open: '(?:', close: ')' }\n}\n\n// any single thing other than /\n// don't need to escape / when using new RegExp()\nvar qmark = '[^/]'\n\n// * => any number of characters\nvar star = qmark + '*?'\n\n// ** when dots are allowed.  Anything goes, except .. and .\n// not (^ or / followed by one or two dots followed by $ or /),\n// followed by anything, any number of times.\nvar twoStarDot = '(?:(?!(?:\\\\\\/|^)(?:\\\\.{1,2})($|\\\\\\/)).)*?'\n\n// not a ^ or / followed by a dot,\n// followed by anything, any number of times.\nvar twoStarNoDot = '(?:(?!(?:\\\\\\/|^)\\\\.).)*?'\n\n// characters that need to be escaped in RegExp.\nvar reSpecials = charSet('().*{}+?[]^$\\\\!')\n\n// \"abc\" -> { a:true, b:true, c:true }\nfunction charSet (s) {\n  return s.split('').reduce(function (set, c) {\n    set[c] = true\n    return set\n  }, {})\n}\n\n// normalizes slashes.\nvar slashSplit = /\\/+/\n\nminimatch.filter = filter\nfunction filter (pattern, options) {\n  options = options || {}\n  return function (p, i, list) {\n    return minimatch(p, pattern, options)\n  }\n}\n\nfunction ext (a, b) {\n  a = a || {}\n  b = b || {}\n  var t = {}\n  Object.keys(b).forEach(function (k) {\n    t[k] = b[k]\n  })\n  Object.keys(a).forEach(function (k) {\n    t[k] = a[k]\n  })\n  return t\n}\n\nminimatch.defaults = function (def) {\n  if (!def || !Object.keys(def).length) return minimatch\n\n  var orig = minimatch\n\n  var m = function minimatch (p, pattern, options) {\n    return orig.minimatch(p, pattern, ext(def, options))\n  }\n\n  m.Minimatch = function Minimatch (pattern, options) {\n    return new orig.Minimatch(pattern, ext(def, options))\n  }\n\n  return m\n}\n\nMinimatch.defaults = function (def) {\n  if (!def || !Object.keys(def).length) return Minimatch\n  return minimatch.defaults(def).Minimatch\n}\n\nfunction minimatch (p, pattern, options) {\n  if (typeof pattern !== 'string') {\n    throw new TypeError('glob pattern string required')\n  }\n\n  if (!options) options = {}\n\n  // shortcut: comments match nothing.\n  if (!options.nocomment && pattern.charAt(0) === '#') {\n    return false\n  }\n\n  // \"\" only matches \"\"\n  if (pattern.trim() === '') return p === ''\n\n  return new Minimatch(pattern, options).match(p)\n}\n\nfunction Minimatch (pattern, options) {\n  if (!(this instanceof Minimatch)) {\n    return new Minimatch(pattern, options)\n  }\n\n  if (typeof pattern !== 'string') {\n    throw new TypeError('glob pattern string required')\n  }\n\n  if (!options) options = {}\n  pattern = pattern.trim()\n\n  // windows support: need to use /, not \\\n  if (path.sep !== '/') {\n    pattern = pattern.split(path.sep).join('/')\n  }\n\n  this.options = options\n  this.set = []\n  this.pattern = pattern\n  this.regexp = null\n  this.negate = false\n  this.comment = false\n  this.empty = false\n\n  // make the set of regexps etc.\n  this.make()\n}\n\nMinimatch.prototype.debug = function () {}\n\nMinimatch.prototype.make = make\nfunction make () {\n  // don't do it more than once.\n  if (this._made) return\n\n  var pattern = this.pattern\n  var options = this.options\n\n  // empty patterns and comments match nothing.\n  if (!options.nocomment && pattern.charAt(0) === '#') {\n    this.comment = true\n    return\n  }\n  if (!pattern) {\n    this.empty = true\n    return\n  }\n\n  // step 1: figure out negation, etc.\n  this.parseNegate()\n\n  // step 2: expand braces\n  var set = this.globSet = this.braceExpand()\n\n  if (options.debug) this.debug = console.error\n\n  this.debug(this.pattern, set)\n\n  // step 3: now we have a set, so turn each one into a series of path-portion\n  // matching patterns.\n  // These will be regexps, except in the case of \"**\", which is\n  // set to the GLOBSTAR object for globstar behavior,\n  // and will not contain any / characters\n  set = this.globParts = set.map(function (s) {\n    return s.split(slashSplit)\n  })\n\n  this.debug(this.pattern, set)\n\n  // glob --> regexps\n  set = set.map(function (s, si, set) {\n    return s.map(this.parse, this)\n  }, this)\n\n  this.debug(this.pattern, set)\n\n  // filter out everything that didn't compile properly.\n  set = set.filter(function (s) {\n    return s.indexOf(false) === -1\n  })\n\n  this.debug(this.pattern, set)\n\n  this.set = set\n}\n\nMinimatch.prototype.parseNegate = parseNegate\nfunction parseNegate () {\n  var pattern = this.pattern\n  var negate = false\n  var options = this.options\n  var negateOffset = 0\n\n  if (options.nonegate) return\n\n  for (var i = 0, l = pattern.length\n    ; i < l && pattern.charAt(i) === '!'\n    ; i++) {\n    negate = !negate\n    negateOffset++\n  }\n\n  if (negateOffset) this.pattern = pattern.substr(negateOffset)\n  this.negate = negate\n}\n\n// Brace expansion:\n// a{b,c}d -> abd acd\n// a{b,}c -> abc ac\n// a{0..3}d -> a0d a1d a2d a3d\n// a{b,c{d,e}f}g -> abg acdfg acefg\n// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg\n//\n// Invalid sets are not expanded.\n// a{2..}b -> a{2..}b\n// a{b}c -> a{b}c\nminimatch.braceExpand = function (pattern, options) {\n  return braceExpand(pattern, options)\n}\n\nMinimatch.prototype.braceExpand = braceExpand\n\nfunction braceExpand (pattern, options) {\n  if (!options) {\n    if (this instanceof Minimatch) {\n      options = this.options\n    } else {\n      options = {}\n    }\n  }\n\n  pattern = typeof pattern === 'undefined'\n    ? this.pattern : pattern\n\n  if (typeof pattern === 'undefined') {\n    throw new TypeError('undefined pattern')\n  }\n\n  if (options.nobrace ||\n    !pattern.match(/\\{.*\\}/)) {\n    // shortcut. no need to expand.\n    return [pattern]\n  }\n\n  return expand(pattern)\n}\n\n// parse a component of the expanded set.\n// At this point, no pattern may contain \"/\" in it\n// so we're going to return a 2d array, where each entry is the full\n// pattern, split on '/', and then turned into a regular expression.\n// A regexp is made at the end which joins each array with an\n// escaped /, and another full one which joins each regexp with |.\n//\n// Following the lead of Bash 4.1, note that \"**\" only has special meaning\n// when it is the *only* thing in a path portion.  Otherwise, any series\n// of * is equivalent to a single *.  Globstar behavior is enabled by\n// default, and can be disabled by setting options.noglobstar.\nMinimatch.prototype.parse = parse\nvar SUBPARSE = {}\nfunction parse (pattern, isSub) {\n  if (pattern.length > 1024 * 64) {\n    throw new TypeError('pattern is too long')\n  }\n\n  var options = this.options\n\n  // shortcuts\n  if (!options.noglobstar && pattern === '**') return GLOBSTAR\n  if (pattern === '') return ''\n\n  var re = ''\n  var hasMagic = !!options.nocase\n  var escaping = false\n  // ? => one single character\n  var patternListStack = []\n  var negativeLists = []\n  var stateChar\n  var inClass = false\n  var reClassStart = -1\n  var classStart = -1\n  // . and .. never match anything that doesn't start with .,\n  // even when options.dot is set.\n  var patternStart = pattern.charAt(0) === '.' ? '' // anything\n  // not (start or / followed by . or .. followed by / or end)\n  : options.dot ? '(?!(?:^|\\\\\\/)\\\\.{1,2}(?:$|\\\\\\/))'\n  : '(?!\\\\.)'\n  var self = this\n\n  function clearStateChar () {\n    if (stateChar) {\n      // we had some state-tracking character\n      // that wasn't consumed by this pass.\n      switch (stateChar) {\n        case '*':\n          re += star\n          hasMagic = true\n        break\n        case '?':\n          re += qmark\n          hasMagic = true\n        break\n        default:\n          re += '\\\\' + stateChar\n        break\n      }\n      self.debug('clearStateChar %j %j', stateChar, re)\n      stateChar = false\n    }\n  }\n\n  for (var i = 0, len = pattern.length, c\n    ; (i < len) && (c = pattern.charAt(i))\n    ; i++) {\n    this.debug('%s\\t%s %s %j', pattern, i, re, c)\n\n    // skip over any that are escaped.\n    if (escaping && reSpecials[c]) {\n      re += '\\\\' + c\n      escaping = false\n      continue\n    }\n\n    switch (c) {\n      case '/':\n        // completely not allowed, even escaped.\n        // Should already be path-split by now.\n        return false\n\n      case '\\\\':\n        clearStateChar()\n        escaping = true\n      continue\n\n      // the various stateChar values\n      // for the \"extglob\" stuff.\n      case '?':\n      case '*':\n      case '+':\n      case '@':\n      case '!':\n        this.debug('%s\\t%s %s %j <-- stateChar', pattern, i, re, c)\n\n        // all of those are literals inside a class, except that\n        // the glob [!a] means [^a] in regexp\n        if (inClass) {\n          this.debug('  in class')\n          if (c === '!' && i === classStart + 1) c = '^'\n          re += c\n          continue\n        }\n\n        // if we already have a stateChar, then it means\n        // that there was something like ** or +? in there.\n        // Handle the stateChar, then proceed with this one.\n        self.debug('call clearStateChar %j', stateChar)\n        clearStateChar()\n        stateChar = c\n        // if extglob is disabled, then +(asdf|foo) isn't a thing.\n        // just clear the statechar *now*, rather than even diving into\n        // the patternList stuff.\n        if (options.noext) clearStateChar()\n      continue\n\n      case '(':\n        if (inClass) {\n          re += '('\n          continue\n        }\n\n        if (!stateChar) {\n          re += '\\\\('\n          continue\n        }\n\n        patternListStack.push({\n          type: stateChar,\n          start: i - 1,\n          reStart: re.length,\n          open: plTypes[stateChar].open,\n          close: plTypes[stateChar].close\n        })\n        // negation is (?:(?!js)[^/]*)\n        re += stateChar === '!' ? '(?:(?!(?:' : '(?:'\n        this.debug('plType %j %j', stateChar, re)\n        stateChar = false\n      continue\n\n      case ')':\n        if (inClass || !patternListStack.length) {\n          re += '\\\\)'\n          continue\n        }\n\n        clearStateChar()\n        hasMagic = true\n        var pl = patternListStack.pop()\n        // negation is (?:(?!js)[^/]*)\n        // The others are (?:<pattern>)<type>\n        re += pl.close\n        if (pl.type === '!') {\n          negativeLists.push(pl)\n        }\n        pl.reEnd = re.length\n      continue\n\n      case '|':\n        if (inClass || !patternListStack.length || escaping) {\n          re += '\\\\|'\n          escaping = false\n          continue\n        }\n\n        clearStateChar()\n        re += '|'\n      continue\n\n      // these are mostly the same in regexp and glob\n      case '[':\n        // swallow any state-tracking char before the [\n        clearStateChar()\n\n        if (inClass) {\n          re += '\\\\' + c\n          continue\n        }\n\n        inClass = true\n        classStart = i\n        reClassStart = re.length\n        re += c\n      continue\n\n      case ']':\n        //  a right bracket shall lose its special\n        //  meaning and represent itself in\n        //  a bracket expression if it occurs\n        //  first in the list.  -- POSIX.2 2.8.3.2\n        if (i === classStart + 1 || !inClass) {\n          re += '\\\\' + c\n          escaping = false\n          continue\n        }\n\n        // handle the case where we left a class open.\n        // \"[z-a]\" is valid, equivalent to \"\\[z-a\\]\"\n        if (inClass) {\n          // split where the last [ was, make sure we don't have\n          // an invalid re. if so, re-walk the contents of the\n          // would-be class to re-translate any characters that\n          // were passed through as-is\n          // TODO: It would probably be faster to determine this\n          // without a try/catch and a new RegExp, but it's tricky\n          // to do safely.  For now, this is safe and works.\n          var cs = pattern.substring(classStart + 1, i)\n          try {\n            RegExp('[' + cs + ']')\n          } catch (er) {\n            // not a valid class!\n            var sp = this.parse(cs, SUBPARSE)\n            re = re.substr(0, reClassStart) + '\\\\[' + sp[0] + '\\\\]'\n            hasMagic = hasMagic || sp[1]\n            inClass = false\n            continue\n          }\n        }\n\n        // finish up the class.\n        hasMagic = true\n        inClass = false\n        re += c\n      continue\n\n      default:\n        // swallow any state char that wasn't consumed\n        clearStateChar()\n\n        if (escaping) {\n          // no need\n          escaping = false\n        } else if (reSpecials[c]\n          && !(c === '^' && inClass)) {\n          re += '\\\\'\n        }\n\n        re += c\n\n    } // switch\n  } // for\n\n  // handle the case where we left a class open.\n  // \"[abc\" is valid, equivalent to \"\\[abc\"\n  if (inClass) {\n    // split where the last [ was, and escape it\n    // this is a huge pita.  We now have to re-walk\n    // the contents of the would-be class to re-translate\n    // any characters that were passed through as-is\n    cs = pattern.substr(classStart + 1)\n    sp = this.parse(cs, SUBPARSE)\n    re = re.substr(0, reClassStart) + '\\\\[' + sp[0]\n    hasMagic = hasMagic || sp[1]\n  }\n\n  // handle the case where we had a +( thing at the *end*\n  // of the pattern.\n  // each pattern list stack adds 3 chars, and we need to go through\n  // and escape any | chars that were passed through as-is for the regexp.\n  // Go through and escape them, taking care not to double-escape any\n  // | chars that were already escaped.\n  for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {\n    var tail = re.slice(pl.reStart + pl.open.length)\n    this.debug('setting tail', re, pl)\n    // maybe some even number of \\, then maybe 1 \\, followed by a |\n    tail = tail.replace(/((?:\\\\{2}){0,64})(\\\\?)\\|/g, function (_, $1, $2) {\n      if (!$2) {\n        // the | isn't already escaped, so escape it.\n        $2 = '\\\\'\n      }\n\n      // need to escape all those slashes *again*, without escaping the\n      // one that we need for escaping the | character.  As it works out,\n      // escaping an even number of slashes can be done by simply repeating\n      // it exactly after itself.  That's why this trick works.\n      //\n      // I am sorry that you have to see this.\n      return $1 + $1 + $2 + '|'\n    })\n\n    this.debug('tail=%j\\n   %s', tail, tail, pl, re)\n    var t = pl.type === '*' ? star\n      : pl.type === '?' ? qmark\n      : '\\\\' + pl.type\n\n    hasMagic = true\n    re = re.slice(0, pl.reStart) + t + '\\\\(' + tail\n  }\n\n  // handle trailing things that only matter at the very end.\n  clearStateChar()\n  if (escaping) {\n    // trailing \\\\\n    re += '\\\\\\\\'\n  }\n\n  // only need to apply the nodot start if the re starts with\n  // something that could conceivably capture a dot\n  var addPatternStart = false\n  switch (re.charAt(0)) {\n    case '.':\n    case '[':\n    case '(': addPatternStart = true\n  }\n\n  // Hack to work around lack of negative lookbehind in JS\n  // A pattern like: *.!(x).!(y|z) needs to ensure that a name\n  // like 'a.xyz.yz' doesn't match.  So, the first negative\n  // lookahead, has to look ALL the way ahead, to the end of\n  // the pattern.\n  for (var n = negativeLists.length - 1; n > -1; n--) {\n    var nl = negativeLists[n]\n\n    var nlBefore = re.slice(0, nl.reStart)\n    var nlFirst = re.slice(nl.reStart, nl.reEnd - 8)\n    var nlLast = re.slice(nl.reEnd - 8, nl.reEnd)\n    var nlAfter = re.slice(nl.reEnd)\n\n    nlLast += nlAfter\n\n    // Handle nested stuff like *(*.js|!(*.json)), where open parens\n    // mean that we should *not* include the ) in the bit that is considered\n    // \"after\" the negated section.\n    var openParensBefore = nlBefore.split('(').length - 1\n    var cleanAfter = nlAfter\n    for (i = 0; i < openParensBefore; i++) {\n      cleanAfter = cleanAfter.replace(/\\)[+*?]?/, '')\n    }\n    nlAfter = cleanAfter\n\n    var dollar = ''\n    if (nlAfter === '' && isSub !== SUBPARSE) {\n      dollar = '$'\n    }\n    var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast\n    re = newRe\n  }\n\n  // if the re is not \"\" at this point, then we need to make sure\n  // it doesn't match against an empty path part.\n  // Otherwise a/* will match a/, which it should not.\n  if (re !== '' && hasMagic) {\n    re = '(?=.)' + re\n  }\n\n  if (addPatternStart) {\n    re = patternStart + re\n  }\n\n  // parsing just a piece of a larger pattern.\n  if (isSub === SUBPARSE) {\n    return [re, hasMagic]\n  }\n\n  // skip the regexp for non-magical patterns\n  // unescape anything in it, though, so that it'll be\n  // an exact match against a file etc.\n  if (!hasMagic) {\n    return globUnescape(pattern)\n  }\n\n  var flags = options.nocase ? 'i' : ''\n  try {\n    var regExp = new RegExp('^' + re + '$', flags)\n  } catch (er) {\n    // If it was an invalid regular expression, then it can't match\n    // anything.  This trick looks for a character after the end of\n    // the string, which is of course impossible, except in multi-line\n    // mode, but it's not a /m regex.\n    return new RegExp('$.')\n  }\n\n  regExp._glob = pattern\n  regExp._src = re\n\n  return regExp\n}\n\nminimatch.makeRe = function (pattern, options) {\n  return new Minimatch(pattern, options || {}).makeRe()\n}\n\nMinimatch.prototype.makeRe = makeRe\nfunction makeRe () {\n  if (this.regexp || this.regexp === false) return this.regexp\n\n  // at this point, this.set is a 2d array of partial\n  // pattern strings, or \"**\".\n  //\n  // It's better to use .match().  This function shouldn't\n  // be used, really, but it's pretty convenient sometimes,\n  // when you just want to work with a regex.\n  var set = this.set\n\n  if (!set.length) {\n    this.regexp = false\n    return this.regexp\n  }\n  var options = this.options\n\n  var twoStar = options.noglobstar ? star\n    : options.dot ? twoStarDot\n    : twoStarNoDot\n  var flags = options.nocase ? 'i' : ''\n\n  var re = set.map(function (pattern) {\n    return pattern.map(function (p) {\n      return (p === GLOBSTAR) ? twoStar\n      : (typeof p === 'string') ? regExpEscape(p)\n      : p._src\n    }).join('\\\\\\/')\n  }).join('|')\n\n  // must match entire pattern\n  // ending in a * or ** will make it less strict.\n  re = '^(?:' + re + ')$'\n\n  // can match anything, as long as it's not this.\n  if (this.negate) re = '^(?!' + re + ').*$'\n\n  try {\n    this.regexp = new RegExp(re, flags)\n  } catch (ex) {\n    this.regexp = false\n  }\n  return this.regexp\n}\n\nminimatch.match = function (list, pattern, options) {\n  options = options || {}\n  var mm = new Minimatch(pattern, options)\n  list = list.filter(function (f) {\n    return mm.match(f)\n  })\n  if (mm.options.nonull && !list.length) {\n    list.push(pattern)\n  }\n  return list\n}\n\nMinimatch.prototype.match = match\nfunction match (f, partial) {\n  this.debug('match', f, this.pattern)\n  // short-circuit in the case of busted things.\n  // comments, etc.\n  if (this.comment) return false\n  if (this.empty) return f === ''\n\n  if (f === '/' && partial) return true\n\n  var options = this.options\n\n  // windows: need to use /, not \\\n  if (path.sep !== '/') {\n    f = f.split(path.sep).join('/')\n  }\n\n  // treat the test path as a set of pathparts.\n  f = f.split(slashSplit)\n  this.debug(this.pattern, 'split', f)\n\n  // just ONE of the pattern sets in this.set needs to match\n  // in order for it to be valid.  If negating, then just one\n  // match means that we have failed.\n  // Either way, return on the first hit.\n\n  var set = this.set\n  this.debug(this.pattern, 'set', set)\n\n  // Find the basename of the path by looking for the last non-empty segment\n  var filename\n  var i\n  for (i = f.length - 1; i >= 0; i--) {\n    filename = f[i]\n    if (filename) break\n  }\n\n  for (i = 0; i < set.length; i++) {\n    var pattern = set[i]\n    var file = f\n    if (options.matchBase && pattern.length === 1) {\n      file = [filename]\n    }\n    var hit = this.matchOne(file, pattern, partial)\n    if (hit) {\n      if (options.flipNegate) return true\n      return !this.negate\n    }\n  }\n\n  // didn't get any hits.  this is success if it's a negative\n  // pattern, failure otherwise.\n  if (options.flipNegate) return false\n  return this.negate\n}\n\n// set partial to true to test if, for example,\n// \"/a/b\" matches the start of \"/*/b/*/d\"\n// Partial means, if you run out of file before you run\n// out of pattern, then that's fine, as long as all\n// the parts match.\nMinimatch.prototype.matchOne = function (file, pattern, partial) {\n  var options = this.options\n\n  this.debug('matchOne',\n    { 'this': this, file: file, pattern: pattern })\n\n  this.debug('matchOne', file.length, pattern.length)\n\n  for (var fi = 0,\n      pi = 0,\n      fl = file.length,\n      pl = pattern.length\n      ; (fi < fl) && (pi < pl)\n      ; fi++, pi++) {\n    this.debug('matchOne loop')\n    var p = pattern[pi]\n    var f = file[fi]\n\n    this.debug(pattern, p, f)\n\n    // should be impossible.\n    // some invalid regexp stuff in the set.\n    if (p === false) return false\n\n    if (p === GLOBSTAR) {\n      this.debug('GLOBSTAR', [pattern, p, f])\n\n      // \"**\"\n      // a/**/b/**/c would match the following:\n      // a/b/x/y/z/c\n      // a/x/y/z/b/c\n      // a/b/x/b/x/c\n      // a/b/c\n      // To do this, take the rest of the pattern after\n      // the **, and see if it would match the file remainder.\n      // If so, return success.\n      // If not, the ** \"swallows\" a segment, and try again.\n      // This is recursively awful.\n      //\n      // a/**/b/**/c matching a/b/x/y/z/c\n      // - a matches a\n      // - doublestar\n      //   - matchOne(b/x/y/z/c, b/**/c)\n      //     - b matches b\n      //     - doublestar\n      //       - matchOne(x/y/z/c, c) -> no\n      //       - matchOne(y/z/c, c) -> no\n      //       - matchOne(z/c, c) -> no\n      //       - matchOne(c, c) yes, hit\n      var fr = fi\n      var pr = pi + 1\n      if (pr === pl) {\n        this.debug('** at the end')\n        // a ** at the end will just swallow the rest.\n        // We have found a match.\n        // however, it will not swallow /.x, unless\n        // options.dot is set.\n        // . and .. are *never* matched by **, for explosively\n        // exponential reasons.\n        for (; fi < fl; fi++) {\n          if (file[fi] === '.' || file[fi] === '..' ||\n            (!options.dot && file[fi].charAt(0) === '.')) return false\n        }\n        return true\n      }\n\n      // ok, let's see if we can swallow whatever we can.\n      while (fr < fl) {\n        var swallowee = file[fr]\n\n        this.debug('\\nglobstar while', file, fr, pattern, pr, swallowee)\n\n        // XXX remove this slice.  Just pass the start index.\n        if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {\n          this.debug('globstar found match!', fr, fl, swallowee)\n          // found a match.\n          return true\n        } else {\n          // can't swallow \".\" or \"..\" ever.\n          // can only swallow \".foo\" when explicitly asked.\n          if (swallowee === '.' || swallowee === '..' ||\n            (!options.dot && swallowee.charAt(0) === '.')) {\n            this.debug('dot detected!', file, fr, pattern, pr)\n            break\n          }\n\n          // ** swallows a segment, and continue.\n          this.debug('globstar swallow a segment, and continue')\n          fr++\n        }\n      }\n\n      // no match was found.\n      // However, in partial mode, we can't say this is necessarily over.\n      // If there's more *pattern* left, then\n      if (partial) {\n        // ran out of file\n        this.debug('\\n>>> no match, partial?', file, fr, pattern, pr)\n        if (fr === fl) return true\n      }\n      return false\n    }\n\n    // something other than **\n    // non-magic patterns just have to match exactly\n    // patterns with magic have been turned into regexps.\n    var hit\n    if (typeof p === 'string') {\n      if (options.nocase) {\n        hit = f.toLowerCase() === p.toLowerCase()\n      } else {\n        hit = f === p\n      }\n      this.debug('string match', p, f, hit)\n    } else {\n      hit = f.match(p)\n      this.debug('pattern match', p, f, hit)\n    }\n\n    if (!hit) return false\n  }\n\n  // Note: ending in / means that we'll get a final \"\"\n  // at the end of the pattern.  This can only match a\n  // corresponding \"\" at the end of the file.\n  // If the file ends in /, then it can only match a\n  // a pattern that ends in /, unless the pattern just\n  // doesn't have any more for it. But, a/b/ should *not*\n  // match \"a/b/*\", even though \"\" matches against the\n  // [^/]*? pattern, except in partial mode, where it might\n  // simply not be reached yet.\n  // However, a/b/ should still satisfy a/*\n\n  // now either we fell off the end of the pattern, or we're done.\n  if (fi === fl && pi === pl) {\n    // ran out of pattern and filename at the same time.\n    // an exact hit!\n    return true\n  } else if (fi === fl) {\n    // ran out of file, but still had pattern left.\n    // this is ok if we're doing the match as part of\n    // a glob fs traversal.\n    return partial\n  } else if (pi === pl) {\n    // ran out of pattern, still have file left.\n    // this is only acceptable if we're on the very last\n    // empty segment of a file with a trailing slash.\n    // a/* should match a/b/\n    var emptyFileEnd = (fi === fl - 1) && (file[fi] === '')\n    return emptyFileEnd\n  }\n\n  // should be unreachable.\n  throw new Error('wtf?')\n}\n\n// replace stuff like \\* with *\nfunction globUnescape (s) {\n  return s.replace(/\\\\(.)/g, '$1')\n}\n\nfunction regExpEscape (s) {\n  return s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n}\n\n},{\"brace-expansion\":11,\"path\":22}],21:[function(require,module,exports){\nvar wrappy = require('wrappy')\nmodule.exports = wrappy(once)\nmodule.exports.strict = wrappy(onceStrict)\n\nonce.proto = once(function () {\n  Object.defineProperty(Function.prototype, 'once', {\n    value: function () {\n      return once(this)\n    },\n    configurable: true\n  })\n\n  Object.defineProperty(Function.prototype, 'onceStrict', {\n    value: function () {\n      return onceStrict(this)\n    },\n    configurable: true\n  })\n})\n\nfunction once (fn) {\n  var f = function () {\n    if (f.called) return f.value\n    f.called = true\n    return f.value = fn.apply(this, arguments)\n  }\n  f.called = false\n  return f\n}\n\nfunction onceStrict (fn) {\n  var f = function () {\n    if (f.called)\n      throw new Error(f.onceError)\n    f.called = true\n    return f.value = fn.apply(this, arguments)\n  }\n  var name = fn.name || 'Function wrapped with `once`'\n  f.onceError = name + \" shouldn't be called more than once\"\n  f.called = false\n  return f\n}\n\n},{\"wrappy\":29}],22:[function(require,module,exports){\n(function (process){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// resolves . and .. elements in a path array with directory names there\n// must be no slashes, empty elements, or device names (c:\\) in the array\n// (so also no leading and trailing slashes - it does not distinguish\n// relative and absolute paths)\nfunction normalizeArray(parts, allowAboveRoot) {\n  // if the path tries to go above the root, `up` ends up > 0\n  var up = 0;\n  for (var i = parts.length - 1; i >= 0; i--) {\n    var last = parts[i];\n    if (last === '.') {\n      parts.splice(i, 1);\n    } else if (last === '..') {\n      parts.splice(i, 1);\n      up++;\n    } else if (up) {\n      parts.splice(i, 1);\n      up--;\n    }\n  }\n\n  // if the path is allowed to go above the root, restore leading ..s\n  if (allowAboveRoot) {\n    for (; up--; up) {\n      parts.unshift('..');\n    }\n  }\n\n  return parts;\n}\n\n// Split a filename into [root, dir, basename, ext], unix version\n// 'root' is just a slash, or nothing.\nvar splitPathRe =\n    /^(\\/?|)([\\s\\S]*?)((?:\\.{1,2}|[^\\/]+?|)(\\.[^.\\/]*|))(?:[\\/]*)$/;\nvar splitPath = function(filename) {\n  return splitPathRe.exec(filename).slice(1);\n};\n\n// path.resolve([from ...], to)\n// posix version\nexports.resolve = function() {\n  var resolvedPath = '',\n      resolvedAbsolute = false;\n\n  for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {\n    var path = (i >= 0) ? arguments[i] : process.cwd();\n\n    // Skip empty and invalid entries\n    if (typeof path !== 'string') {\n      throw new TypeError('Arguments to path.resolve must be strings');\n    } else if (!path) {\n      continue;\n    }\n\n    resolvedPath = path + '/' + resolvedPath;\n    resolvedAbsolute = path.charAt(0) === '/';\n  }\n\n  // At this point the path should be resolved to a full absolute path, but\n  // handle relative paths to be safe (might happen when process.cwd() fails)\n\n  // Normalize the path\n  resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {\n    return !!p;\n  }), !resolvedAbsolute).join('/');\n\n  return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';\n};\n\n// path.normalize(path)\n// posix version\nexports.normalize = function(path) {\n  var isAbsolute = exports.isAbsolute(path),\n      trailingSlash = substr(path, -1) === '/';\n\n  // Normalize the path\n  path = normalizeArray(filter(path.split('/'), function(p) {\n    return !!p;\n  }), !isAbsolute).join('/');\n\n  if (!path && !isAbsolute) {\n    path = '.';\n  }\n  if (path && trailingSlash) {\n    path += '/';\n  }\n\n  return (isAbsolute ? '/' : '') + path;\n};\n\n// posix version\nexports.isAbsolute = function(path) {\n  return path.charAt(0) === '/';\n};\n\n// posix version\nexports.join = function() {\n  var paths = Array.prototype.slice.call(arguments, 0);\n  return exports.normalize(filter(paths, function(p, index) {\n    if (typeof p !== 'string') {\n      throw new TypeError('Arguments to path.join must be strings');\n    }\n    return p;\n  }).join('/'));\n};\n\n\n// path.relative(from, to)\n// posix version\nexports.relative = function(from, to) {\n  from = exports.resolve(from).substr(1);\n  to = exports.resolve(to).substr(1);\n\n  function trim(arr) {\n    var start = 0;\n    for (; start < arr.length; start++) {\n      if (arr[start] !== '') break;\n    }\n\n    var end = arr.length - 1;\n    for (; end >= 0; end--) {\n      if (arr[end] !== '') break;\n    }\n\n    if (start > end) return [];\n    return arr.slice(start, end - start + 1);\n  }\n\n  var fromParts = trim(from.split('/'));\n  var toParts = trim(to.split('/'));\n\n  var length = Math.min(fromParts.length, toParts.length);\n  var samePartsLength = length;\n  for (var i = 0; i < length; i++) {\n    if (fromParts[i] !== toParts[i]) {\n      samePartsLength = i;\n      break;\n    }\n  }\n\n  var outputParts = [];\n  for (var i = samePartsLength; i < fromParts.length; i++) {\n    outputParts.push('..');\n  }\n\n  outputParts = outputParts.concat(toParts.slice(samePartsLength));\n\n  return outputParts.join('/');\n};\n\nexports.sep = '/';\nexports.delimiter = ':';\n\nexports.dirname = function(path) {\n  var result = splitPath(path),\n      root = result[0],\n      dir = result[1];\n\n  if (!root && !dir) {\n    // No dirname whatsoever\n    return '.';\n  }\n\n  if (dir) {\n    // It has a dirname, strip trailing slash\n    dir = dir.substr(0, dir.length - 1);\n  }\n\n  return root + dir;\n};\n\n\nexports.basename = function(path, ext) {\n  var f = splitPath(path)[2];\n  // TODO: make this comparison case-insensitive on windows?\n  if (ext && f.substr(-1 * ext.length) === ext) {\n    f = f.substr(0, f.length - ext.length);\n  }\n  return f;\n};\n\n\nexports.extname = function(path) {\n  return splitPath(path)[3];\n};\n\nfunction filter (xs, f) {\n    if (xs.filter) return xs.filter(f);\n    var res = [];\n    for (var i = 0; i < xs.length; i++) {\n        if (f(xs[i], i, xs)) res.push(xs[i]);\n    }\n    return res;\n}\n\n// String.prototype.substr - negative index don't work in IE8\nvar substr = 'ab'.substr(-1) === 'b'\n    ? function (str, start, len) { return str.substr(start, len) }\n    : function (str, start, len) {\n        if (start < 0) start = str.length + start;\n        return str.substr(start, len);\n    }\n;\n\n}).call(this,require('_process'))\n},{\"_process\":24}],23:[function(require,module,exports){\n(function (process){\n'use strict';\n\nfunction posix(path) {\n\treturn path.charAt(0) === '/';\n}\n\nfunction win32(path) {\n\t// https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56\n\tvar splitDeviceRe = /^([a-zA-Z]:|[\\\\\\/]{2}[^\\\\\\/]+[\\\\\\/]+[^\\\\\\/]+)?([\\\\\\/])?([\\s\\S]*?)$/;\n\tvar result = splitDeviceRe.exec(path);\n\tvar device = result[1] || '';\n\tvar isUnc = Boolean(device && device.charAt(1) !== ':');\n\n\t// UNC paths are always absolute\n\treturn Boolean(result[2] || isUnc);\n}\n\nmodule.exports = process.platform === 'win32' ? win32 : posix;\nmodule.exports.posix = posix;\nmodule.exports.win32 = win32;\n\n}).call(this,require('_process'))\n},{\"_process\":24}],24:[function(require,module,exports){\n// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things.  But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals.  It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n    throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n    throw new Error('clearTimeout has not been defined');\n}\n(function () {\n    try {\n        if (typeof setTimeout === 'function') {\n            cachedSetTimeout = setTimeout;\n        } else {\n            cachedSetTimeout = defaultSetTimout;\n        }\n    } catch (e) {\n        cachedSetTimeout = defaultSetTimout;\n    }\n    try {\n        if (typeof clearTimeout === 'function') {\n            cachedClearTimeout = clearTimeout;\n        } else {\n            cachedClearTimeout = defaultClearTimeout;\n        }\n    } catch (e) {\n        cachedClearTimeout = defaultClearTimeout;\n    }\n} ())\nfunction runTimeout(fun) {\n    if (cachedSetTimeout === setTimeout) {\n        //normal enviroments in sane situations\n        return setTimeout(fun, 0);\n    }\n    // if setTimeout wasn't available but was latter defined\n    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n        cachedSetTimeout = setTimeout;\n        return setTimeout(fun, 0);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedSetTimeout(fun, 0);\n    } catch(e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n            return cachedSetTimeout.call(null, fun, 0);\n        } catch(e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n            return cachedSetTimeout.call(this, fun, 0);\n        }\n    }\n\n\n}\nfunction runClearTimeout(marker) {\n    if (cachedClearTimeout === clearTimeout) {\n        //normal enviroments in sane situations\n        return clearTimeout(marker);\n    }\n    // if clearTimeout wasn't available but was latter defined\n    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n        cachedClearTimeout = clearTimeout;\n        return clearTimeout(marker);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedClearTimeout(marker);\n    } catch (e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally\n            return cachedClearTimeout.call(null, marker);\n        } catch (e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n            // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n            return cachedClearTimeout.call(this, marker);\n        }\n    }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    if (!draining || !currentQueue) {\n        return;\n    }\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = runTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        runTimeout(drainQueue);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],25:[function(require,module,exports){\n//     Underscore.js 1.8.3\n//     http://underscorejs.org\n//     (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n//     Underscore may be freely distributed under the MIT license.\n\n(function() {\n\n  // Baseline setup\n  // --------------\n\n  // Establish the root object, `window` in the browser, or `exports` on the server.\n  var root = this;\n\n  // Save the previous value of the `_` variable.\n  var previousUnderscore = root._;\n\n  // Save bytes in the minified (but not gzipped) version:\n  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;\n\n  // Create quick reference variables for speed access to core prototypes.\n  var\n    push             = ArrayProto.push,\n    slice            = ArrayProto.slice,\n    toString         = ObjProto.toString,\n    hasOwnProperty   = ObjProto.hasOwnProperty;\n\n  // All **ECMAScript 5** native function implementations that we hope to use\n  // are declared here.\n  var\n    nativeIsArray      = Array.isArray,\n    nativeKeys         = Object.keys,\n    nativeBind         = FuncProto.bind,\n    nativeCreate       = Object.create;\n\n  // Naked function reference for surrogate-prototype-swapping.\n  var Ctor = function(){};\n\n  // Create a safe reference to the Underscore object for use below.\n  var _ = function(obj) {\n    if (obj instanceof _) return obj;\n    if (!(this instanceof _)) return new _(obj);\n    this._wrapped = obj;\n  };\n\n  // Export the Underscore object for **Node.js**, with\n  // backwards-compatibility for the old `require()` API. If we're in\n  // the browser, add `_` as a global object.\n  if (typeof exports !== 'undefined') {\n    if (typeof module !== 'undefined' && module.exports) {\n      exports = module.exports = _;\n    }\n    exports._ = _;\n  } else {\n    root._ = _;\n  }\n\n  // Current version.\n  _.VERSION = '1.8.3';\n\n  // Internal function that returns an efficient (for current engines) version\n  // of the passed-in callback, to be repeatedly applied in other Underscore\n  // functions.\n  var optimizeCb = function(func, context, argCount) {\n    if (context === void 0) return func;\n    switch (argCount == null ? 3 : argCount) {\n      case 1: return function(value) {\n        return func.call(context, value);\n      };\n      case 2: return function(value, other) {\n        return func.call(context, value, other);\n      };\n      case 3: return function(value, index, collection) {\n        return func.call(context, value, index, collection);\n      };\n      case 4: return function(accumulator, value, index, collection) {\n        return func.call(context, accumulator, value, index, collection);\n      };\n    }\n    return function() {\n      return func.apply(context, arguments);\n    };\n  };\n\n  // A mostly-internal function to generate callbacks that can be applied\n  // to each element in a collection, returning the desired result — either\n  // identity, an arbitrary callback, a property matcher, or a property accessor.\n  var cb = function(value, context, argCount) {\n    if (value == null) return _.identity;\n    if (_.isFunction(value)) return optimizeCb(value, context, argCount);\n    if (_.isObject(value)) return _.matcher(value);\n    return _.property(value);\n  };\n  _.iteratee = function(value, context) {\n    return cb(value, context, Infinity);\n  };\n\n  // An internal function for creating assigner functions.\n  var createAssigner = function(keysFunc, undefinedOnly) {\n    return function(obj) {\n      var length = arguments.length;\n      if (length < 2 || obj == null) return obj;\n      for (var index = 1; index < length; index++) {\n        var source = arguments[index],\n            keys = keysFunc(source),\n            l = keys.length;\n        for (var i = 0; i < l; i++) {\n          var key = keys[i];\n          if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];\n        }\n      }\n      return obj;\n    };\n  };\n\n  // An internal function for creating a new object that inherits from another.\n  var baseCreate = function(prototype) {\n    if (!_.isObject(prototype)) return {};\n    if (nativeCreate) return nativeCreate(prototype);\n    Ctor.prototype = prototype;\n    var result = new Ctor;\n    Ctor.prototype = null;\n    return result;\n  };\n\n  var property = function(key) {\n    return function(obj) {\n      return obj == null ? void 0 : obj[key];\n    };\n  };\n\n  // Helper for collection methods to determine whether a collection\n  // should be iterated as an array or as an object\n  // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength\n  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094\n  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;\n  var getLength = property('length');\n  var isArrayLike = function(collection) {\n    var length = getLength(collection);\n    return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;\n  };\n\n  // Collection Functions\n  // --------------------\n\n  // The cornerstone, an `each` implementation, aka `forEach`.\n  // Handles raw objects in addition to array-likes. Treats all\n  // sparse array-likes as if they were dense.\n  _.each = _.forEach = function(obj, iteratee, context) {\n    iteratee = optimizeCb(iteratee, context);\n    var i, length;\n    if (isArrayLike(obj)) {\n      for (i = 0, length = obj.length; i < length; i++) {\n        iteratee(obj[i], i, obj);\n      }\n    } else {\n      var keys = _.keys(obj);\n      for (i = 0, length = keys.length; i < length; i++) {\n        iteratee(obj[keys[i]], keys[i], obj);\n      }\n    }\n    return obj;\n  };\n\n  // Return the results of applying the iteratee to each element.\n  _.map = _.collect = function(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var keys = !isArrayLike(obj) && _.keys(obj),\n        length = (keys || obj).length,\n        results = Array(length);\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys ? keys[index] : index;\n      results[index] = iteratee(obj[currentKey], currentKey, obj);\n    }\n    return results;\n  };\n\n  // Create a reducing function iterating left or right.\n  function createReduce(dir) {\n    // Optimized iterator function as using arguments.length\n    // in the main function will deoptimize the, see #1991.\n    function iterator(obj, iteratee, memo, keys, index, length) {\n      for (; index >= 0 && index < length; index += dir) {\n        var currentKey = keys ? keys[index] : index;\n        memo = iteratee(memo, obj[currentKey], currentKey, obj);\n      }\n      return memo;\n    }\n\n    return function(obj, iteratee, memo, context) {\n      iteratee = optimizeCb(iteratee, context, 4);\n      var keys = !isArrayLike(obj) && _.keys(obj),\n          length = (keys || obj).length,\n          index = dir > 0 ? 0 : length - 1;\n      // Determine the initial value if none is provided.\n      if (arguments.length < 3) {\n        memo = obj[keys ? keys[index] : index];\n        index += dir;\n      }\n      return iterator(obj, iteratee, memo, keys, index, length);\n    };\n  }\n\n  // **Reduce** builds up a single result from a list of values, aka `inject`,\n  // or `foldl`.\n  _.reduce = _.foldl = _.inject = createReduce(1);\n\n  // The right-associative version of reduce, also known as `foldr`.\n  _.reduceRight = _.foldr = createReduce(-1);\n\n  // Return the first value which passes a truth test. Aliased as `detect`.\n  _.find = _.detect = function(obj, predicate, context) {\n    var key;\n    if (isArrayLike(obj)) {\n      key = _.findIndex(obj, predicate, context);\n    } else {\n      key = _.findKey(obj, predicate, context);\n    }\n    if (key !== void 0 && key !== -1) return obj[key];\n  };\n\n  // Return all the elements that pass a truth test.\n  // Aliased as `select`.\n  _.filter = _.select = function(obj, predicate, context) {\n    var results = [];\n    predicate = cb(predicate, context);\n    _.each(obj, function(value, index, list) {\n      if (predicate(value, index, list)) results.push(value);\n    });\n    return results;\n  };\n\n  // Return all the elements for which a truth test fails.\n  _.reject = function(obj, predicate, context) {\n    return _.filter(obj, _.negate(cb(predicate)), context);\n  };\n\n  // Determine whether all of the elements match a truth test.\n  // Aliased as `all`.\n  _.every = _.all = function(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var keys = !isArrayLike(obj) && _.keys(obj),\n        length = (keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys ? keys[index] : index;\n      if (!predicate(obj[currentKey], currentKey, obj)) return false;\n    }\n    return true;\n  };\n\n  // Determine if at least one element in the object matches a truth test.\n  // Aliased as `any`.\n  _.some = _.any = function(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var keys = !isArrayLike(obj) && _.keys(obj),\n        length = (keys || obj).length;\n    for (var index = 0; index < length; index++) {\n      var currentKey = keys ? keys[index] : index;\n      if (predicate(obj[currentKey], currentKey, obj)) return true;\n    }\n    return false;\n  };\n\n  // Determine if the array or object contains a given item (using `===`).\n  // Aliased as `includes` and `include`.\n  _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {\n    if (!isArrayLike(obj)) obj = _.values(obj);\n    if (typeof fromIndex != 'number' || guard) fromIndex = 0;\n    return _.indexOf(obj, item, fromIndex) >= 0;\n  };\n\n  // Invoke a method (with arguments) on every item in a collection.\n  _.invoke = function(obj, method) {\n    var args = slice.call(arguments, 2);\n    var isFunc = _.isFunction(method);\n    return _.map(obj, function(value) {\n      var func = isFunc ? method : value[method];\n      return func == null ? func : func.apply(value, args);\n    });\n  };\n\n  // Convenience version of a common use case of `map`: fetching a property.\n  _.pluck = function(obj, key) {\n    return _.map(obj, _.property(key));\n  };\n\n  // Convenience version of a common use case of `filter`: selecting only objects\n  // containing specific `key:value` pairs.\n  _.where = function(obj, attrs) {\n    return _.filter(obj, _.matcher(attrs));\n  };\n\n  // Convenience version of a common use case of `find`: getting the first object\n  // containing specific `key:value` pairs.\n  _.findWhere = function(obj, attrs) {\n    return _.find(obj, _.matcher(attrs));\n  };\n\n  // Return the maximum element (or element-based computation).\n  _.max = function(obj, iteratee, context) {\n    var result = -Infinity, lastComputed = -Infinity,\n        value, computed;\n    if (iteratee == null && obj != null) {\n      obj = isArrayLike(obj) ? obj : _.values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value > result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      _.each(obj, function(value, index, list) {\n        computed = iteratee(value, index, list);\n        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {\n          result = value;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  };\n\n  // Return the minimum element (or element-based computation).\n  _.min = function(obj, iteratee, context) {\n    var result = Infinity, lastComputed = Infinity,\n        value, computed;\n    if (iteratee == null && obj != null) {\n      obj = isArrayLike(obj) ? obj : _.values(obj);\n      for (var i = 0, length = obj.length; i < length; i++) {\n        value = obj[i];\n        if (value < result) {\n          result = value;\n        }\n      }\n    } else {\n      iteratee = cb(iteratee, context);\n      _.each(obj, function(value, index, list) {\n        computed = iteratee(value, index, list);\n        if (computed < lastComputed || computed === Infinity && result === Infinity) {\n          result = value;\n          lastComputed = computed;\n        }\n      });\n    }\n    return result;\n  };\n\n  // Shuffle a collection, using the modern version of the\n  // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).\n  _.shuffle = function(obj) {\n    var set = isArrayLike(obj) ? obj : _.values(obj);\n    var length = set.length;\n    var shuffled = Array(length);\n    for (var index = 0, rand; index < length; index++) {\n      rand = _.random(0, index);\n      if (rand !== index) shuffled[index] = shuffled[rand];\n      shuffled[rand] = set[index];\n    }\n    return shuffled;\n  };\n\n  // Sample **n** random values from a collection.\n  // If **n** is not specified, returns a single random element.\n  // The internal `guard` argument allows it to work with `map`.\n  _.sample = function(obj, n, guard) {\n    if (n == null || guard) {\n      if (!isArrayLike(obj)) obj = _.values(obj);\n      return obj[_.random(obj.length - 1)];\n    }\n    return _.shuffle(obj).slice(0, Math.max(0, n));\n  };\n\n  // Sort the object's values by a criterion produced by an iteratee.\n  _.sortBy = function(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    return _.pluck(_.map(obj, function(value, index, list) {\n      return {\n        value: value,\n        index: index,\n        criteria: iteratee(value, index, list)\n      };\n    }).sort(function(left, right) {\n      var a = left.criteria;\n      var b = right.criteria;\n      if (a !== b) {\n        if (a > b || a === void 0) return 1;\n        if (a < b || b === void 0) return -1;\n      }\n      return left.index - right.index;\n    }), 'value');\n  };\n\n  // An internal function used for aggregate \"group by\" operations.\n  var group = function(behavior) {\n    return function(obj, iteratee, context) {\n      var result = {};\n      iteratee = cb(iteratee, context);\n      _.each(obj, function(value, index) {\n        var key = iteratee(value, index, obj);\n        behavior(result, value, key);\n      });\n      return result;\n    };\n  };\n\n  // Groups the object's values by a criterion. Pass either a string attribute\n  // to group by, or a function that returns the criterion.\n  _.groupBy = group(function(result, value, key) {\n    if (_.has(result, key)) result[key].push(value); else result[key] = [value];\n  });\n\n  // Indexes the object's values by a criterion, similar to `groupBy`, but for\n  // when you know that your index values will be unique.\n  _.indexBy = group(function(result, value, key) {\n    result[key] = value;\n  });\n\n  // Counts instances of an object that group by a certain criterion. Pass\n  // either a string attribute to count by, or a function that returns the\n  // criterion.\n  _.countBy = group(function(result, value, key) {\n    if (_.has(result, key)) result[key]++; else result[key] = 1;\n  });\n\n  // Safely create a real, live array from anything iterable.\n  _.toArray = function(obj) {\n    if (!obj) return [];\n    if (_.isArray(obj)) return slice.call(obj);\n    if (isArrayLike(obj)) return _.map(obj, _.identity);\n    return _.values(obj);\n  };\n\n  // Return the number of elements in an object.\n  _.size = function(obj) {\n    if (obj == null) return 0;\n    return isArrayLike(obj) ? obj.length : _.keys(obj).length;\n  };\n\n  // Split a collection into two arrays: one whose elements all satisfy the given\n  // predicate, and one whose elements all do not satisfy the predicate.\n  _.partition = function(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var pass = [], fail = [];\n    _.each(obj, function(value, key, obj) {\n      (predicate(value, key, obj) ? pass : fail).push(value);\n    });\n    return [pass, fail];\n  };\n\n  // Array Functions\n  // ---------------\n\n  // Get the first element of an array. Passing **n** will return the first N\n  // values in the array. Aliased as `head` and `take`. The **guard** check\n  // allows it to work with `_.map`.\n  _.first = _.head = _.take = function(array, n, guard) {\n    if (array == null) return void 0;\n    if (n == null || guard) return array[0];\n    return _.initial(array, array.length - n);\n  };\n\n  // Returns everything but the last entry of the array. Especially useful on\n  // the arguments object. Passing **n** will return all the values in\n  // the array, excluding the last N.\n  _.initial = function(array, n, guard) {\n    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));\n  };\n\n  // Get the last element of an array. Passing **n** will return the last N\n  // values in the array.\n  _.last = function(array, n, guard) {\n    if (array == null) return void 0;\n    if (n == null || guard) return array[array.length - 1];\n    return _.rest(array, Math.max(0, array.length - n));\n  };\n\n  // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.\n  // Especially useful on the arguments object. Passing an **n** will return\n  // the rest N values in the array.\n  _.rest = _.tail = _.drop = function(array, n, guard) {\n    return slice.call(array, n == null || guard ? 1 : n);\n  };\n\n  // Trim out all falsy values from an array.\n  _.compact = function(array) {\n    return _.filter(array, _.identity);\n  };\n\n  // Internal implementation of a recursive `flatten` function.\n  var flatten = function(input, shallow, strict, startIndex) {\n    var output = [], idx = 0;\n    for (var i = startIndex || 0, length = getLength(input); i < length; i++) {\n      var value = input[i];\n      if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {\n        //flatten current level of array or arguments object\n        if (!shallow) value = flatten(value, shallow, strict);\n        var j = 0, len = value.length;\n        output.length += len;\n        while (j < len) {\n          output[idx++] = value[j++];\n        }\n      } else if (!strict) {\n        output[idx++] = value;\n      }\n    }\n    return output;\n  };\n\n  // Flatten out an array, either recursively (by default), or just one level.\n  _.flatten = function(array, shallow) {\n    return flatten(array, shallow, false);\n  };\n\n  // Return a version of the array that does not contain the specified value(s).\n  _.without = function(array) {\n    return _.difference(array, slice.call(arguments, 1));\n  };\n\n  // Produce a duplicate-free version of the array. If the array has already\n  // been sorted, you have the option of using a faster algorithm.\n  // Aliased as `unique`.\n  _.uniq = _.unique = function(array, isSorted, iteratee, context) {\n    if (!_.isBoolean(isSorted)) {\n      context = iteratee;\n      iteratee = isSorted;\n      isSorted = false;\n    }\n    if (iteratee != null) iteratee = cb(iteratee, context);\n    var result = [];\n    var seen = [];\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var value = array[i],\n          computed = iteratee ? iteratee(value, i, array) : value;\n      if (isSorted) {\n        if (!i || seen !== computed) result.push(value);\n        seen = computed;\n      } else if (iteratee) {\n        if (!_.contains(seen, computed)) {\n          seen.push(computed);\n          result.push(value);\n        }\n      } else if (!_.contains(result, value)) {\n        result.push(value);\n      }\n    }\n    return result;\n  };\n\n  // Produce an array that contains the union: each distinct element from all of\n  // the passed-in arrays.\n  _.union = function() {\n    return _.uniq(flatten(arguments, true, true));\n  };\n\n  // Produce an array that contains every item shared between all the\n  // passed-in arrays.\n  _.intersection = function(array) {\n    var result = [];\n    var argsLength = arguments.length;\n    for (var i = 0, length = getLength(array); i < length; i++) {\n      var item = array[i];\n      if (_.contains(result, item)) continue;\n      for (var j = 1; j < argsLength; j++) {\n        if (!_.contains(arguments[j], item)) break;\n      }\n      if (j === argsLength) result.push(item);\n    }\n    return result;\n  };\n\n  // Take the difference between one array and a number of other arrays.\n  // Only the elements present in just the first array will remain.\n  _.difference = function(array) {\n    var rest = flatten(arguments, true, true, 1);\n    return _.filter(array, function(value){\n      return !_.contains(rest, value);\n    });\n  };\n\n  // Zip together multiple lists into a single array -- elements that share\n  // an index go together.\n  _.zip = function() {\n    return _.unzip(arguments);\n  };\n\n  // Complement of _.zip. Unzip accepts an array of arrays and groups\n  // each array's elements on shared indices\n  _.unzip = function(array) {\n    var length = array && _.max(array, getLength).length || 0;\n    var result = Array(length);\n\n    for (var index = 0; index < length; index++) {\n      result[index] = _.pluck(array, index);\n    }\n    return result;\n  };\n\n  // Converts lists into objects. Pass either a single array of `[key, value]`\n  // pairs, or two parallel arrays of the same length -- one of keys, and one of\n  // the corresponding values.\n  _.object = function(list, values) {\n    var result = {};\n    for (var i = 0, length = getLength(list); i < length; i++) {\n      if (values) {\n        result[list[i]] = values[i];\n      } else {\n        result[list[i][0]] = list[i][1];\n      }\n    }\n    return result;\n  };\n\n  // Generator function to create the findIndex and findLastIndex functions\n  function createPredicateIndexFinder(dir) {\n    return function(array, predicate, context) {\n      predicate = cb(predicate, context);\n      var length = getLength(array);\n      var index = dir > 0 ? 0 : length - 1;\n      for (; index >= 0 && index < length; index += dir) {\n        if (predicate(array[index], index, array)) return index;\n      }\n      return -1;\n    };\n  }\n\n  // Returns the first index on an array-like that passes a predicate test\n  _.findIndex = createPredicateIndexFinder(1);\n  _.findLastIndex = createPredicateIndexFinder(-1);\n\n  // Use a comparator function to figure out the smallest index at which\n  // an object should be inserted so as to maintain order. Uses binary search.\n  _.sortedIndex = function(array, obj, iteratee, context) {\n    iteratee = cb(iteratee, context, 1);\n    var value = iteratee(obj);\n    var low = 0, high = getLength(array);\n    while (low < high) {\n      var mid = Math.floor((low + high) / 2);\n      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;\n    }\n    return low;\n  };\n\n  // Generator function to create the indexOf and lastIndexOf functions\n  function createIndexFinder(dir, predicateFind, sortedIndex) {\n    return function(array, item, idx) {\n      var i = 0, length = getLength(array);\n      if (typeof idx == 'number') {\n        if (dir > 0) {\n            i = idx >= 0 ? idx : Math.max(idx + length, i);\n        } else {\n            length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;\n        }\n      } else if (sortedIndex && idx && length) {\n        idx = sortedIndex(array, item);\n        return array[idx] === item ? idx : -1;\n      }\n      if (item !== item) {\n        idx = predicateFind(slice.call(array, i, length), _.isNaN);\n        return idx >= 0 ? idx + i : -1;\n      }\n      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {\n        if (array[idx] === item) return idx;\n      }\n      return -1;\n    };\n  }\n\n  // Return the position of the first occurrence of an item in an array,\n  // or -1 if the item is not included in the array.\n  // If the array is large and already in sort order, pass `true`\n  // for **isSorted** to use binary search.\n  _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);\n  _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);\n\n  // Generate an integer Array containing an arithmetic progression. A port of\n  // the native Python `range()` function. See\n  // [the Python documentation](http://docs.python.org/library/functions.html#range).\n  _.range = function(start, stop, step) {\n    if (stop == null) {\n      stop = start || 0;\n      start = 0;\n    }\n    step = step || 1;\n\n    var length = Math.max(Math.ceil((stop - start) / step), 0);\n    var range = Array(length);\n\n    for (var idx = 0; idx < length; idx++, start += step) {\n      range[idx] = start;\n    }\n\n    return range;\n  };\n\n  // Function (ahem) Functions\n  // ------------------\n\n  // Determines whether to execute a function as a constructor\n  // or a normal function with the provided arguments\n  var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {\n    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);\n    var self = baseCreate(sourceFunc.prototype);\n    var result = sourceFunc.apply(self, args);\n    if (_.isObject(result)) return result;\n    return self;\n  };\n\n  // Create a function bound to a given object (assigning `this`, and arguments,\n  // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if\n  // available.\n  _.bind = function(func, context) {\n    if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));\n    if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');\n    var args = slice.call(arguments, 2);\n    var bound = function() {\n      return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));\n    };\n    return bound;\n  };\n\n  // Partially apply a function by creating a version that has had some of its\n  // arguments pre-filled, without changing its dynamic `this` context. _ acts\n  // as a placeholder, allowing any combination of arguments to be pre-filled.\n  _.partial = function(func) {\n    var boundArgs = slice.call(arguments, 1);\n    var bound = function() {\n      var position = 0, length = boundArgs.length;\n      var args = Array(length);\n      for (var i = 0; i < length; i++) {\n        args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];\n      }\n      while (position < arguments.length) args.push(arguments[position++]);\n      return executeBound(func, bound, this, this, args);\n    };\n    return bound;\n  };\n\n  // Bind a number of an object's methods to that object. Remaining arguments\n  // are the method names to be bound. Useful for ensuring that all callbacks\n  // defined on an object belong to it.\n  _.bindAll = function(obj) {\n    var i, length = arguments.length, key;\n    if (length <= 1) throw new Error('bindAll must be passed function names');\n    for (i = 1; i < length; i++) {\n      key = arguments[i];\n      obj[key] = _.bind(obj[key], obj);\n    }\n    return obj;\n  };\n\n  // Memoize an expensive function by storing its results.\n  _.memoize = function(func, hasher) {\n    var memoize = function(key) {\n      var cache = memoize.cache;\n      var address = '' + (hasher ? hasher.apply(this, arguments) : key);\n      if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);\n      return cache[address];\n    };\n    memoize.cache = {};\n    return memoize;\n  };\n\n  // Delays a function for the given number of milliseconds, and then calls\n  // it with the arguments supplied.\n  _.delay = function(func, wait) {\n    var args = slice.call(arguments, 2);\n    return setTimeout(function(){\n      return func.apply(null, args);\n    }, wait);\n  };\n\n  // Defers a function, scheduling it to run after the current call stack has\n  // cleared.\n  _.defer = _.partial(_.delay, _, 1);\n\n  // Returns a function, that, when invoked, will only be triggered at most once\n  // during a given window of time. Normally, the throttled function will run\n  // as much as it can, without ever going more than once per `wait` duration;\n  // but if you'd like to disable the execution on the leading edge, pass\n  // `{leading: false}`. To disable execution on the trailing edge, ditto.\n  _.throttle = function(func, wait, options) {\n    var context, args, result;\n    var timeout = null;\n    var previous = 0;\n    if (!options) options = {};\n    var later = function() {\n      previous = options.leading === false ? 0 : _.now();\n      timeout = null;\n      result = func.apply(context, args);\n      if (!timeout) context = args = null;\n    };\n    return function() {\n      var now = _.now();\n      if (!previous && options.leading === false) previous = now;\n      var remaining = wait - (now - previous);\n      context = this;\n      args = arguments;\n      if (remaining <= 0 || remaining > wait) {\n        if (timeout) {\n          clearTimeout(timeout);\n          timeout = null;\n        }\n        previous = now;\n        result = func.apply(context, args);\n        if (!timeout) context = args = null;\n      } else if (!timeout && options.trailing !== false) {\n        timeout = setTimeout(later, remaining);\n      }\n      return result;\n    };\n  };\n\n  // Returns a function, that, as long as it continues to be invoked, will not\n  // be triggered. The function will be called after it stops being called for\n  // N milliseconds. If `immediate` is passed, trigger the function on the\n  // leading edge, instead of the trailing.\n  _.debounce = function(func, wait, immediate) {\n    var timeout, args, context, timestamp, result;\n\n    var later = function() {\n      var last = _.now() - timestamp;\n\n      if (last < wait && last >= 0) {\n        timeout = setTimeout(later, wait - last);\n      } else {\n        timeout = null;\n        if (!immediate) {\n          result = func.apply(context, args);\n          if (!timeout) context = args = null;\n        }\n      }\n    };\n\n    return function() {\n      context = this;\n      args = arguments;\n      timestamp = _.now();\n      var callNow = immediate && !timeout;\n      if (!timeout) timeout = setTimeout(later, wait);\n      if (callNow) {\n        result = func.apply(context, args);\n        context = args = null;\n      }\n\n      return result;\n    };\n  };\n\n  // Returns the first function passed as an argument to the second,\n  // allowing you to adjust arguments, run code before and after, and\n  // conditionally execute the original function.\n  _.wrap = function(func, wrapper) {\n    return _.partial(wrapper, func);\n  };\n\n  // Returns a negated version of the passed-in predicate.\n  _.negate = function(predicate) {\n    return function() {\n      return !predicate.apply(this, arguments);\n    };\n  };\n\n  // Returns a function that is the composition of a list of functions, each\n  // consuming the return value of the function that follows.\n  _.compose = function() {\n    var args = arguments;\n    var start = args.length - 1;\n    return function() {\n      var i = start;\n      var result = args[start].apply(this, arguments);\n      while (i--) result = args[i].call(this, result);\n      return result;\n    };\n  };\n\n  // Returns a function that will only be executed on and after the Nth call.\n  _.after = function(times, func) {\n    return function() {\n      if (--times < 1) {\n        return func.apply(this, arguments);\n      }\n    };\n  };\n\n  // Returns a function that will only be executed up to (but not including) the Nth call.\n  _.before = function(times, func) {\n    var memo;\n    return function() {\n      if (--times > 0) {\n        memo = func.apply(this, arguments);\n      }\n      if (times <= 1) func = null;\n      return memo;\n    };\n  };\n\n  // Returns a function that will be executed at most one time, no matter how\n  // often you call it. Useful for lazy initialization.\n  _.once = _.partial(_.before, 2);\n\n  // Object Functions\n  // ----------------\n\n  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.\n  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');\n  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',\n                      'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];\n\n  function collectNonEnumProps(obj, keys) {\n    var nonEnumIdx = nonEnumerableProps.length;\n    var constructor = obj.constructor;\n    var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;\n\n    // Constructor is a special case.\n    var prop = 'constructor';\n    if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);\n\n    while (nonEnumIdx--) {\n      prop = nonEnumerableProps[nonEnumIdx];\n      if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {\n        keys.push(prop);\n      }\n    }\n  }\n\n  // Retrieve the names of an object's own properties.\n  // Delegates to **ECMAScript 5**'s native `Object.keys`\n  _.keys = function(obj) {\n    if (!_.isObject(obj)) return [];\n    if (nativeKeys) return nativeKeys(obj);\n    var keys = [];\n    for (var key in obj) if (_.has(obj, key)) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  };\n\n  // Retrieve all the property names of an object.\n  _.allKeys = function(obj) {\n    if (!_.isObject(obj)) return [];\n    var keys = [];\n    for (var key in obj) keys.push(key);\n    // Ahem, IE < 9.\n    if (hasEnumBug) collectNonEnumProps(obj, keys);\n    return keys;\n  };\n\n  // Retrieve the values of an object's properties.\n  _.values = function(obj) {\n    var keys = _.keys(obj);\n    var length = keys.length;\n    var values = Array(length);\n    for (var i = 0; i < length; i++) {\n      values[i] = obj[keys[i]];\n    }\n    return values;\n  };\n\n  // Returns the results of applying the iteratee to each element of the object\n  // In contrast to _.map it returns an object\n  _.mapObject = function(obj, iteratee, context) {\n    iteratee = cb(iteratee, context);\n    var keys =  _.keys(obj),\n          length = keys.length,\n          results = {},\n          currentKey;\n      for (var index = 0; index < length; index++) {\n        currentKey = keys[index];\n        results[currentKey] = iteratee(obj[currentKey], currentKey, obj);\n      }\n      return results;\n  };\n\n  // Convert an object into a list of `[key, value]` pairs.\n  _.pairs = function(obj) {\n    var keys = _.keys(obj);\n    var length = keys.length;\n    var pairs = Array(length);\n    for (var i = 0; i < length; i++) {\n      pairs[i] = [keys[i], obj[keys[i]]];\n    }\n    return pairs;\n  };\n\n  // Invert the keys and values of an object. The values must be serializable.\n  _.invert = function(obj) {\n    var result = {};\n    var keys = _.keys(obj);\n    for (var i = 0, length = keys.length; i < length; i++) {\n      result[obj[keys[i]]] = keys[i];\n    }\n    return result;\n  };\n\n  // Return a sorted list of the function names available on the object.\n  // Aliased as `methods`\n  _.functions = _.methods = function(obj) {\n    var names = [];\n    for (var key in obj) {\n      if (_.isFunction(obj[key])) names.push(key);\n    }\n    return names.sort();\n  };\n\n  // Extend a given object with all the properties in passed-in object(s).\n  _.extend = createAssigner(_.allKeys);\n\n  // Assigns a given object with all the own properties in the passed-in object(s)\n  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)\n  _.extendOwn = _.assign = createAssigner(_.keys);\n\n  // Returns the first key on an object that passes a predicate test\n  _.findKey = function(obj, predicate, context) {\n    predicate = cb(predicate, context);\n    var keys = _.keys(obj), key;\n    for (var i = 0, length = keys.length; i < length; i++) {\n      key = keys[i];\n      if (predicate(obj[key], key, obj)) return key;\n    }\n  };\n\n  // Return a copy of the object only containing the whitelisted properties.\n  _.pick = function(object, oiteratee, context) {\n    var result = {}, obj = object, iteratee, keys;\n    if (obj == null) return result;\n    if (_.isFunction(oiteratee)) {\n      keys = _.allKeys(obj);\n      iteratee = optimizeCb(oiteratee, context);\n    } else {\n      keys = flatten(arguments, false, false, 1);\n      iteratee = function(value, key, obj) { return key in obj; };\n      obj = Object(obj);\n    }\n    for (var i = 0, length = keys.length; i < length; i++) {\n      var key = keys[i];\n      var value = obj[key];\n      if (iteratee(value, key, obj)) result[key] = value;\n    }\n    return result;\n  };\n\n   // Return a copy of the object without the blacklisted properties.\n  _.omit = function(obj, iteratee, context) {\n    if (_.isFunction(iteratee)) {\n      iteratee = _.negate(iteratee);\n    } else {\n      var keys = _.map(flatten(arguments, false, false, 1), String);\n      iteratee = function(value, key) {\n        return !_.contains(keys, key);\n      };\n    }\n    return _.pick(obj, iteratee, context);\n  };\n\n  // Fill in a given object with default properties.\n  _.defaults = createAssigner(_.allKeys, true);\n\n  // Creates an object that inherits from the given prototype object.\n  // If additional properties are provided then they will be added to the\n  // created object.\n  _.create = function(prototype, props) {\n    var result = baseCreate(prototype);\n    if (props) _.extendOwn(result, props);\n    return result;\n  };\n\n  // Create a (shallow-cloned) duplicate of an object.\n  _.clone = function(obj) {\n    if (!_.isObject(obj)) return obj;\n    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);\n  };\n\n  // Invokes interceptor with the obj, and then returns obj.\n  // The primary purpose of this method is to \"tap into\" a method chain, in\n  // order to perform operations on intermediate results within the chain.\n  _.tap = function(obj, interceptor) {\n    interceptor(obj);\n    return obj;\n  };\n\n  // Returns whether an object has a given set of `key:value` pairs.\n  _.isMatch = function(object, attrs) {\n    var keys = _.keys(attrs), length = keys.length;\n    if (object == null) return !length;\n    var obj = Object(object);\n    for (var i = 0; i < length; i++) {\n      var key = keys[i];\n      if (attrs[key] !== obj[key] || !(key in obj)) return false;\n    }\n    return true;\n  };\n\n\n  // Internal recursive comparison function for `isEqual`.\n  var eq = function(a, b, aStack, bStack) {\n    // Identical objects are equal. `0 === -0`, but they aren't identical.\n    // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).\n    if (a === b) return a !== 0 || 1 / a === 1 / b;\n    // A strict comparison is necessary because `null == undefined`.\n    if (a == null || b == null) return a === b;\n    // Unwrap any wrapped objects.\n    if (a instanceof _) a = a._wrapped;\n    if (b instanceof _) b = b._wrapped;\n    // Compare `[[Class]]` names.\n    var className = toString.call(a);\n    if (className !== toString.call(b)) return false;\n    switch (className) {\n      // Strings, numbers, regular expressions, dates, and booleans are compared by value.\n      case '[object RegExp]':\n      // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')\n      case '[object String]':\n        // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n        // equivalent to `new String(\"5\")`.\n        return '' + a === '' + b;\n      case '[object Number]':\n        // `NaN`s are equivalent, but non-reflexive.\n        // Object(NaN) is equivalent to NaN\n        if (+a !== +a) return +b !== +b;\n        // An `egal` comparison is performed for other numeric values.\n        return +a === 0 ? 1 / +a === 1 / b : +a === +b;\n      case '[object Date]':\n      case '[object Boolean]':\n        // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n        // millisecond representations. Note that invalid dates with millisecond representations\n        // of `NaN` are not equivalent.\n        return +a === +b;\n    }\n\n    var areArrays = className === '[object Array]';\n    if (!areArrays) {\n      if (typeof a != 'object' || typeof b != 'object') return false;\n\n      // Objects with different constructors are not equivalent, but `Object`s or `Array`s\n      // from different frames are.\n      var aCtor = a.constructor, bCtor = b.constructor;\n      if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&\n                               _.isFunction(bCtor) && bCtor instanceof bCtor)\n                          && ('constructor' in a && 'constructor' in b)) {\n        return false;\n      }\n    }\n    // Assume equality for cyclic structures. The algorithm for detecting cyclic\n    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n\n    // Initializing stack of traversed objects.\n    // It's done here since we only need them for objects and arrays comparison.\n    aStack = aStack || [];\n    bStack = bStack || [];\n    var length = aStack.length;\n    while (length--) {\n      // Linear search. Performance is inversely proportional to the number of\n      // unique nested structures.\n      if (aStack[length] === a) return bStack[length] === b;\n    }\n\n    // Add the first object to the stack of traversed objects.\n    aStack.push(a);\n    bStack.push(b);\n\n    // Recursively compare objects and arrays.\n    if (areArrays) {\n      // Compare array lengths to determine if a deep comparison is necessary.\n      length = a.length;\n      if (length !== b.length) return false;\n      // Deep compare the contents, ignoring non-numeric properties.\n      while (length--) {\n        if (!eq(a[length], b[length], aStack, bStack)) return false;\n      }\n    } else {\n      // Deep compare objects.\n      var keys = _.keys(a), key;\n      length = keys.length;\n      // Ensure that both objects contain the same number of properties before comparing deep equality.\n      if (_.keys(b).length !== length) return false;\n      while (length--) {\n        // Deep compare each member\n        key = keys[length];\n        if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;\n      }\n    }\n    // Remove the first object from the stack of traversed objects.\n    aStack.pop();\n    bStack.pop();\n    return true;\n  };\n\n  // Perform a deep comparison to check if two objects are equal.\n  _.isEqual = function(a, b) {\n    return eq(a, b);\n  };\n\n  // Is a given array, string, or object empty?\n  // An \"empty\" object has no enumerable own-properties.\n  _.isEmpty = function(obj) {\n    if (obj == null) return true;\n    if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;\n    return _.keys(obj).length === 0;\n  };\n\n  // Is a given value a DOM element?\n  _.isElement = function(obj) {\n    return !!(obj && obj.nodeType === 1);\n  };\n\n  // Is a given value an array?\n  // Delegates to ECMA5's native Array.isArray\n  _.isArray = nativeIsArray || function(obj) {\n    return toString.call(obj) === '[object Array]';\n  };\n\n  // Is a given variable an object?\n  _.isObject = function(obj) {\n    var type = typeof obj;\n    return type === 'function' || type === 'object' && !!obj;\n  };\n\n  // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.\n  _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {\n    _['is' + name] = function(obj) {\n      return toString.call(obj) === '[object ' + name + ']';\n    };\n  });\n\n  // Define a fallback version of the method in browsers (ahem, IE < 9), where\n  // there isn't any inspectable \"Arguments\" type.\n  if (!_.isArguments(arguments)) {\n    _.isArguments = function(obj) {\n      return _.has(obj, 'callee');\n    };\n  }\n\n  // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,\n  // IE 11 (#1621), and in Safari 8 (#1929).\n  if (typeof /./ != 'function' && typeof Int8Array != 'object') {\n    _.isFunction = function(obj) {\n      return typeof obj == 'function' || false;\n    };\n  }\n\n  // Is a given object a finite number?\n  _.isFinite = function(obj) {\n    return isFinite(obj) && !isNaN(parseFloat(obj));\n  };\n\n  // Is the given value `NaN`? (NaN is the only number which does not equal itself).\n  _.isNaN = function(obj) {\n    return _.isNumber(obj) && obj !== +obj;\n  };\n\n  // Is a given value a boolean?\n  _.isBoolean = function(obj) {\n    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';\n  };\n\n  // Is a given value equal to null?\n  _.isNull = function(obj) {\n    return obj === null;\n  };\n\n  // Is a given variable undefined?\n  _.isUndefined = function(obj) {\n    return obj === void 0;\n  };\n\n  // Shortcut function for checking if an object has a given property directly\n  // on itself (in other words, not on a prototype).\n  _.has = function(obj, key) {\n    return obj != null && hasOwnProperty.call(obj, key);\n  };\n\n  // Utility Functions\n  // -----------------\n\n  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its\n  // previous owner. Returns a reference to the Underscore object.\n  _.noConflict = function() {\n    root._ = previousUnderscore;\n    return this;\n  };\n\n  // Keep the identity function around for default iteratees.\n  _.identity = function(value) {\n    return value;\n  };\n\n  // Predicate-generating functions. Often useful outside of Underscore.\n  _.constant = function(value) {\n    return function() {\n      return value;\n    };\n  };\n\n  _.noop = function(){};\n\n  _.property = property;\n\n  // Generates a function for a given object that returns a given property.\n  _.propertyOf = function(obj) {\n    return obj == null ? function(){} : function(key) {\n      return obj[key];\n    };\n  };\n\n  // Returns a predicate for checking whether an object has a given set of\n  // `key:value` pairs.\n  _.matcher = _.matches = function(attrs) {\n    attrs = _.extendOwn({}, attrs);\n    return function(obj) {\n      return _.isMatch(obj, attrs);\n    };\n  };\n\n  // Run a function **n** times.\n  _.times = function(n, iteratee, context) {\n    var accum = Array(Math.max(0, n));\n    iteratee = optimizeCb(iteratee, context, 1);\n    for (var i = 0; i < n; i++) accum[i] = iteratee(i);\n    return accum;\n  };\n\n  // Return a random integer between min and max (inclusive).\n  _.random = function(min, max) {\n    if (max == null) {\n      max = min;\n      min = 0;\n    }\n    return min + Math.floor(Math.random() * (max - min + 1));\n  };\n\n  // A (possibly faster) way to get the current timestamp as an integer.\n  _.now = Date.now || function() {\n    return new Date().getTime();\n  };\n\n   // List of HTML entities for escaping.\n  var escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n  var unescapeMap = _.invert(escapeMap);\n\n  // Functions for escaping and unescaping strings to/from HTML interpolation.\n  var createEscaper = function(map) {\n    var escaper = function(match) {\n      return map[match];\n    };\n    // Regexes for identifying a key that needs to be escaped\n    var source = '(?:' + _.keys(map).join('|') + ')';\n    var testRegexp = RegExp(source);\n    var replaceRegexp = RegExp(source, 'g');\n    return function(string) {\n      string = string == null ? '' : '' + string;\n      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;\n    };\n  };\n  _.escape = createEscaper(escapeMap);\n  _.unescape = createEscaper(unescapeMap);\n\n  // If the value of the named `property` is a function then invoke it with the\n  // `object` as context; otherwise, return it.\n  _.result = function(object, property, fallback) {\n    var value = object == null ? void 0 : object[property];\n    if (value === void 0) {\n      value = fallback;\n    }\n    return _.isFunction(value) ? value.call(object) : value;\n  };\n\n  // Generate a unique integer id (unique within the entire client session).\n  // Useful for temporary DOM ids.\n  var idCounter = 0;\n  _.uniqueId = function(prefix) {\n    var id = ++idCounter + '';\n    return prefix ? prefix + id : id;\n  };\n\n  // By default, Underscore uses ERB-style template delimiters, change the\n  // following template settings to use alternative delimiters.\n  _.templateSettings = {\n    evaluate    : /<%([\\s\\S]+?)%>/g,\n    interpolate : /<%=([\\s\\S]+?)%>/g,\n    escape      : /<%-([\\s\\S]+?)%>/g\n  };\n\n  // When customizing `templateSettings`, if you don't want to define an\n  // interpolation, evaluation or escaping regex, we need one that is\n  // guaranteed not to match.\n  var noMatch = /(.)^/;\n\n  // Certain characters need to be escaped so that they can be put into a\n  // string literal.\n  var escapes = {\n    \"'\":      \"'\",\n    '\\\\':     '\\\\',\n    '\\r':     'r',\n    '\\n':     'n',\n    '\\u2028': 'u2028',\n    '\\u2029': 'u2029'\n  };\n\n  var escaper = /\\\\|'|\\r|\\n|\\u2028|\\u2029/g;\n\n  var escapeChar = function(match) {\n    return '\\\\' + escapes[match];\n  };\n\n  // JavaScript micro-templating, similar to John Resig's implementation.\n  // Underscore templating handles arbitrary delimiters, preserves whitespace,\n  // and correctly escapes quotes within interpolated code.\n  // NB: `oldSettings` only exists for backwards compatibility.\n  _.template = function(text, settings, oldSettings) {\n    if (!settings && oldSettings) settings = oldSettings;\n    settings = _.defaults({}, settings, _.templateSettings);\n\n    // Combine delimiters into one regular expression via alternation.\n    var matcher = RegExp([\n      (settings.escape || noMatch).source,\n      (settings.interpolate || noMatch).source,\n      (settings.evaluate || noMatch).source\n    ].join('|') + '|$', 'g');\n\n    // Compile the template source, escaping string literals appropriately.\n    var index = 0;\n    var source = \"__p+='\";\n    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {\n      source += text.slice(index, offset).replace(escaper, escapeChar);\n      index = offset + match.length;\n\n      if (escape) {\n        source += \"'+\\n((__t=(\" + escape + \"))==null?'':_.escape(__t))+\\n'\";\n      } else if (interpolate) {\n        source += \"'+\\n((__t=(\" + interpolate + \"))==null?'':__t)+\\n'\";\n      } else if (evaluate) {\n        source += \"';\\n\" + evaluate + \"\\n__p+='\";\n      }\n\n      // Adobe VMs need the match returned to produce the correct offest.\n      return match;\n    });\n    source += \"';\\n\";\n\n    // If a variable is not specified, place data values in local scope.\n    if (!settings.variable) source = 'with(obj||{}){\\n' + source + '}\\n';\n\n    source = \"var __t,__p='',__j=Array.prototype.join,\" +\n      \"print=function(){__p+=__j.call(arguments,'');};\\n\" +\n      source + 'return __p;\\n';\n\n    try {\n      var render = new Function(settings.variable || 'obj', '_', source);\n    } catch (e) {\n      e.source = source;\n      throw e;\n    }\n\n    var template = function(data) {\n      return render.call(this, data, _);\n    };\n\n    // Provide the compiled source as a convenience for precompilation.\n    var argument = settings.variable || 'obj';\n    template.source = 'function(' + argument + '){\\n' + source + '}';\n\n    return template;\n  };\n\n  // Add a \"chain\" function. Start chaining a wrapped Underscore object.\n  _.chain = function(obj) {\n    var instance = _(obj);\n    instance._chain = true;\n    return instance;\n  };\n\n  // OOP\n  // ---------------\n  // If Underscore is called as a function, it returns a wrapped object that\n  // can be used OO-style. This wrapper holds altered versions of all the\n  // underscore functions. Wrapped objects may be chained.\n\n  // Helper function to continue chaining intermediate results.\n  var result = function(instance, obj) {\n    return instance._chain ? _(obj).chain() : obj;\n  };\n\n  // Add your own custom functions to the Underscore object.\n  _.mixin = function(obj) {\n    _.each(_.functions(obj), function(name) {\n      var func = _[name] = obj[name];\n      _.prototype[name] = function() {\n        var args = [this._wrapped];\n        push.apply(args, arguments);\n        return result(this, func.apply(_, args));\n      };\n    });\n  };\n\n  // Add all of the Underscore functions to the wrapper object.\n  _.mixin(_);\n\n  // Add all mutator Array functions to the wrapper.\n  _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {\n    var method = ArrayProto[name];\n    _.prototype[name] = function() {\n      var obj = this._wrapped;\n      method.apply(obj, arguments);\n      if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];\n      return result(this, obj);\n    };\n  });\n\n  // Add all accessor Array functions to the wrapper.\n  _.each(['concat', 'join', 'slice'], function(name) {\n    var method = ArrayProto[name];\n    _.prototype[name] = function() {\n      return result(this, method.apply(this._wrapped, arguments));\n    };\n  });\n\n  // Extracts the result from a wrapped and chained object.\n  _.prototype.value = function() {\n    return this._wrapped;\n  };\n\n  // Provide unwrapping proxy for some methods used in engine operations\n  // such as arithmetic and JSON stringification.\n  _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;\n\n  _.prototype.toString = function() {\n    return '' + this._wrapped;\n  };\n\n  // AMD registration happens at the end for compatibility with AMD loaders\n  // that may not enforce next-turn semantics on modules. Even though general\n  // practice for AMD registration is to be anonymous, underscore registers\n  // as a named module because, like jQuery, it is a base library that is\n  // popular enough to be bundled in a third party lib, but not be part of\n  // an AMD load request. Those cases could generate an error when an\n  // anonymous define() is called outside of a loader request.\n  if (typeof define === 'function' && define.amd) {\n    define('underscore', [], function() {\n      return _;\n    });\n  }\n}.call(this));\n\n},{}],26:[function(require,module,exports){\narguments[4][19][0].apply(exports,arguments)\n},{\"dup\":19}],27:[function(require,module,exports){\nmodule.exports = function isBuffer(arg) {\n  return arg && typeof arg === 'object'\n    && typeof arg.copy === 'function'\n    && typeof arg.fill === 'function'\n    && typeof arg.readUInt8 === 'function';\n}\n},{}],28:[function(require,module,exports){\n(function (process,global){\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n  if (!isString(f)) {\n    var objects = [];\n    for (var i = 0; i < arguments.length; i++) {\n      objects.push(inspect(arguments[i]));\n    }\n    return objects.join(' ');\n  }\n\n  var i = 1;\n  var args = arguments;\n  var len = args.length;\n  var str = String(f).replace(formatRegExp, function(x) {\n    if (x === '%%') return '%';\n    if (i >= len) return x;\n    switch (x) {\n      case '%s': return String(args[i++]);\n      case '%d': return Number(args[i++]);\n      case '%j':\n        try {\n          return JSON.stringify(args[i++]);\n        } catch (_) {\n          return '[Circular]';\n        }\n      default:\n        return x;\n    }\n  });\n  for (var x = args[i]; i < len; x = args[++i]) {\n    if (isNull(x) || !isObject(x)) {\n      str += ' ' + x;\n    } else {\n      str += ' ' + inspect(x);\n    }\n  }\n  return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n  // Allow for deprecating things in the process of starting up.\n  if (isUndefined(global.process)) {\n    return function() {\n      return exports.deprecate(fn, msg).apply(this, arguments);\n    };\n  }\n\n  if (process.noDeprecation === true) {\n    return fn;\n  }\n\n  var warned = false;\n  function deprecated() {\n    if (!warned) {\n      if (process.throwDeprecation) {\n        throw new Error(msg);\n      } else if (process.traceDeprecation) {\n        console.trace(msg);\n      } else {\n        console.error(msg);\n      }\n      warned = true;\n    }\n    return fn.apply(this, arguments);\n  }\n\n  return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n  if (isUndefined(debugEnviron))\n    debugEnviron = process.env.NODE_DEBUG || '';\n  set = set.toUpperCase();\n  if (!debugs[set]) {\n    if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n      var pid = process.pid;\n      debugs[set] = function() {\n        var msg = exports.format.apply(exports, arguments);\n        console.error('%s %d: %s', set, pid, msg);\n      };\n    } else {\n      debugs[set] = function() {};\n    }\n  }\n  return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n  // default options\n  var ctx = {\n    seen: [],\n    stylize: stylizeNoColor\n  };\n  // legacy...\n  if (arguments.length >= 3) ctx.depth = arguments[2];\n  if (arguments.length >= 4) ctx.colors = arguments[3];\n  if (isBoolean(opts)) {\n    // legacy...\n    ctx.showHidden = opts;\n  } else if (opts) {\n    // got an \"options\" object\n    exports._extend(ctx, opts);\n  }\n  // set default options\n  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n  if (isUndefined(ctx.depth)) ctx.depth = 2;\n  if (isUndefined(ctx.colors)) ctx.colors = false;\n  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n  if (ctx.colors) ctx.stylize = stylizeWithColor;\n  return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n  'bold' : [1, 22],\n  'italic' : [3, 23],\n  'underline' : [4, 24],\n  'inverse' : [7, 27],\n  'white' : [37, 39],\n  'grey' : [90, 39],\n  'black' : [30, 39],\n  'blue' : [34, 39],\n  'cyan' : [36, 39],\n  'green' : [32, 39],\n  'magenta' : [35, 39],\n  'red' : [31, 39],\n  'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n  'special': 'cyan',\n  'number': 'yellow',\n  'boolean': 'yellow',\n  'undefined': 'grey',\n  'null': 'bold',\n  'string': 'green',\n  'date': 'magenta',\n  // \"name\": intentionally not styling\n  'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n  var style = inspect.styles[styleType];\n\n  if (style) {\n    return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n           '\\u001b[' + inspect.colors[style][1] + 'm';\n  } else {\n    return str;\n  }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n  return str;\n}\n\n\nfunction arrayToHash(array) {\n  var hash = {};\n\n  array.forEach(function(val, idx) {\n    hash[val] = true;\n  });\n\n  return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n  // Provide a hook for user-specified inspect functions.\n  // Check that value is an object with an inspect function on it\n  if (ctx.customInspect &&\n      value &&\n      isFunction(value.inspect) &&\n      // Filter out the util module, it's inspect function is special\n      value.inspect !== exports.inspect &&\n      // Also filter out any prototype objects using the circular check.\n      !(value.constructor && value.constructor.prototype === value)) {\n    var ret = value.inspect(recurseTimes, ctx);\n    if (!isString(ret)) {\n      ret = formatValue(ctx, ret, recurseTimes);\n    }\n    return ret;\n  }\n\n  // Primitive types cannot have properties\n  var primitive = formatPrimitive(ctx, value);\n  if (primitive) {\n    return primitive;\n  }\n\n  // Look up the keys of the object.\n  var keys = Object.keys(value);\n  var visibleKeys = arrayToHash(keys);\n\n  if (ctx.showHidden) {\n    keys = Object.getOwnPropertyNames(value);\n  }\n\n  // IE doesn't make error fields non-enumerable\n  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n  if (isError(value)\n      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n    return formatError(value);\n  }\n\n  // Some type of object without properties can be shortcutted.\n  if (keys.length === 0) {\n    if (isFunction(value)) {\n      var name = value.name ? ': ' + value.name : '';\n      return ctx.stylize('[Function' + name + ']', 'special');\n    }\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    }\n    if (isDate(value)) {\n      return ctx.stylize(Date.prototype.toString.call(value), 'date');\n    }\n    if (isError(value)) {\n      return formatError(value);\n    }\n  }\n\n  var base = '', array = false, braces = ['{', '}'];\n\n  // Make Array say that they are Array\n  if (isArray(value)) {\n    array = true;\n    braces = ['[', ']'];\n  }\n\n  // Make functions say that they are functions\n  if (isFunction(value)) {\n    var n = value.name ? ': ' + value.name : '';\n    base = ' [Function' + n + ']';\n  }\n\n  // Make RegExps say that they are RegExps\n  if (isRegExp(value)) {\n    base = ' ' + RegExp.prototype.toString.call(value);\n  }\n\n  // Make dates with properties first say the date\n  if (isDate(value)) {\n    base = ' ' + Date.prototype.toUTCString.call(value);\n  }\n\n  // Make error with message first say the error\n  if (isError(value)) {\n    base = ' ' + formatError(value);\n  }\n\n  if (keys.length === 0 && (!array || value.length == 0)) {\n    return braces[0] + base + braces[1];\n  }\n\n  if (recurseTimes < 0) {\n    if (isRegExp(value)) {\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n    } else {\n      return ctx.stylize('[Object]', 'special');\n    }\n  }\n\n  ctx.seen.push(value);\n\n  var output;\n  if (array) {\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n  } else {\n    output = keys.map(function(key) {\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n    });\n  }\n\n  ctx.seen.pop();\n\n  return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n  if (isUndefined(value))\n    return ctx.stylize('undefined', 'undefined');\n  if (isString(value)) {\n    var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n                                             .replace(/'/g, \"\\\\'\")\n                                             .replace(/\\\\\"/g, '\"') + '\\'';\n    return ctx.stylize(simple, 'string');\n  }\n  if (isNumber(value))\n    return ctx.stylize('' + value, 'number');\n  if (isBoolean(value))\n    return ctx.stylize('' + value, 'boolean');\n  // For some reason typeof null is \"object\", so special case here.\n  if (isNull(value))\n    return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n  return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n  var output = [];\n  for (var i = 0, l = value.length; i < l; ++i) {\n    if (hasOwnProperty(value, String(i))) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          String(i), true));\n    } else {\n      output.push('');\n    }\n  }\n  keys.forEach(function(key) {\n    if (!key.match(/^\\d+$/)) {\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n          key, true));\n    }\n  });\n  return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n  var name, str, desc;\n  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n  if (desc.get) {\n    if (desc.set) {\n      str = ctx.stylize('[Getter/Setter]', 'special');\n    } else {\n      str = ctx.stylize('[Getter]', 'special');\n    }\n  } else {\n    if (desc.set) {\n      str = ctx.stylize('[Setter]', 'special');\n    }\n  }\n  if (!hasOwnProperty(visibleKeys, key)) {\n    name = '[' + key + ']';\n  }\n  if (!str) {\n    if (ctx.seen.indexOf(desc.value) < 0) {\n      if (isNull(recurseTimes)) {\n        str = formatValue(ctx, desc.value, null);\n      } else {\n        str = formatValue(ctx, desc.value, recurseTimes - 1);\n      }\n      if (str.indexOf('\\n') > -1) {\n        if (array) {\n          str = str.split('\\n').map(function(line) {\n            return '  ' + line;\n          }).join('\\n').substr(2);\n        } else {\n          str = '\\n' + str.split('\\n').map(function(line) {\n            return '   ' + line;\n          }).join('\\n');\n        }\n      }\n    } else {\n      str = ctx.stylize('[Circular]', 'special');\n    }\n  }\n  if (isUndefined(name)) {\n    if (array && key.match(/^\\d+$/)) {\n      return str;\n    }\n    name = JSON.stringify('' + key);\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n      name = name.substr(1, name.length - 2);\n      name = ctx.stylize(name, 'name');\n    } else {\n      name = name.replace(/'/g, \"\\\\'\")\n                 .replace(/\\\\\"/g, '\"')\n                 .replace(/(^\"|\"$)/g, \"'\");\n      name = ctx.stylize(name, 'string');\n    }\n  }\n\n  return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n  var numLinesEst = 0;\n  var length = output.reduce(function(prev, cur) {\n    numLinesEst++;\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\n    return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n  }, 0);\n\n  if (length > 60) {\n    return braces[0] +\n           (base === '' ? '' : base + '\\n ') +\n           ' ' +\n           output.join(',\\n  ') +\n           ' ' +\n           braces[1];\n  }\n\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n  return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n  return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n  return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n  return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n  return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n  return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n  return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n  return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n  return isObject(e) &&\n      (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n  return arg === null ||\n         typeof arg === 'boolean' ||\n         typeof arg === 'number' ||\n         typeof arg === 'string' ||\n         typeof arg === 'symbol' ||  // ES6 symbol\n         typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n  return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n  return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n              'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n  var d = new Date();\n  var time = [pad(d.getHours()),\n              pad(d.getMinutes()),\n              pad(d.getSeconds())].join(':');\n  return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n *     prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n  // Don't do anything if add isn't an object\n  if (!add || !isObject(add)) return origin;\n\n  var keys = Object.keys(add);\n  var i = keys.length;\n  while (i--) {\n    origin[keys[i]] = add[keys[i]];\n  }\n  return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n  return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"./support/isBuffer\":27,\"_process\":24,\"inherits\":26}],29:[function(require,module,exports){\n// Returns a wrapper function that returns a wrapped callback\n// The wrapper function should do some stuff, and return a\n// presumably different callback function.\n// This makes sure that own properties are retained, so that\n// decorations and such are not lost along the way.\nmodule.exports = wrappy\nfunction wrappy (fn, cb) {\n  if (fn && cb) return wrappy(fn)(cb)\n\n  if (typeof fn !== 'function')\n    throw new TypeError('need wrapper function')\n\n  Object.keys(fn).forEach(function (k) {\n    wrapper[k] = fn[k]\n  })\n\n  return wrapper\n\n  function wrapper() {\n    var args = new Array(arguments.length)\n    for (var i = 0; i < args.length; i++) {\n      args[i] = arguments[i]\n    }\n    var ret = fn.apply(this, args)\n    var cb = args[args.length-1]\n    if (typeof ret === 'function' && ret !== cb) {\n      Object.keys(cb).forEach(function (k) {\n        ret[k] = cb[k]\n      })\n    }\n    return ret\n  }\n}\n\n},{}]},{},[7])(7)\n});"
  },
  {
    "path": "site/book/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\" class=\"no-js\"><head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n      \n      \n        <link rel=\"canonical\" href=\"https://100go.co/book/\">\n      \n      \n        <link rel=\"prev\" href=\"../pt-br/\">\n      \n      \n        <link rel=\"next\" href=\"../chapter-1/\">\n      \n      \n      <link rel=\"icon\" href=\"../img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>100 Go Mistakes and How to Avoid Them - 100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"../assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\"..\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n      \n        <meta property=\"og:type\" content=\"website\">\n      \n        <meta property=\"og:title\" content=\"100 Go Mistakes and How to Avoid Them - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta property=\"og:description\" content=\"None\">\n      \n        <meta property=\"og:image\" content=\"https://100go.co/assets/images/social/book.png\">\n      \n        <meta property=\"og:image:type\" content=\"image/png\">\n      \n        <meta property=\"og:image:width\" content=\"1200\">\n      \n        <meta property=\"og:image:height\" content=\"630\">\n      \n        <meta property=\"og:url\" content=\"https://100go.co/book/\">\n      \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n      \n        <meta name=\"twitter:title\" content=\"100 Go Mistakes and How to Avoid Them - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta name=\"twitter:description\" content=\"None\">\n      \n        <meta name=\"twitter:image\" content=\"https://100go.co/assets/images/social/book.png\">\n      \n    \n    \n  <link href=\"../assets/stylesheets/glightbox.min.css\" rel=\"stylesheet\"><script src=\"../assets/javascripts/glightbox.min.js\"></script><style id=\"glightbox-style\">\n            html.glightbox-open { overflow: initial; height: 100%; }\n            .gslide-title { margin-top: 0px; user-select: text; }\n            .gslide-desc { color: #666; user-select: text; }\n            .gslide-image img { background: white; }\n            .gscrollbar-fixer { padding-right: 15px; }\n            .gdesc-inner { font-size: 0.75rem; }\n            body[data-md-color-scheme=\"slate\"] .gdesc-inner { background: var(--md-default-bg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-title { color: var(--md-default-fg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-desc { color: var(--md-default-fg-color); }\n        </style></head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n        \n        <a href=\"#100-go-mistakes-and-how-to-avoid-them\" class=\"md-skip\">\n          Skip to content\n        </a>\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"></path></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              100 Go Mistakes and How to Avoid Them\n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"></path></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"></path></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"></path></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"..\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n    \n  \n  \n    \n    \n      <li class=\"md-tabs__item md-tabs__item--active\">\n        <a href=\"./\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"..\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../5-interface-pollution/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../9-generics/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../20-slice/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../28-maps-memory-leaks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../56-concurrency-faster/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../89-benchmarks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../92-false-sharing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../98-profiling-execution-tracing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_3\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../zh/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../ja/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../pt-br/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n        \n        \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_2\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n    \n  \n  \n  \n    <li class=\"md-nav__item md-nav__item--active\">\n      \n      <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n      \n      \n        \n      \n      \n        <label class=\"md-nav__link md-nav__link--active\" for=\"__toc\">\n          \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n          <span class=\"md-nav__icon md-icon\"></span>\n        </label>\n      \n      <a href=\"./\" class=\"md-nav__link md-nav__link--active\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n      \n        \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#description\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Description\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#quotes-and-ratings\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Quotes and Ratings\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#where-to-buy\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Where to Buy?\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#about-the-author\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      About the Author\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../chapter-1/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../external/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\" hidden>\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#description\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Description\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#quotes-and-ratings\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Quotes and Ratings\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#where-to-buy\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Where to Buy?\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#about-the-author\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      About the Author\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n                  \n  \n\n\n\n  \n  \n\n\n<h1 id=\"100-go-mistakes-and-how-to-avoid-them\">100 Go Mistakes and How to Avoid Them</h1>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/cover.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/cover.png\"></a></p>\n<h2 id=\"description\">Description</h2>\n<p>If you're a Go developer looking to improve your skills, the <em>100 Go Mistakes and How to Avoid Them</em> book is for you. With a focus on practical examples, this book covers a wide range of topics from concurrency and error handling to testing and code organization. You'll learn to write more idiomatic, efficient, and maintainable code and become a proficient Go developer.</p>\n<p>Read a <a href=\"../\">summary</a> of the 100 mistakes or the <a href=\"../chapter-1/\">first chapter</a>.</p>\n<h2 id=\"quotes-and-ratings\">Quotes and Ratings</h2>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">Krystian (Goodreads user)</p>\n<p>This is an <strong>exceptional book</strong>. Usually, if a book contains either high-quality explanations or is written succinctly, I consider myself lucky to have found it. This one combines these two characteristics, which is <strong>super rare</strong>. It's another Go book for me and I still had quite a lot of \"a-ha!\" moments while reading it, and all of that without the unnecessary fluff, just straight to the point.</p>\n</div>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">Akash Chetty</p>\n<p>The book is completely <strong>exceptional</strong>, especially the examples carved out for each topic are really great. There is one topic that I struggled to understand is Concurrency but the way it is explained in this book is truly an art of genius.</p>\n</div>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">Neeraj Shah</p>\n<p>This should be the <strong>required reading</strong> for all Golang developers before they touch code in <strong>Production</strong>... It's the Golang equivalent of the legendary 'Effective Java' by Joshua Bloch.</p>\n</div>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">Anupam Sengupta</p>\n<p>Not having this will be the <strong>101st mistake</strong> a Go programmer could make.</p>\n</div>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/ratings-goodreads.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/ratings-goodreads.png\" width=\"300\"></a>\n  <a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/ratings-amazon.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/ratings-amazon.png\" width=\"300\"></a>\n  <a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/ratings-manning.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/ratings-manning.png\"></a>\n  </p>\n<figcaption>Manning, Goodreads, and Amazon reviews: 4.7/5 avg rating</figcaption>\n</figure>\n<h2 id=\"where-to-buy\">Where to Buy?</h2>\n<ul>\n<li>\n<p><em>100 Go Mistakes and How to Avoid Them</em> (🇬🇧 edition: paper, digital, or audiobook)</p>\n<ul>\n<li><a href=\"https://www.manning.com/books/100-go-mistakes-and-how-to-avoid-them\">Manning</a> (please make sure to use my personal discount code for -35%: <code>au35har</code>)</li>\n<li><a href=\"https://www.oreilly.com/library/view/100-go-mistakes/9781617299599/\">O’Reilly</a></li>\n<li>Amazon: <a href=\"https://www.amazon.com/dp/1617299596\">.com</a>, <a href=\"https://www.amazon.co.uk/dp/B0BBSNJR6B\">.co.uk</a>, <a href=\"https://www.amazon.de/dp/B0BBHQD8BQ\">.de</a>, <a href=\"https://www.amazon.fr/100-Mistakes-How-Avoid-Them/dp/1617299596\">.fr</a>, <a href=\"https://www.amazon.in/dp/B0BBHQD8BQ\">.in</a>, <a href=\"https://www.amazon.co.jp/dp/B0BBHQD8BQ\">.co.jp</a>, <a href=\"https://www.amazon.es/dp/B0BBHQD8BQ\">.es</a>, <a href=\"https://www.amazon.it/dp/B0BBHQD8BQ\">.it</a>, <a href=\"https://www.amazon.com.br/dp/B0BBHQD8BQ\">.com.br</a></li>\n</ul>\n</li>\n<li>\n<p><em>Go言語100Tips 開発者にありがちな間違いへの対処法</em> (🇯🇵 edition: paper or digital)</p>\n<ul>\n<li>Amazon: <a href=\"https://www.amazon.co.jp/exec/obidos/ASIN/4295017531/\">.co.jp</a></li>\n</ul>\n</li>\n<li>\n<p><em>100个Go语言典型错误</em> (🇨🇳 edition: paper or digital)</p>\n<ul>\n<li><a href=\"https://read.douban.com/ebook/455919353/\">Douban.com</a></li>\n</ul>\n</li>\n<li>\n<p><em>Go 100가지 실수 패턴과 솔루션</em> (🇰🇷 edition: paper or digital)</p>\n<ul>\n<li><a href=\"https://m.yes24.com/Goods/Detail/124158773\">Yes24.com</a></li>\n</ul>\n</li>\n</ul>\n<figure>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/cover-en.jpg\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/cover-en.jpg\" width=\"200\"></a>\n  <a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/cover-jp.jpg\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/cover-jp.jpg\" width=\"200\"></a>\n  <a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/cover-cn.jpg\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/cover-cn.jpg\" width=\"170\"></a>\n  <a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/cover-kr.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/cover-kr.png\" width=\"200\"></a>\n  </p>\n<figcaption>Covers (English, Japanese, Chinese, and Korean)</figcaption>\n</figure>\n<h2 id=\"about-the-author\">About the Author</h2>\n<p><a href=\"https://teivah.dev\">Teiva Harsanyi</a> is a senior software engineer at Google. He has worked in various domains, including insurance, transportation, and safety-critical industries like air traffic management. He is passionate about Go and how to design and implement reliable systems.</p>\n\n\n\n\n\n\n\n  \n  \n\n\n\n  \n\n\n  \n\n\n\n                \n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright © 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"></path></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \"..\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"../assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"../assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  \n<script id=\"init-glightbox\">const lightbox = GLightbox({\"touchNavigation\": true, \"loop\": false, \"zoomable\": true, \"draggable\": true, \"openEffect\": \"zoom\", \"closeEffect\": \"zoom\", \"slideEffect\": \"slide\"});\ndocument$.subscribe(()=>{ lightbox.reload(); });\n</script></body></html>"
  },
  {
    "path": "site/chapter-1/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\" class=\"no-js\"><head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n      \n      \n        <link rel=\"canonical\" href=\"https://100go.co/chapter-1/\">\n      \n      \n        <link rel=\"prev\" href=\"../book/\">\n      \n      \n        <link rel=\"next\" href=\"../external/\">\n      \n      \n      <link rel=\"icon\" href=\"../img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>Read the First Chapter - 100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"../assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\"..\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n      \n        <meta property=\"og:type\" content=\"website\">\n      \n        <meta property=\"og:title\" content=\"Read the First Chapter - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta property=\"og:description\" content=\"None\">\n      \n        <meta property=\"og:image\" content=\"https://100go.co/assets/images/social/chapter-1.png\">\n      \n        <meta property=\"og:image:type\" content=\"image/png\">\n      \n        <meta property=\"og:image:width\" content=\"1200\">\n      \n        <meta property=\"og:image:height\" content=\"630\">\n      \n        <meta property=\"og:url\" content=\"https://100go.co/chapter-1/\">\n      \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n      \n        <meta name=\"twitter:title\" content=\"Read the First Chapter - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta name=\"twitter:description\" content=\"None\">\n      \n        <meta name=\"twitter:image\" content=\"https://100go.co/assets/images/social/chapter-1.png\">\n      \n    \n    \n  <link href=\"../assets/stylesheets/glightbox.min.css\" rel=\"stylesheet\"><script src=\"../assets/javascripts/glightbox.min.js\"></script><style id=\"glightbox-style\">\n            html.glightbox-open { overflow: initial; height: 100%; }\n            .gslide-title { margin-top: 0px; user-select: text; }\n            .gslide-desc { color: #666; user-select: text; }\n            .gslide-image img { background: white; }\n            .gscrollbar-fixer { padding-right: 15px; }\n            .gdesc-inner { font-size: 0.75rem; }\n            body[data-md-color-scheme=\"slate\"] .gdesc-inner { background: var(--md-default-bg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-title { color: var(--md-default-fg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-desc { color: var(--md-default-fg-color); }\n        </style></head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n        \n        <a href=\"#go-simple-to-learn-but-hard-to-master\" class=\"md-skip\">\n          Skip to content\n        </a>\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"></path></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              Read the First Chapter\n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"></path></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"></path></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"></path></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"..\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n    \n  \n  \n    \n    \n      <li class=\"md-tabs__item md-tabs__item--active\">\n        <a href=\"../book/\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"..\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../5-interface-pollution/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../9-generics/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../20-slice/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../28-maps-memory-leaks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../56-concurrency-faster/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../89-benchmarks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../92-false-sharing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../98-profiling-execution-tracing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_3\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../zh/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../ja/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../pt-br/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n        \n        \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_2\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../book/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    <li class=\"md-nav__item md-nav__item--active\">\n      \n      <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n      \n      \n        \n      \n      \n        <label class=\"md-nav__link md-nav__link--active\" for=\"__toc\">\n          \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n          <span class=\"md-nav__icon md-icon\"></span>\n        </label>\n      \n      <a href=\"./\" class=\"md-nav__link md-nav__link--active\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n      \n        \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#go-outline\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Go outline\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#simple-doesnt-mean-easy\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Simple doesn’t mean easy\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#100-go-mistakes\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      100 Go mistakes\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"100 Go mistakes\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#bugs\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Bugs\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#needless-complexity\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Needless complexity\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#weaker-readability\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Weaker readability\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#suboptimal-or-unidiomatic-organization\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Suboptimal or unidiomatic organization\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#lack-of-api-convenience\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Lack of API convenience\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#under-optimized-code\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Under-optimized code\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#lack-of-productivity\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Lack of productivity\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#summary\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Summary\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../external/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n                \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\" hidden>\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#go-outline\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Go outline\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#simple-doesnt-mean-easy\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Simple doesn’t mean easy\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#100-go-mistakes\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      100 Go mistakes\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"100 Go mistakes\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#bugs\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Bugs\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#needless-complexity\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Needless complexity\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#weaker-readability\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Weaker readability\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#suboptimal-or-unidiomatic-organization\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Suboptimal or unidiomatic organization\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#lack-of-api-convenience\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Lack of API convenience\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#under-optimized-code\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Under-optimized code\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#lack-of-productivity\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Lack of productivity\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#summary\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Summary\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n                  \n  \n\n\n\n  \n  \n\n\n<h1 id=\"go-simple-to-learn-but-hard-to-master\">Go: Simple to learn but hard to master</h1>\n<p>This chapter covers</p>\n<ul>\n<li>What makes Go an efficient, scalable, and productive language</li>\n<li>Exploring why Go is simple to learn but hard to master</li>\n<li>Presenting the common types of mistakes made by developers</li>\n</ul>\n<p>Making mistakes is part of everyone’s life. As Albert Einstein once said,</p>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">Albert Einstein</p>\n<p>A person who never made a mistake never tried anything new.</p>\n</div>\n<p>What matters in the end isn’t the number of mistakes we make, but our capacity to learn from them. This assertion also applies to programming. The seniority we acquire in a language isn’t a magical process; it involves making many mistakes and learning from them. The purpose of this book is centered around this idea. It will help you, the reader, become a more proficient Go developer by looking at and learning from 100 common mistakes people make in many areas of the language.</p>\n<p>This chapter presents a quick refresher as to why Go has become mainstream over the years. We’ll discuss why, despite Go being considered simple to learn, mastering its nuances can be challenging. Finally, we’ll introduce the concepts this book covers.</p>\n<h2 id=\"go-outline\">Go outline</h2>\n<p>If you are reading this book, it’s likely that you’re already sold on Go. Therefore, this section provides a brief reminder about what makes Go such a powerful language.</p>\n<p>Software engineering has evolved considerably during the past decades. Most modern systems are no longer written by a single person but by teams consisting of multiple programmers—sometimes even hundreds, if not thousands. Nowadays, code must be readable, expressive, and maintainable to guarantee a system’s durability over the years. Meanwhile, in our fast-moving world, maximizing agility and reducing the time to market is critical for most organizations. Programming should also follow this trend, and companies strive to ensure that software engineers are as productive as possible when reading, writing, and maintaining code.</p>\n<p>In response to these challenges, Google created the Go programming language in 2007. Since then, many organizations have adopted the language to support various use cases: APIs, automation, databases, CLIs (command-line interfaces), and so on. Many today consider Go the language of the cloud.</p>\n<p>Feature-wise, Go has no type inheritance, no exceptions, no macros, no partial functions, no support for lazy variable evaluation or immutability, no operator overloading, no pattern matching, and on and on. Why are these features missing from the language? The official <a href=\"https://go.dev/doc/faq\">Go FAQ</a> gives us some insight:</p>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">Go FAQ</p>\n<p>Why does Go not have feature X? Your favorite feature may be missing because it doesn’t fit, because it affects compilation speed or clarity of design, or because it would make the fundamental system model too difficult.</p>\n</div>\n<p>Judging the quality of a programming language via its number of features is probably not an accurate metric. At least, it’s not an objective of Go. Instead, Go utilizes a few essential characteristics when adopting a language at scale for an organization. These include the following:</p>\n<ul>\n<li><em>Stability</em>—Even though Go receives frequent updates (including improvements and security patches), it remains a stable language. Some may even consider this one of the best features of the language.</li>\n<li><em>Expressivity</em>—We can define expressivity in a programming language by how naturally and intuitively we can write and read code. A reduced number of keywords and limited ways to solve common problems make Go an expressive language for large codebases.</li>\n<li><em>Compilation</em>—As developers, what can be more exasperating than having to wait for a build to test our application? Targeting fast compilation times has always been a conscious goal for the language designers. This, in turn, enables productivity.</li>\n<li><em>Safety</em>—Go is a strong, statically typed language. Hence, it has strict compiletime rules, which ensure the code is type-safe in most cases.</li>\n</ul>\n<p>Go was built from the ground up with solid features such as outstanding concurrency primitives with goroutines and channels. There’s not a strong need to rely on external libraries to build efficient concurrent applications. Observing how important concurrency is these days also demonstrates why Go is such a suitable language for the present and probably for the foreseeable future.</p>\n<p>Some also consider Go a simple language. And, in a sense, this isn’t necessarily wrong. For example, a newcomer can learn the language’s main features in less than a day. So why read a book centered on the concept of mistakes if Go is simple?</p>\n<h2 id=\"simple-doesnt-mean-easy\">Simple doesn’t mean easy</h2>\n<p>There is a subtle difference between simple and easy. <em>Simple</em>, applied to a technology, means not complicated to learn or understand. However, <em>easy</em> means that we can achieve anything without much effort. Go is simple to learn but not necessarily easy to master.</p>\n<p>Let’s take concurrency, for example. In 2019, a study focusing on concurrency bugs was published: <a href=\"https://songlh.github.io/paper/go-study.pdf\">Understanding Real-World Concurrency Bugs in Go</a>. This study was the first systematic analysis of concurrency bugs. It focused on multiple popular Go repositories such as Docker, gRPC, and Kubernetes. One of the most important takeaways from this study is that most of the blocking bugs are caused by inaccurate use of the message-passing paradigm via channels, despite the belief that message passing is easier to handle and less error-prone than sharing memory.</p>\n<p>What should be an appropriate reaction to such a takeaway? Should we consider that the language designers were wrong about message passing? Should we reconsider how we deal with concurrency in our project? Of course not.</p>\n<p>It’s not a question of confronting message passing versus sharing memory and determining the winner. However, it’s up to us as Go developers to thoroughly understand how to use concurrency, its implications on modern processors, when to favor one approach over the other, and how to avoid common traps. This example highlights that although a concept such as channels and goroutines can be simple to learn, it isn’t an easy topic in practice.</p>\n<p>This leitmotif—simple doesn’t mean easy—can be generalized to many aspects of Go, not only concurrency. Hence, to be proficient Go developers, we must have a thorough understanding of many aspects of the language, which requires time, effort, and mistakes.</p>\n<p>This book aims to help accelerate our journey toward proficiency by delving into 100 Go mistakes.</p>\n<h2 id=\"100-go-mistakes\">100 Go mistakes</h2>\n<p>Why should we read a book about common Go mistakes? Why not deepen our knowledge with an ordinary book that would dig into different topics?</p>\n<p>In a 2011 article, neuroscientists proved that the best time for brain growth is when we’re facing mistakes. <sup id=\"fnref:1\"><a class=\"footnote-ref\" href=\"#fn:1\">1</a></sup> Haven’t we all experienced the process of learning from a mistake and recalling that occasion after months or even years, when some context related to it? As presented in another article, by Janet Metcalfe, this happens because mistakes have a facilitative effect. <sup id=\"fnref:2\"><a class=\"footnote-ref\" href=\"#fn:2\">2</a></sup> The main idea is that we can remember not only the error but also the context surrounding the mistake. This is one of the reasons why learning from mistakes is so efficient.</p>\n<p>To strengthen this facilitative effect, this book accompanies each mistake as much as possible with real-world examples. This book isn’t only about theory; it also helps us get better at avoiding mistakes and making more well-informed, conscious decisions because we now understand the rationale behind them.</p>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">Unknown</p>\n<p>Tell me and I forget. Teach me and I remember. Involve me and I learn.</p>\n</div>\n<p>This book presents seven main categories of mistakes. Overall, the mistakes can be classified as</p>\n<ul>\n<li>Bugs</li>\n<li>Needless complexity</li>\n<li>Weaker readability</li>\n<li>Suboptimal or unidiomatic organization </li>\n<li>Lack of API convenience</li>\n<li>Under-optimized code</li>\n<li>Lack of productivity</li>\n</ul>\n<p>We introduce each mistake category next.</p>\n<h3 id=\"bugs\">Bugs</h3>\n<p>The first type of mistake and probably the most obvious is software bugs. In 2020, a study conducted by Synopsys estimated the cost of software bugs in the U.S. alone to be over $2 trillion. <sup id=\"fnref:3\"><a class=\"footnote-ref\" href=\"#fn:3\">3</a></sup></p>\n<p>Furthermore, bugs can also lead to tragic impacts. We can, for example, mention cases such as Therac-25, a radiation therapy machine produced by Atomic Energy of Canada Limited (AECL). Because of a race condition, the machine gave its patients radiation doses that were hundreds of times greater than expected, leading to the death of three patients. Hence, software bugs aren’t only about money. As developers, we should remember how impactful our jobs are.</p>\n<p>This book covers plenty of cases that could lead to various software bugs, including data races, leaks, logic errors, and other defects. Although accurate tests should be a way to discover such bugs as early as possible, we may sometimes miss cases because of different factors such as time constraints or complexity. Therefore, as a Go developer, it’s essential to make sure we avoid common bugs.</p>\n<h3 id=\"needless-complexity\">Needless complexity</h3>\n<p>The next category of mistakes is related to unnecessary complexity. A significant part of software complexity comes from the fact that, as developers, we strive to think about imaginary futures. Instead of solving concrete problems right now, it can be tempting to build evolutionary software that could tackle whatever future use case arises. However, this leads to more drawbacks than benefits in most cases because it can make a codebase more complex to understand and reason about.</p>\n<p>Getting back to Go, we can think of plenty of use cases where developers might be tempted to design abstractions for future needs, such as interfaces or generics. This book discusses topics where we should remain careful not to harm a codebase with needless complexity.</p>\n<h3 id=\"weaker-readability\">Weaker readability</h3>\n<p>Another kind of mistake is to weaken readability. As Robert C. Martin wrote in his book <em>Clean Code: A Handbook of Agile Software Craftsmanship</em>, the ratio of time spent reading versus writing is well over 10 to 1. Most of us started to program on solo projects where readability wasn’t that important. However, today’s software engineering is programming with a time dimension: making sure we can still work with and maintain an application months, years, or perhaps even decades later.</p>\n<p>When programming in Go, we can make many mistakes that can harm readability. These mistakes may include nested code, data type representations, or not using named result parameters in some cases. Throughout this book, we will learn how to write readable code and care for future readers (including our future selves).</p>\n<h3 id=\"suboptimal-or-unidiomatic-organization\">Suboptimal or unidiomatic organization</h3>\n<p>Be it while working on a new project or because we acquire inaccurate reflexes, another type of mistake is organizing our code and a project suboptimally and unidiomatically. Such issues can make a project harder to reason about and maintain. This book covers some of these common mistakes in Go. For example, we’ll look at how to structure a project and deal with utility packages or init functions. All in all, looking at these mistakes should help us organize our code and projects more efficiently and idiomatically.</p>\n<h3 id=\"lack-of-api-convenience\">Lack of API convenience</h3>\n<p>Making common mistakes that weaken how convenient an API is for our clients is another type of mistake. If an API isn’t user-friendly, it will be less expressive and, hence, harder to understand and more error-prone.</p>\n<p>We can think about many situations such as overusing any types, using the wrong creational pattern to deal with options, or blindly applying standard practices from object-oriented programming that affect the usability of our APIs. This book covers common mistakes that prevent us from exposing convenient APIs for our users.</p>\n<h3 id=\"under-optimized-code\">Under-optimized code</h3>\n<p>Under-optimized code is another type of mistake made by developers. It can happen for various reasons, such as not understanding language features or even a lack of fundamental knowledge. Performance is one of the most obvious impacts of this mistake, but not the only one.</p>\n<p>We can think about optimizing code for other goals, such as accuracy. For example, this book provides some common techniques to ensure that floating-point operations are accurate. Meanwhile, we will cover plenty of cases that can negatively impact performance code because of poorly parallelized executions, not knowing how to reduce allocations, or the impacts of data alignment, for example. We will tackle optimization via different prisms.</p>\n<h3 id=\"lack-of-productivity\">Lack of productivity</h3>\n<p>In most cases, what’s the best language we can choose when working on a new project? The one we’re the most productive with. Being comfortable with how a language works and exploiting it to get the best out of it is crucial to reach proficiency.</p>\n<p>In this book, we will cover many cases and concrete examples that will help us to be more productive while working in Go. For instance, we’ll look at writing efficient tests to ensure that our code works, relying on the standard library to be more effective, and getting the best out of the profiling tools and linters. Now, it’s time to delve into those 100 common Go mistakes.</p>\n<h2 id=\"summary\">Summary</h2>\n<ul>\n<li>Go is a modern programming language that enables developer productivity, which is crucial for most companies today.</li>\n<li>Go is simple to learn but not easy to master. This is why we need to deepen our knowledge to make the most effective use of the language.</li>\n<li>Learning via mistakes and concrete examples is a powerful way to be proficient in a language. This book will accelerate our path to proficiency by exploring 100 common mistakes.</li>\n</ul>\n<div class=\"footnote\">\n<hr>\n<ol>\n<li id=\"fn:1\">\n<p>J. S. Moser, H. S. Schroder, et al., “Mind Your Errors: Evidence for a Neural Mechanism Linking Growth Mindset to Adaptive Posterror Adjustments,” Psychological Science, vol. 22, no. 12, pp. 1484–1489, Dec. 2011.&nbsp;<a class=\"footnote-backref\" href=\"#fnref:1\" title=\"Jump back to footnote 1 in the text\">↩</a></p>\n</li>\n<li id=\"fn:2\">\n<p>J. Metcalfe, “Learning from Errors,” Annual Review of Psychology, vol. 68, pp. 465–489, Jan. 2017.&nbsp;<a class=\"footnote-backref\" href=\"#fnref:2\" title=\"Jump back to footnote 2 in the text\">↩</a></p>\n</li>\n<li id=\"fn:3\">\n<p>Synopsys, “The Cost of Poor Software Quality in the US: A 2020 Report.” 2020. <a href=\"https://news.synopsys.com/2021-01-06-Synopsys-Sponsored-CISQ-Research-Estimates-Cost-of-Poor-Software-Quality-in-the-US-2-08-Trillion-in-2020\">https://news.synopsys.com/2021-01-06-Synopsys-Sponsored-CISQ-Research-Estimates-Cost-of-Poor-Software-Quality-in-the-US-2-08-Trillion-in-2020</a>.&nbsp;<a class=\"footnote-backref\" href=\"#fnref:3\" title=\"Jump back to footnote 3 in the text\">↩</a></p>\n</li>\n</ol>\n</div>\n\n\n\n\n\n\n\n  \n  \n\n\n\n  \n\n\n  \n\n\n\n                \n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright © 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"></path></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \"..\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"../assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"../assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  \n<script id=\"init-glightbox\">const lightbox = GLightbox({\"touchNavigation\": true, \"loop\": false, \"zoomable\": true, \"draggable\": true, \"openEffect\": \"zoom\", \"closeEffect\": \"zoom\", \"slideEffect\": \"slide\"});\ndocument$.subscribe(()=>{ lightbox.reload(); });\n</script></body></html>"
  },
  {
    "path": "site/external/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\" class=\"no-js\"><head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n      \n      \n        <link rel=\"canonical\" href=\"https://100go.co/external/\">\n      \n      \n        <link rel=\"prev\" href=\"../chapter-1/\">\n      \n      \n      \n      <link rel=\"icon\" href=\"../img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>External Resources - 100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"../assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\"..\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n      \n        <meta property=\"og:type\" content=\"website\">\n      \n        <meta property=\"og:title\" content=\"External Resources - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta property=\"og:description\" content=\"None\">\n      \n        <meta property=\"og:image\" content=\"https://100go.co/assets/images/social/external.png\">\n      \n        <meta property=\"og:image:type\" content=\"image/png\">\n      \n        <meta property=\"og:image:width\" content=\"1200\">\n      \n        <meta property=\"og:image:height\" content=\"630\">\n      \n        <meta property=\"og:url\" content=\"https://100go.co/external/\">\n      \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n      \n        <meta name=\"twitter:title\" content=\"External Resources - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta name=\"twitter:description\" content=\"None\">\n      \n        <meta name=\"twitter:image\" content=\"https://100go.co/assets/images/social/external.png\">\n      \n    \n    \n  <link href=\"../assets/stylesheets/glightbox.min.css\" rel=\"stylesheet\"><script src=\"../assets/javascripts/glightbox.min.js\"></script><style id=\"glightbox-style\">\n            html.glightbox-open { overflow: initial; height: 100%; }\n            .gslide-title { margin-top: 0px; user-select: text; }\n            .gslide-desc { color: #666; user-select: text; }\n            .gslide-image img { background: white; }\n            .gscrollbar-fixer { padding-right: 15px; }\n            .gdesc-inner { font-size: 0.75rem; }\n            body[data-md-color-scheme=\"slate\"] .gdesc-inner { background: var(--md-default-bg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-title { color: var(--md-default-fg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-desc { color: var(--md-default-fg-color); }\n        </style></head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n        \n        <a href=\"#external-resources\" class=\"md-skip\">\n          Skip to content\n        </a>\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"></path></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              External Resources\n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"></path></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"></path></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"></path></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"..\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n    \n  \n  \n    \n    \n      <li class=\"md-tabs__item md-tabs__item--active\">\n        <a href=\"../book/\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"..\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../5-interface-pollution/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../9-generics/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../20-slice/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../28-maps-memory-leaks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../56-concurrency-faster/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../89-benchmarks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../92-false-sharing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../98-profiling-execution-tracing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_3\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../zh/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../ja/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../pt-br/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n        \n        \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_2\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../book/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../chapter-1/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    <li class=\"md-nav__item md-nav__item--active\">\n      \n      <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n      \n      \n        \n      \n      \n        <label class=\"md-nav__link md-nav__link--active\" for=\"__toc\">\n          \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n          <span class=\"md-nav__icon md-icon\"></span>\n        </label>\n      \n      <a href=\"./\" class=\"md-nav__link md-nav__link--active\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n      \n        \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#english\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      English\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"English\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#the-best-golang-book-prime-reacts\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      The Best Golang Book | Prime Reacts\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#book-review-100-go-mistakes-and-how-to-avoid-them\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Book Review: 100 Go Mistakes (And How to Avoid Them)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#the-most-useful-book-for-a-go-programmer\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      The Most Useful Book for a Go Programmer?\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#how-to-make-mistakes-in-go-go-time-190\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      How to make mistakes in Go - Go Time #190\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-is-amazing\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Go is AMAZING\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#8lu-100-test-coverage\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      8LU - 100% Test Coverage\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#some-tips-i-learned-from-100-mistakes-in-go\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Some Tips I learned from 100 Mistakes in Go\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#what-can-be-summarized-from-100-go-mistakes\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      What can be summarized from 100 Go Mistakes?\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#book-review-100-go-mistakes-and-how-to-avoid-them_1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Book review: 100 Go Mistakes and How to Avoid Them\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#chinese\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Chinese\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Chinese\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#100-go-mistakes-and-how-to-avoid-them\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      深度阅读之《100 Go Mistakes and How to Avoid Them\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#100-go-mistakes\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      100 Go Mistakes 随记\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      我为什么放弃Go语言？\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#japanese\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Japanese\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Japanese\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go100-go-mistakes-and-how-to-avoid-them\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      最近読んだGo言語の本の紹介：100 Go Mistakes and How to Avoid Them\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#100-go-mistakes-and-how-to-avoid-them_1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      『100 Go Mistakes and How to Avoid Them』を読む\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#portuguese\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Portuguese\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Portuguese\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#um-otimo-livro-para-programadores-go\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Um ÓTIMO livro para programadores Go\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#english\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      English\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"English\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#the-best-golang-book-prime-reacts\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      The Best Golang Book | Prime Reacts\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#book-review-100-go-mistakes-and-how-to-avoid-them\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Book Review: 100 Go Mistakes (And How to Avoid Them)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#the-most-useful-book-for-a-go-programmer\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      The Most Useful Book for a Go Programmer?\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#how-to-make-mistakes-in-go-go-time-190\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      How to make mistakes in Go - Go Time #190\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-is-amazing\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Go is AMAZING\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#8lu-100-test-coverage\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      8LU - 100% Test Coverage\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#some-tips-i-learned-from-100-mistakes-in-go\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Some Tips I learned from 100 Mistakes in Go\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#what-can-be-summarized-from-100-go-mistakes\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      What can be summarized from 100 Go Mistakes?\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#book-review-100-go-mistakes-and-how-to-avoid-them_1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Book review: 100 Go Mistakes and How to Avoid Them\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#chinese\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Chinese\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Chinese\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#100-go-mistakes-and-how-to-avoid-them\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      深度阅读之《100 Go Mistakes and How to Avoid Them\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#100-go-mistakes\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      100 Go Mistakes 随记\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      我为什么放弃Go语言？\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#japanese\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Japanese\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Japanese\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go100-go-mistakes-and-how-to-avoid-them\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      最近読んだGo言語の本の紹介：100 Go Mistakes and How to Avoid Them\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#100-go-mistakes-and-how-to-avoid-them_1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      『100 Go Mistakes and How to Avoid Them』を読む\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#portuguese\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Portuguese\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Portuguese\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#um-otimo-livro-para-programadores-go\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Um ÓTIMO livro para programadores Go\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n                  \n\n\n  \n  \n\n\n<h1 id=\"external-resources\">External Resources</h1>\n<h2 id=\"english\">English</h2>\n<h3 id=\"the-best-golang-book-prime-reacts\">The Best Golang Book | Prime Reacts</h3>\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/a-lYYYr-5a8?si=hWm7um5GS19KVbog\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n\n<h3 id=\"book-review-100-go-mistakes-and-how-to-avoid-them\">Book Review: 100 Go Mistakes (And How to Avoid Them)</h3>\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/tcRYU9g5wtw?si=2s10hXwxL7ButfRm\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n\n<p><a href=\"https://boldlygo.tech/posts/2023-08-09-review-100-go-mistakes/\">Post</a></p>\n<h3 id=\"the-most-useful-book-for-a-go-programmer\">The Most Useful Book for a Go Programmer?</h3>\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/8pqgv4_Yjq0?si=CunG1j2Uh2isXm4b\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n\n<h3 id=\"how-to-make-mistakes-in-go-go-time-190\">How to make mistakes in Go - Go Time #190</h3>\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/VGOgDqDe30E?si=HErewJsxDjie92AU\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n\n<ul>\n<li><a href=\"https://changelog.com/gotime/190\">Episode</a></li>\n<li><a href=\"https://open.spotify.com/episode/0K1DImrxHCy6E7zVY4AxMZ?si=akroInsPQ1mM5B5V2tHLUw&amp;dl_branch=1\">Spotify</a></li>\n</ul>\n<h3 id=\"go-is-amazing\">Go is AMAZING</h3>\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/iQBdVqnB0Ss?si=6lX1-oj28s_OZPwp&amp;start=281\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n\n<h3 id=\"8lu-100-test-coverage\">8LU - 100% Test Coverage</h3>\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/V3FBDav6wgQ?si=iA58zxZHQewKF6Jz&amp;start=1210\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n\n<h3 id=\"some-tips-i-learned-from-100-mistakes-in-go\">Some Tips I learned from 100 Mistakes in Go</h3>\n<p><a href=\"https://raygervais.dev/articles/2023/04/100_mistakes_in_go/\">Post</a></p>\n<h3 id=\"what-can-be-summarized-from-100-go-mistakes\">What can be summarized from 100 Go Mistakes?</h3>\n<p><a href=\"https://www.sobyte.net/post/2023-05/summarized-from-100-go-mistakes/\">Post</a></p>\n<h3 id=\"book-review-100-go-mistakes-and-how-to-avoid-them_1\">Book review: 100 Go Mistakes and How to Avoid Them</h3>\n<p><a href=\"https://schfkt.dev/blog/book-10-go-mistakes/\">Post</a></p>\n<h2 id=\"chinese\">Chinese</h2>\n<h3 id=\"100-go-mistakes-and-how-to-avoid-them\">深度阅读之《100 Go Mistakes and How to Avoid Them</h3>\n<p><a href=\"https://qcrao.com/post/100-go-mistakes-reading-notes/\">Post</a></p>\n<h3 id=\"100-go-mistakes\">100 Go Mistakes 随记</h3>\n<p><a href=\"https://zhuanlan.zhihu.com/p/592602656\">Post</a></p>\n<h3 id=\"go\">我为什么放弃Go语言？</h3>\n<p><a href=\"https://juejin.cn/post/7241452578125824061\">Post</a></p>\n<h2 id=\"japanese\">Japanese</h2>\n<h3 id=\"go100-go-mistakes-and-how-to-avoid-them\">最近読んだGo言語の本の紹介：100 Go Mistakes and How to Avoid Them</h3>\n<p><a href=\"https://qiita.com/kentaro_suzuki/items/c9c31dc81217f237433c\">Post</a></p>\n<h3 id=\"100-go-mistakes-and-how-to-avoid-them_1\">『100 Go Mistakes and How to Avoid Them』を読む</h3>\n<p><a href=\"https://zenn.dev/yukibobier/books/066f07c8a59fa0\">Post</a></p>\n<h2 id=\"portuguese\">Portuguese</h2>\n<h3 id=\"um-otimo-livro-para-programadores-go\">Um ÓTIMO livro para programadores Go</h3>\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/34XShL_jWD4?si=WQZR3QexpwEZ9-EU\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n\n\n\n\n\n\n\n  \n  \n\n\n\n  \n\n\n\n\n                \n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright © 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"></path></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \"..\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"../assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"../assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  \n<script id=\"init-glightbox\">const lightbox = GLightbox({\"touchNavigation\": true, \"loop\": false, \"zoomable\": true, \"draggable\": true, \"openEffect\": \"zoom\", \"closeEffect\": \"zoom\", \"slideEffect\": \"slide\"});\ndocument$.subscribe(()=>{ lightbox.reload(); });\n</script></body></html>"
  },
  {
    "path": "site/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\" class=\"no-js\"><head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n        <meta name=\"description\" content=\"Summary of the mistakes in the 100 Go Mistakes book.\">\n      \n      \n      \n        <link rel=\"canonical\" href=\"https://100go.co/\">\n      \n      \n      \n        <link rel=\"next\" href=\"5-interface-pollution/\">\n      \n      \n      <link rel=\"icon\" href=\"img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>Common Go Mistakes - 100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\".\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n      \n        <meta property=\"og:type\" content=\"website\">\n      \n        <meta property=\"og:title\" content=\"Common Go Mistakes - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta property=\"og:description\" content=\"Summary of the mistakes in the 100 Go Mistakes book.\">\n      \n        <meta property=\"og:image\" content=\"https://100go.co/assets/images/social/index.png\">\n      \n        <meta property=\"og:image:type\" content=\"image/png\">\n      \n        <meta property=\"og:image:width\" content=\"1200\">\n      \n        <meta property=\"og:image:height\" content=\"630\">\n      \n        <meta property=\"og:url\" content=\"https://100go.co/\">\n      \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n      \n        <meta name=\"twitter:title\" content=\"Common Go Mistakes - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta name=\"twitter:description\" content=\"Summary of the mistakes in the 100 Go Mistakes book.\">\n      \n        <meta name=\"twitter:image\" content=\"https://100go.co/assets/images/social/index.png\">\n      \n    \n    \n  <link href=\"assets/stylesheets/glightbox.min.css\" rel=\"stylesheet\"><script src=\"assets/javascripts/glightbox.min.js\"></script><style id=\"glightbox-style\">\n            html.glightbox-open { overflow: initial; height: 100%; }\n            .gslide-title { margin-top: 0px; user-select: text; }\n            .gslide-desc { color: #666; user-select: text; }\n            .gslide-image img { background: white; }\n            .gscrollbar-fixer { padding-right: 15px; }\n            .gdesc-inner { font-size: 0.75rem; }\n            body[data-md-color-scheme=\"slate\"] .gdesc-inner { background: var(--md-default-bg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-title { color: var(--md-default-fg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-desc { color: var(--md-default-fg-color); }\n        </style></head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n        \n        <a href=\"#common-go-mistakes\" class=\"md-skip\">\n          Skip to content\n        </a>\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\".\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"></path></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              Common Go Mistakes\n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"></path></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"></path></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"></path></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n    \n  \n  \n    \n    \n      <li class=\"md-tabs__item md-tabs__item--active\">\n        <a href=\".\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"book/\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\".\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n        \n        \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n    \n  \n  \n  \n    <li class=\"md-nav__item md-nav__item--active\">\n      \n      <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n      \n      \n        \n      \n      \n        <label class=\"md-nav__link md-nav__link--active\" for=\"__toc\">\n          \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n          <span class=\"md-nav__icon md-icon\"></span>\n        </label>\n      \n      <a href=\".\" class=\"md-nav__link md-nav__link--active\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n      \n        \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#code-and-project-organization\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Code and Project Organization\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Code and Project Organization\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#unintended-variable-shadowing-1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Unintended variable shadowing (#1)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#unnecessary-nested-code-2\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Unnecessary nested code (#2)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#misusing-init-functions-3\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Misusing init functions (#3)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#overusing-getters-and-setters-4\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Overusing getters and setters (#4)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#interface-pollution-5\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Interface pollution (#5)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#interface-on-the-producer-side-6\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Interface on the producer side (#6)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#returning-interfaces-7\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Returning interfaces (#7)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#any-says-nothing-8\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      any says nothing (#8)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#being-confused-about-when-to-use-generics-9\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Being confused about when to use generics (#9)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-being-aware-of-the-possible-problems-with-type-embedding-10\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not being aware of the possible problems with type embedding (#10)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-the-functional-options-pattern-11\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using the functional options pattern (#11)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#project-misorganization-project-structure-and-package-organization-12\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Project misorganization (project structure and package organization) (#12)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#creating-utility-packages-13\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Creating utility packages (#13)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignoring-package-name-collisions-14\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignoring package name collisions (#14)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#missing-code-documentation-15\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Missing code documentation (#15)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-linters-16\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using linters (#16)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#data-types\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Data Types\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Data Types\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#creating-confusion-with-octal-literals-17\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Creating confusion with octal literals (#17)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#neglecting-integer-overflows-18\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Neglecting integer overflows (#18)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-floating-points-19\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding floating-points (#19)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-slice-length-and-capacity-20\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding slice length and capacity (#20)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#inefficient-slice-initialization-21\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Inefficient slice initialization (#21)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#being-confused-about-nil-vs-empty-slice-22\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Being confused about nil vs. empty slice (#22)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-properly-checking-if-a-slice-is-empty-23\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not properly checking if a slice is empty (#23)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-making-slice-copies-correctly-24\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not making slice copies correctly (#24)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#unexpected-side-effects-using-slice-append-25\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Unexpected side effects using slice append (#25)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slices-and-memory-leaks-26\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Slices and memory leaks (#26)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Slices and memory leaks (#26)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#leaking-capacity\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Leaking capacity\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-and-pointers\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Slice and pointers\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#inefficient-map-initialization-27\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Inefficient map initialization (#27)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#maps-and-memory-leaks-28\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Maps and memory leaks (#28)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#comparing-values-incorrectly-29\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Comparing values incorrectly (#29)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#control-structures\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Control Structures\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Control Structures\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignoring-that-elements-are-copied-in-range-loops-30\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignoring that elements are copied in range loops (#30)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignoring-how-arguments-are-evaluated-in-range-loops-channels-and-arrays-31\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignoring how arguments are evaluated in range loops (channels and arrays) (#31)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignoring-the-impacts-of-using-pointer-elements-in-range-loops-32\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignoring the impacts of using pointer elements in range loops (#32)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#making-wrong-assumptions-during-map-iterations-ordering-and-map-insert-during-iteration-33\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Making wrong assumptions during map iterations (ordering and map insert during iteration) (#33)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignoring-how-the-break-statement-works-34\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignoring how the break statement works (#34)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#using-defer-inside-a-loop-35\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Using defer inside a loop (#35)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#strings\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Strings\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Strings\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-the-concept-of-rune-36\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding the concept of rune (#36)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#inaccurate-string-iteration-37\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Inaccurate string iteration (#37)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#misusing-trim-functions-38\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Misusing trim functions (#38)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#under-optimized-strings-concatenation-39\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Under-optimized strings concatenation (#39)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#useless-string-conversions-40\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Useless string conversions (#40)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#substring-and-memory-leaks-41\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Substring and memory leaks (#41)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#functions-and-methods\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Functions and Methods\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Functions and Methods\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-knowing-which-type-of-receiver-to-use-42\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not knowing which type of receiver to use (#42)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#never-using-named-result-parameters-43\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Never using named result parameters (#43)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#unintended-side-effects-with-named-result-parameters-44\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Unintended side effects with named result parameters (#44)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#returning-a-nil-receiver-45\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Returning a nil receiver (#45)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#using-a-filename-as-a-function-input-46\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Using a filename as a function input (#46)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignoring-how-defer-arguments-and-receivers-are-evaluated-argument-evaluation-pointer-and-value-receivers-47\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignoring how defer arguments and receivers are evaluated (argument evaluation, pointer, and value receivers) (#47)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#error-management\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Error Management\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Error Management\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#panicking-48\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Panicking (#48)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignoring-when-to-wrap-an-error-49\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignoring when to wrap an error (#49)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#comparing-an-error-type-inaccurately-50\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Comparing an error type inaccurately (#50)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#comparing-an-error-value-inaccurately-51\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Comparing an error value inaccurately (#51)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#handling-an-error-twice-52\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Handling an error twice (#52)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-handling-an-error-53\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not handling an error (#53)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-handling-defer-errors-54\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not handling defer errors (#54)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#concurrency-foundations\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Concurrency: Foundations\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Concurrency: Foundations\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#mixing-up-concurrency-and-parallelism-55\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Mixing up concurrency and parallelism (#55)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#thinking-concurrency-is-always-faster-56\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Thinking concurrency is always faster (#56)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#being-puzzled-about-when-to-use-channels-or-mutexes-57\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Being puzzled about when to use channels or mutexes (#57)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-race-problems-data-races-vs-race-conditions-and-the-go-memory-model-58\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding race problems (data races vs. race conditions and the Go memory model) (#58)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Not understanding race problems (data races vs. race conditions and the Go memory model) (#58)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#data-race\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Data Race\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#race-condition\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Race Condition\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-the-concurrency-impacts-of-a-workload-type-59\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding the concurrency impacts of a workload type (#59)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#misunderstanding-go-contexts-60\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Misunderstanding Go contexts (#60)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Misunderstanding Go contexts (#60)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#deadline\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Deadline\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#cancellation-signals\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Cancellation signals\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#context-values\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Context values\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#catching-a-context-cancellation\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Catching a context cancellation\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#concurrency-practice\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Concurrency: Practice\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Concurrency: Practice\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#propagating-an-inappropriate-context-61\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Propagating an inappropriate context (#61)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#starting-a-goroutine-without-knowing-when-to-stop-it-62\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Starting a goroutine without knowing when to stop it (#62)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-being-careful-with-goroutines-and-loop-variables-63\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not being careful with goroutines and loop variables (#63)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#expecting-a-deterministic-behavior-using-select-and-channels-64\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Expecting a deterministic behavior using select and channels (#64)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-notification-channels-65\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using notification channels (#65)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-nil-channels-66\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using nil channels (#66)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#being-puzzled-about-channel-size-67\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Being puzzled about channel size (#67)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#forgetting-about-possible-side-effects-with-string-formatting-68\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Forgetting about possible side effects with string formatting (#68)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Forgetting about possible side effects with string formatting (#68)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#etcd-data-race\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      etcd data race\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#deadlock\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Deadlock\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#creating-data-races-with-append-69\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Creating data races with append (#69)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#using-mutexes-inaccurately-with-slices-and-maps-70\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Using mutexes inaccurately with slices and maps (#70)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#misusing-syncwaitgroup-71\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Misusing sync.WaitGroup (#71)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#forgetting-about-synccond-72\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Forgetting about sync.Cond (#72)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-errgroup-73\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using errgroup (#73)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#copying-a-sync-type-74\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Copying a sync type (#74)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#standard-library\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Standard Library\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Standard Library\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#providing-a-wrong-time-duration-75\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Providing a wrong time duration (#75)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#timeafter-and-memory-leaks-76\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      time.After and memory leaks (#76)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#json-handling-common-mistakes-77\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      JSON handling common mistakes (#77)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#common-sql-mistakes-78\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Common SQL mistakes (#78)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-closing-transient-resources-http-body-sqlrows-and-osfile-79\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not closing transient resources (HTTP body, sql.Rows, and os.File) (#79)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#forgetting-the-return-statement-after-replying-to-an-http-request-80\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Forgetting the return statement after replying to an HTTP request (#80)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#using-the-default-http-client-and-server-81\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Using the default HTTP client and server (#81)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#testing\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Testing\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Testing\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-categorizing-tests-build-tags-environment-variables-and-short-mode-82\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not categorizing tests (build tags, environment variables, and short mode) (#82)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-enabling-the-race-flag-83\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not enabling the race flag (#83)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-test-execution-modes-parallel-and-shuffle-84\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using test execution modes (parallel and shuffle) (#84)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-table-driven-tests-85\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using table-driven tests (#85)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#sleeping-in-unit-tests-86\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Sleeping in unit tests (#86)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-dealing-with-the-time-api-efficiently-87\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not dealing with the time API efficiently (#87)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-testing-utility-packages-httptest-and-iotest-88\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using testing utility packages (httptest and iotest) (#88)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#writing-inaccurate-benchmarks-89\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Writing inaccurate benchmarks (#89)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-exploring-all-the-go-testing-features-90\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not exploring all the Go testing features (#90)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-fuzzing-community-mistake\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using fuzzing (community mistake)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#optimizations\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Optimizations\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Optimizations\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-cpu-caches-91\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding CPU caches (#91)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#writing-concurrent-code-that-leads-to-false-sharing-92\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Writing concurrent code that leads to false sharing (#92)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-taking-into-account-instruction-level-parallelism-93\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not taking into account instruction-level parallelism (#93)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-being-aware-of-data-alignment-94\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not being aware of data alignment (#94)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-stack-vs-heap-95\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding stack vs. heap (#95)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-knowing-how-to-reduce-allocations-api-change-compiler-optimizations-and-syncpool-96\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not knowing how to reduce allocations (API change, compiler optimizations, and sync.Pool) (#96)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-relying-on-inlining-97\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not relying on inlining (#97)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-go-diagnostics-tooling-98\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using Go diagnostics tooling (#98)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-how-the-gc-works-99\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding how the GC works (#99)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-the-impacts-of-running-go-in-docker-and-kubernetes-100\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding the impacts of running Go in Docker and Kubernetes (#100)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#community\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Community\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#powered-by\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Powered by\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"5-interface-pollution/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"9-generics/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"20-slice/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"28-maps-memory-leaks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"56-concurrency-faster/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"89-benchmarks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"92-false-sharing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"98-profiling-execution-tracing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_3\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"zh/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"ja/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"pt-br/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"book/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"chapter-1/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"external/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#code-and-project-organization\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Code and Project Organization\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Code and Project Organization\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#unintended-variable-shadowing-1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Unintended variable shadowing (#1)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#unnecessary-nested-code-2\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Unnecessary nested code (#2)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#misusing-init-functions-3\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Misusing init functions (#3)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#overusing-getters-and-setters-4\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Overusing getters and setters (#4)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#interface-pollution-5\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Interface pollution (#5)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#interface-on-the-producer-side-6\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Interface on the producer side (#6)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#returning-interfaces-7\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Returning interfaces (#7)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#any-says-nothing-8\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      any says nothing (#8)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#being-confused-about-when-to-use-generics-9\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Being confused about when to use generics (#9)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-being-aware-of-the-possible-problems-with-type-embedding-10\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not being aware of the possible problems with type embedding (#10)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-the-functional-options-pattern-11\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using the functional options pattern (#11)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#project-misorganization-project-structure-and-package-organization-12\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Project misorganization (project structure and package organization) (#12)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#creating-utility-packages-13\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Creating utility packages (#13)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignoring-package-name-collisions-14\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignoring package name collisions (#14)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#missing-code-documentation-15\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Missing code documentation (#15)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-linters-16\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using linters (#16)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#data-types\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Data Types\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Data Types\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#creating-confusion-with-octal-literals-17\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Creating confusion with octal literals (#17)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#neglecting-integer-overflows-18\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Neglecting integer overflows (#18)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-floating-points-19\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding floating-points (#19)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-slice-length-and-capacity-20\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding slice length and capacity (#20)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#inefficient-slice-initialization-21\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Inefficient slice initialization (#21)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#being-confused-about-nil-vs-empty-slice-22\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Being confused about nil vs. empty slice (#22)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-properly-checking-if-a-slice-is-empty-23\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not properly checking if a slice is empty (#23)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-making-slice-copies-correctly-24\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not making slice copies correctly (#24)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#unexpected-side-effects-using-slice-append-25\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Unexpected side effects using slice append (#25)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slices-and-memory-leaks-26\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Slices and memory leaks (#26)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Slices and memory leaks (#26)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#leaking-capacity\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Leaking capacity\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-and-pointers\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Slice and pointers\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#inefficient-map-initialization-27\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Inefficient map initialization (#27)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#maps-and-memory-leaks-28\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Maps and memory leaks (#28)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#comparing-values-incorrectly-29\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Comparing values incorrectly (#29)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#control-structures\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Control Structures\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Control Structures\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignoring-that-elements-are-copied-in-range-loops-30\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignoring that elements are copied in range loops (#30)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignoring-how-arguments-are-evaluated-in-range-loops-channels-and-arrays-31\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignoring how arguments are evaluated in range loops (channels and arrays) (#31)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignoring-the-impacts-of-using-pointer-elements-in-range-loops-32\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignoring the impacts of using pointer elements in range loops (#32)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#making-wrong-assumptions-during-map-iterations-ordering-and-map-insert-during-iteration-33\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Making wrong assumptions during map iterations (ordering and map insert during iteration) (#33)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignoring-how-the-break-statement-works-34\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignoring how the break statement works (#34)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#using-defer-inside-a-loop-35\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Using defer inside a loop (#35)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#strings\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Strings\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Strings\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-the-concept-of-rune-36\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding the concept of rune (#36)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#inaccurate-string-iteration-37\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Inaccurate string iteration (#37)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#misusing-trim-functions-38\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Misusing trim functions (#38)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#under-optimized-strings-concatenation-39\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Under-optimized strings concatenation (#39)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#useless-string-conversions-40\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Useless string conversions (#40)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#substring-and-memory-leaks-41\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Substring and memory leaks (#41)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#functions-and-methods\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Functions and Methods\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Functions and Methods\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-knowing-which-type-of-receiver-to-use-42\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not knowing which type of receiver to use (#42)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#never-using-named-result-parameters-43\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Never using named result parameters (#43)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#unintended-side-effects-with-named-result-parameters-44\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Unintended side effects with named result parameters (#44)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#returning-a-nil-receiver-45\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Returning a nil receiver (#45)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#using-a-filename-as-a-function-input-46\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Using a filename as a function input (#46)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignoring-how-defer-arguments-and-receivers-are-evaluated-argument-evaluation-pointer-and-value-receivers-47\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignoring how defer arguments and receivers are evaluated (argument evaluation, pointer, and value receivers) (#47)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#error-management\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Error Management\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Error Management\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#panicking-48\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Panicking (#48)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignoring-when-to-wrap-an-error-49\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignoring when to wrap an error (#49)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#comparing-an-error-type-inaccurately-50\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Comparing an error type inaccurately (#50)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#comparing-an-error-value-inaccurately-51\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Comparing an error value inaccurately (#51)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#handling-an-error-twice-52\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Handling an error twice (#52)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-handling-an-error-53\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not handling an error (#53)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-handling-defer-errors-54\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not handling defer errors (#54)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#concurrency-foundations\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Concurrency: Foundations\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Concurrency: Foundations\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#mixing-up-concurrency-and-parallelism-55\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Mixing up concurrency and parallelism (#55)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#thinking-concurrency-is-always-faster-56\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Thinking concurrency is always faster (#56)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#being-puzzled-about-when-to-use-channels-or-mutexes-57\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Being puzzled about when to use channels or mutexes (#57)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-race-problems-data-races-vs-race-conditions-and-the-go-memory-model-58\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding race problems (data races vs. race conditions and the Go memory model) (#58)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Not understanding race problems (data races vs. race conditions and the Go memory model) (#58)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#data-race\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Data Race\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#race-condition\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Race Condition\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-the-concurrency-impacts-of-a-workload-type-59\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding the concurrency impacts of a workload type (#59)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#misunderstanding-go-contexts-60\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Misunderstanding Go contexts (#60)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Misunderstanding Go contexts (#60)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#deadline\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Deadline\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#cancellation-signals\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Cancellation signals\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#context-values\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Context values\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#catching-a-context-cancellation\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Catching a context cancellation\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#concurrency-practice\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Concurrency: Practice\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Concurrency: Practice\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#propagating-an-inappropriate-context-61\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Propagating an inappropriate context (#61)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#starting-a-goroutine-without-knowing-when-to-stop-it-62\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Starting a goroutine without knowing when to stop it (#62)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-being-careful-with-goroutines-and-loop-variables-63\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not being careful with goroutines and loop variables (#63)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#expecting-a-deterministic-behavior-using-select-and-channels-64\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Expecting a deterministic behavior using select and channels (#64)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-notification-channels-65\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using notification channels (#65)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-nil-channels-66\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using nil channels (#66)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#being-puzzled-about-channel-size-67\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Being puzzled about channel size (#67)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#forgetting-about-possible-side-effects-with-string-formatting-68\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Forgetting about possible side effects with string formatting (#68)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Forgetting about possible side effects with string formatting (#68)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#etcd-data-race\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      etcd data race\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#deadlock\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Deadlock\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#creating-data-races-with-append-69\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Creating data races with append (#69)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#using-mutexes-inaccurately-with-slices-and-maps-70\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Using mutexes inaccurately with slices and maps (#70)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#misusing-syncwaitgroup-71\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Misusing sync.WaitGroup (#71)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#forgetting-about-synccond-72\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Forgetting about sync.Cond (#72)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-errgroup-73\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using errgroup (#73)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#copying-a-sync-type-74\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Copying a sync type (#74)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#standard-library\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Standard Library\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Standard Library\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#providing-a-wrong-time-duration-75\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Providing a wrong time duration (#75)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#timeafter-and-memory-leaks-76\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      time.After and memory leaks (#76)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#json-handling-common-mistakes-77\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      JSON handling common mistakes (#77)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#common-sql-mistakes-78\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Common SQL mistakes (#78)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-closing-transient-resources-http-body-sqlrows-and-osfile-79\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not closing transient resources (HTTP body, sql.Rows, and os.File) (#79)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#forgetting-the-return-statement-after-replying-to-an-http-request-80\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Forgetting the return statement after replying to an HTTP request (#80)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#using-the-default-http-client-and-server-81\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Using the default HTTP client and server (#81)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#testing\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Testing\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Testing\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-categorizing-tests-build-tags-environment-variables-and-short-mode-82\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not categorizing tests (build tags, environment variables, and short mode) (#82)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-enabling-the-race-flag-83\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not enabling the race flag (#83)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-test-execution-modes-parallel-and-shuffle-84\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using test execution modes (parallel and shuffle) (#84)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-table-driven-tests-85\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using table-driven tests (#85)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#sleeping-in-unit-tests-86\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Sleeping in unit tests (#86)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-dealing-with-the-time-api-efficiently-87\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not dealing with the time API efficiently (#87)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-testing-utility-packages-httptest-and-iotest-88\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using testing utility packages (httptest and iotest) (#88)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#writing-inaccurate-benchmarks-89\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Writing inaccurate benchmarks (#89)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-exploring-all-the-go-testing-features-90\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not exploring all the Go testing features (#90)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-fuzzing-community-mistake\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using fuzzing (community mistake)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#optimizations\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Optimizations\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Optimizations\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-cpu-caches-91\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding CPU caches (#91)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#writing-concurrent-code-that-leads-to-false-sharing-92\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Writing concurrent code that leads to false sharing (#92)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-taking-into-account-instruction-level-parallelism-93\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not taking into account instruction-level parallelism (#93)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-being-aware-of-data-alignment-94\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not being aware of data alignment (#94)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-stack-vs-heap-95\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding stack vs. heap (#95)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-knowing-how-to-reduce-allocations-api-change-compiler-optimizations-and-syncpool-96\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not knowing how to reduce allocations (API change, compiler optimizations, and sync.Pool) (#96)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-relying-on-inlining-97\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not relying on inlining (#97)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-using-go-diagnostics-tooling-98\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not using Go diagnostics tooling (#98)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-how-the-gc-works-99\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding how the GC works (#99)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#not-understanding-the-impacts-of-running-go-in-docker-and-kubernetes-100\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Not understanding the impacts of running Go in Docker and Kubernetes (#100)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#community\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Community\n    </span>\n  </a>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#powered-by\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Powered by\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n                  \n\n\n  \n  \n\n\n<h1 id=\"common-go-mistakes\">Common Go Mistakes</h1>\n<details class=\"tip\" open=\"open\">\n<summary>The Coder Cafe</summary>\n<p>If you enjoyed my book, you may be interested in my latest project: <a href=\"https://thecoder.cafe?rd=100go.co\">The Coder Cafe</a>, a newsletter for coders.</p>\n<blockquote>\n<p>Feeling overwhelmed by the endless stream of tech content? At The Coder Cafe, we serve timeless concepts with your coffee. Written by a Google SWE and published author, we help you grow as an engineer, one coffee at a time.</p>\n</blockquote>\n<p></p><center><a href=\"https://thecoder.cafe?rd=100go.co\"><img src=\"../img/thecodercafe.png\" alt=\"\" style=\"width:480px;height:240px;\"></a></center><p></p>\n</details>\n<p>This page is a summary of the mistakes in the <a href=\"book/\">100 Go Mistakes and How to Avoid Them book</a>. Meanwhile, it's also open to the community. If you believe that a common Go mistake should be added, please create an <a href=\"https://github.com/teivah/100-go-mistakes/issues/new?assignees=&amp;labels=community+mistake&amp;template=community_mistake.md&amp;title=\">issue</a>.</p>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"img/inside-cover.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"img/inside-cover.png\"></a></p>\n<details class=\"warning\" open=\"open\">\n<summary>Beta</summary>\n<p>You're viewing a beta version enriched with significantly more content. However, this version is not yet complete, and I'm looking for volunteers to help me summarize the remaining mistakes (<a href=\"https://github.com/teivah/100-go-mistakes/issues/43\">GitHub issue #43</a>).</p>\n<p>Progress:\n<progress value=\"81\" max=\"100\"></progress></p>\n</details>\n<h2 id=\"code-and-project-organization\">Code and Project Organization</h2>\n<h3 id=\"unintended-variable-shadowing-1\">Unintended variable shadowing (#1)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Avoiding shadowed variables can help prevent mistakes like referencing the wrong variable or confusing readers.</p>\n</details>\n<p>Variable shadowing occurs when a variable name is redeclared in an inner block, but this practice is prone to mistakes. Imposing a rule to forbid shadowed variables depends on personal taste. For example, sometimes it can be convenient to reuse an existing variable name like <code>err</code> for errors. Yet, in general, we should remain cautious because we now know that we can face a scenario where the code compiles, but the variable that receives the value is not the one expected.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/1-variable-shadowing/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"unnecessary-nested-code-2\">Unnecessary nested code (#2)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Avoiding nested levels and keeping the happy path aligned on the left makes building a mental code model easier.</p>\n</details>\n<p>In general, the more nested levels a function requires, the more complex it is to read and understand. Let’s see some different applications of this rule to optimize our code for readability:</p>\n<ul>\n<li>When an <code>if</code> block returns, we should omit the <code>else</code> block in all cases. For example, we shouldn’t write:</li>\n</ul>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-0-1\"><a id=\"__codelineno-0-1\" name=\"__codelineno-0-1\" href=\"#__codelineno-0-1\"></a><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">foo</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-0-2\"><a id=\"__codelineno-0-2\" name=\"__codelineno-0-2\" href=\"#__codelineno-0-2\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-0-3\"><a id=\"__codelineno-0-3\" name=\"__codelineno-0-3\" href=\"#__codelineno-0-3\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">true</span>\n</span><span id=\"__span-0-4\"><a id=\"__codelineno-0-4\" name=\"__codelineno-0-4\" href=\"#__codelineno-0-4\"></a><span class=\"p\">}</span><span class=\"w\"> </span><span class=\"k\">else</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-0-5\"><a id=\"__codelineno-0-5\" name=\"__codelineno-0-5\" href=\"#__codelineno-0-5\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-0-6\"><a id=\"__codelineno-0-6\" name=\"__codelineno-0-6\" href=\"#__codelineno-0-6\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Instead, we omit the <code>else</code> block like this:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-1-1\"><a id=\"__codelineno-1-1\" name=\"__codelineno-1-1\" href=\"#__codelineno-1-1\"></a><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">foo</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-2\"><a id=\"__codelineno-1-2\" name=\"__codelineno-1-2\" href=\"#__codelineno-1-2\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-1-3\"><a id=\"__codelineno-1-3\" name=\"__codelineno-1-3\" href=\"#__codelineno-1-3\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">true</span>\n</span><span id=\"__span-1-4\"><a id=\"__codelineno-1-4\" name=\"__codelineno-1-4\" href=\"#__codelineno-1-4\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-1-5\"><a id=\"__codelineno-1-5\" name=\"__codelineno-1-5\" href=\"#__codelineno-1-5\"></a><span class=\"c1\">// ...</span>\n</span></code></pre></div>\n<ul>\n<li>We can also follow this logic with a non-happy path:</li>\n</ul>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-2-1\"><a id=\"__codelineno-2-1\" name=\"__codelineno-2-1\" href=\"#__codelineno-2-1\"></a><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"s\">\"\"</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-2-2\"><a id=\"__codelineno-2-2\" name=\"__codelineno-2-2\" href=\"#__codelineno-2-2\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-2-3\"><a id=\"__codelineno-2-3\" name=\"__codelineno-2-3\" href=\"#__codelineno-2-3\"></a><span class=\"p\">}</span><span class=\"w\"> </span><span class=\"k\">else</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-2-4\"><a id=\"__codelineno-2-4\" name=\"__codelineno-2-4\" href=\"#__codelineno-2-4\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">errors</span><span class=\"p\">.</span><span class=\"nx\">New</span><span class=\"p\">(</span><span class=\"s\">\"empty string\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-2-5\"><a id=\"__codelineno-2-5\" name=\"__codelineno-2-5\" href=\"#__codelineno-2-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Here, an empty <code>s</code> represents the non-happy path. Hence, we should flip the\n  condition like so:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-3-1\"><a id=\"__codelineno-3-1\" name=\"__codelineno-3-1\" href=\"#__codelineno-3-1\"></a><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">==</span><span class=\"w\"> </span><span class=\"s\">\"\"</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-3-2\"><a id=\"__codelineno-3-2\" name=\"__codelineno-3-2\" href=\"#__codelineno-3-2\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">errors</span><span class=\"p\">.</span><span class=\"nx\">New</span><span class=\"p\">(</span><span class=\"s\">\"empty string\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-3-3\"><a id=\"__codelineno-3-3\" name=\"__codelineno-3-3\" href=\"#__codelineno-3-3\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-3-4\"><a id=\"__codelineno-3-4\" name=\"__codelineno-3-4\" href=\"#__codelineno-3-4\"></a><span class=\"c1\">// ...</span>\n</span></code></pre></div>\n<p>Writing readable code is an important challenge for every developer. Striving to reduce the number of nested blocks, aligning the happy path on the left, and returning as early as possible are concrete means to improve our code’s readability.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/2-nested-code/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"misusing-init-functions-3\">Misusing init functions (#3)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>When initializing variables, remember that init functions have limited error handling and make state handling and testing more complex. In most cases, initializations should be handled as specific functions.</p>\n</details>\n<p>An init function is a function used to initialize the state of an application. It takes no arguments and returns no result (a <code>func()</code> function). When a package is initialized, all the constant and variable declarations in the package are evaluated. Then, the init functions are executed.</p>\n<p>Init functions can lead to some issues:</p>\n<ul>\n<li>They can limit error management.</li>\n<li>They can complicate how to implement tests (for example, an external dependency must be set up, which may not be necessary for the scope of unit tests).</li>\n<li>If the initialization requires us to set a state, that has to be done through global variables.</li>\n</ul>\n<p>We should be cautious with init functions. They can be helpful in some situations, however, such as defining static configuration. Otherwise, and in most cases, we should handle initializations through ad hoc functions.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/3-init-functions/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"overusing-getters-and-setters-4\">Overusing getters and setters (#4)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Forcing the use of getters and setters isn’t idiomatic in Go. Being pragmatic and finding the right balance between efficiency and blindly following certain idioms should be the way to go.</p>\n</details>\n<p>Data encapsulation refers to hiding the values or state of an object. Getters and setters are means to enable encapsulation by providing exported methods on top of unexported object fields.</p>\n<p>In Go, there is no automatic support for getters and setters as we see in some languages. It is also considered neither mandatory nor idiomatic to use getters and setters to access struct fields. We shouldn’t overwhelm our code with getters and setters on structs if they don’t bring any value. We should be pragmatic and strive to find the right balance between efficiency and following idioms that are sometimes considered indisputable in other programming paradigms.</p>\n<p>Remember that Go is a unique language designed for many characteristics, including simplicity. However, if we find a need for getters and setters or, as mentioned, foresee a future need while guaranteeing forward compatibility, there’s nothing wrong with using them.</p>\n<h3 id=\"interface-pollution-5\">Interface pollution (#5)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Abstractions should be discovered, not created. To prevent unnecessary complexity, create an interface when you need it and not when you foresee needing it, or if you can at least prove the abstraction to be a valid one.</p>\n</details>\n<p>Read the full section <a href=\"5-interface-pollution/\">here</a>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/5-interface-pollution/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"interface-on-the-producer-side-6\">Interface on the producer side (#6)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Keeping interfaces on the client side avoids unnecessary abstractions.</p>\n</details>\n<p>Interfaces are satisfied implicitly in Go, which tends to be a gamechanger compared to languages with an explicit implementation. In most cases, the approach to follow is similar to what we described in the previous section: <em>abstractions should be discovered, not created</em>. This means that it’s not up to the producer to force a given abstraction for all the clients. Instead, it’s up to the client to decide whether it needs some form of abstraction and then determine the best abstraction level for its needs.</p>\n<p>An interface should live on the consumer side in most cases. However, in particular contexts (for example, when we know—not foresee—that an abstraction will be helpful for consumers), we may want to have it on the producer side. If we do, we should strive to keep it as minimal as possible, increasing its reusability potential and making it more easily composable.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/6-interface-producer/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"returning-interfaces-7\">Returning interfaces (#7)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>To prevent being restricted in terms of flexibility, a function shouldn’t return interfaces but concrete implementations in most cases. Conversely, a function should accept interfaces whenever possible.</p>\n</details>\n<p>In most cases, we shouldn’t return interfaces but concrete implementations. Otherwise, it can make our design more complex due to package dependencies and can restrict flexibility because all the clients would have to rely on the same abstraction. Again, the conclusion is similar to the previous sections: if we know (not foresee) that an abstraction will be helpful for clients, we can consider returning an interface. Otherwise, we shouldn’t force abstractions; they should be discovered by clients. If a client needs to abstract an implementation for whatever reason, it can still do that on the client’s side.</p>\n<h3 id=\"any-says-nothing-8\"><code>any</code> says nothing (#8)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Only use <code>any</code> if you need to accept or return any possible type, such as <code>json.Marshal</code>. Otherwise, <code>any</code> doesn’t provide meaningful information and can lead to compile-time issues by allowing a caller to call methods with any data type.</p>\n</details>\n<p>The <code>any</code> type can be helpful if there is a genuine need for accepting or returning any possible type (for instance, when it comes to marshaling or formatting). In general, we should avoid overgeneralizing the code we write at all costs. Perhaps a little bit of duplicated code might occasionally be better if it improves other aspects such as code expressiveness.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/8-any/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"being-confused-about-when-to-use-generics-9\">Being confused about when to use generics (#9)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Relying on generics and type parameters can prevent writing boilerplate code to factor out elements or behaviors. However, do not use type parameters prematurely, but only when you see a concrete need for them. Otherwise, they introduce unnecessary abstractions and complexity.</p>\n</details>\n<p>Read the full section <a href=\"9-generics/\">here</a>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/9-generics/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-being-aware-of-the-possible-problems-with-type-embedding-10\">Not being aware of the possible problems with type embedding (#10)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Using type embedding can also help avoid boilerplate code; however, ensure that doing so doesn’t lead to visibility issues where some fields should have remained hidden.</p>\n</details>\n<p>When creating a struct, Go offers the option to embed types. But this can sometimes lead to unexpected behaviors if we don’t understand all the implications of type embedding. Throughout this section, we look at how to embed types, what these bring, and the possible issues.</p>\n<p>In Go, a struct field is called embedded if it’s declared without a name. For example,</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-4-1\"><a id=\"__codelineno-4-1\" name=\"__codelineno-4-1\" href=\"#__codelineno-4-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Foo</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-4-2\"><a id=\"__codelineno-4-2\" name=\"__codelineno-4-2\" href=\"#__codelineno-4-2\"></a><span class=\"w\">    </span><span class=\"nx\">Bar</span><span class=\"w\"> </span><span class=\"c1\">// Embedded field</span>\n</span><span id=\"__span-4-3\"><a id=\"__codelineno-4-3\" name=\"__codelineno-4-3\" href=\"#__codelineno-4-3\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-4-4\"><a id=\"__codelineno-4-4\" name=\"__codelineno-4-4\" href=\"#__codelineno-4-4\"></a>\n</span><span id=\"__span-4-5\"><a id=\"__codelineno-4-5\" name=\"__codelineno-4-5\" href=\"#__codelineno-4-5\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Bar</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-4-6\"><a id=\"__codelineno-4-6\" name=\"__codelineno-4-6\" href=\"#__codelineno-4-6\"></a><span class=\"w\">    </span><span class=\"nx\">Baz</span><span class=\"w\"> </span><span class=\"kt\">int</span>\n</span><span id=\"__span-4-7\"><a id=\"__codelineno-4-7\" name=\"__codelineno-4-7\" href=\"#__codelineno-4-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>In the <code>Foo</code> struct, the <code>Bar</code> type is declared without an associated name; hence, it’s an embedded field.</p>\n<p>We use embedding to promote the fields and methods of an embedded type. Because <code>Bar</code> contains a <code>Baz</code> field, this field is\npromoted to <code>Foo</code>. Therefore, <code>Baz</code> becomes available from <code>Foo</code>.</p>\n<p>What can we say about type embedding? First, let’s note that it’s rarely a necessity, and it means that whatever the use case, we can probably solve it as well without type embedding. Type embedding is mainly used for convenience: in most cases, to promote behaviors.</p>\n<p>If we decide to use type embedding, we need to keep two main constraints in mind:</p>\n<ul>\n<li>It shouldn’t be used solely as some syntactic sugar to simplify accessing a field (such as <code>Foo.Baz()</code> instead of <code>Foo.Bar.Baz()</code>). If this is the only rationale, let’s not embed the inner type and use a field instead.</li>\n<li>It shouldn’t promote data (fields) or a behavior (methods) we want to hide from the outside: for example, if it allows clients to access a locking behavior that should remain private to the struct.</li>\n</ul>\n<p>Using type embedding consciously by keeping these constraints in mind can help avoid boilerplate code with additional forwarding methods. However, let’s make sure we don’t do it solely for cosmetics and not promote elements that should remain hidden.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/10-type-embedding/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-using-the-functional-options-pattern-11\">Not using the functional options pattern (#11)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>To handle options conveniently and in an API-friendly manner, use the functional options pattern.</p>\n</details>\n<p>Although there are different implementations with minor variations, the main idea is as follows:</p>\n<ul>\n<li>An unexported struct holds the configuration: options.</li>\n<li>Each option is a function that returns the same type: <code>type Option func(options *options) error</code>. For example, <code>WithPort</code> accepts an <code>int</code> argument that represents the port and returns an <code>Option</code> type that represents how to update the <code>options</code> struct.</li>\n</ul>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"img/options.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"img/options.png\"></a></p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-5-1\"><a id=\"__codelineno-5-1\" name=\"__codelineno-5-1\" href=\"#__codelineno-5-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">options</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-2\"><a id=\"__codelineno-5-2\" name=\"__codelineno-5-2\" href=\"#__codelineno-5-2\"></a><span class=\"w\">  </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"kt\">int</span>\n</span><span id=\"__span-5-3\"><a id=\"__codelineno-5-3\" name=\"__codelineno-5-3\" href=\"#__codelineno-5-3\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-5-4\"><a id=\"__codelineno-5-4\" name=\"__codelineno-5-4\" href=\"#__codelineno-5-4\"></a>\n</span><span id=\"__span-5-5\"><a id=\"__codelineno-5-5\" name=\"__codelineno-5-5\" href=\"#__codelineno-5-5\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Option</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">(</span><span class=\"nx\">options</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">options</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span>\n</span><span id=\"__span-5-6\"><a id=\"__codelineno-5-6\" name=\"__codelineno-5-6\" href=\"#__codelineno-5-6\"></a>\n</span><span id=\"__span-5-7\"><a id=\"__codelineno-5-7\" name=\"__codelineno-5-7\" href=\"#__codelineno-5-7\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">WithPort</span><span class=\"p\">(</span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">Option</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-8\"><a id=\"__codelineno-5-8\" name=\"__codelineno-5-8\" href=\"#__codelineno-5-8\"></a><span class=\"w\">  </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">(</span><span class=\"nx\">options</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">options</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-9\"><a id=\"__codelineno-5-9\" name=\"__codelineno-5-9\" href=\"#__codelineno-5-9\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-10\"><a id=\"__codelineno-5-10\" name=\"__codelineno-5-10\" href=\"#__codelineno-5-10\"></a><span class=\"w\">      </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">errors</span><span class=\"p\">.</span><span class=\"nx\">New</span><span class=\"p\">(</span><span class=\"s\">\"port should be positive\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-5-11\"><a id=\"__codelineno-5-11\" name=\"__codelineno-5-11\" href=\"#__codelineno-5-11\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-12\"><a id=\"__codelineno-5-12\" name=\"__codelineno-5-12\" href=\"#__codelineno-5-12\"></a><span class=\"w\">    </span><span class=\"nx\">options</span><span class=\"p\">.</span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"o\">&amp;</span><span class=\"nx\">port</span>\n</span><span id=\"__span-5-13\"><a id=\"__codelineno-5-13\" name=\"__codelineno-5-13\" href=\"#__codelineno-5-13\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-5-14\"><a id=\"__codelineno-5-14\" name=\"__codelineno-5-14\" href=\"#__codelineno-5-14\"></a><span class=\"w\">  </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-15\"><a id=\"__codelineno-5-15\" name=\"__codelineno-5-15\" href=\"#__codelineno-5-15\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-5-16\"><a id=\"__codelineno-5-16\" name=\"__codelineno-5-16\" href=\"#__codelineno-5-16\"></a>\n</span><span id=\"__span-5-17\"><a id=\"__codelineno-5-17\" name=\"__codelineno-5-17\" href=\"#__codelineno-5-17\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">NewServer</span><span class=\"p\">(</span><span class=\"nx\">addr</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">opts</span><span class=\"w\"> </span><span class=\"o\">...</span><span class=\"nx\">Option</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Server</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-18\"><a id=\"__codelineno-5-18\" name=\"__codelineno-5-18\" href=\"#__codelineno-5-18\"></a><span class=\"w\">  </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">options</span><span class=\"w\"> </span><span class=\"nx\">options</span>\n</span><span id=\"__span-5-19\"><a id=\"__codelineno-5-19\" name=\"__codelineno-5-19\" href=\"#__codelineno-5-19\"></a><span class=\"w\">  </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">opt</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">opts</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-20\"><a id=\"__codelineno-5-20\" name=\"__codelineno-5-20\" href=\"#__codelineno-5-20\"></a><span class=\"w\">    </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">opt</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">options</span><span class=\"p\">)</span>\n</span><span id=\"__span-5-21\"><a id=\"__codelineno-5-21\" name=\"__codelineno-5-21\" href=\"#__codelineno-5-21\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-22\"><a id=\"__codelineno-5-22\" name=\"__codelineno-5-22\" href=\"#__codelineno-5-22\"></a><span class=\"w\">      </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-5-23\"><a id=\"__codelineno-5-23\" name=\"__codelineno-5-23\" href=\"#__codelineno-5-23\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-24\"><a id=\"__codelineno-5-24\" name=\"__codelineno-5-24\" href=\"#__codelineno-5-24\"></a><span class=\"w\">  </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-25\"><a id=\"__codelineno-5-25\" name=\"__codelineno-5-25\" href=\"#__codelineno-5-25\"></a>\n</span><span id=\"__span-5-26\"><a id=\"__codelineno-5-26\" name=\"__codelineno-5-26\" href=\"#__codelineno-5-26\"></a><span class=\"w\">  </span><span class=\"c1\">// At this stage, the options struct is built and contains the config</span>\n</span><span id=\"__span-5-27\"><a id=\"__codelineno-5-27\" name=\"__codelineno-5-27\" href=\"#__codelineno-5-27\"></a><span class=\"w\">  </span><span class=\"c1\">// Therefore, we can implement our logic related to port configuration</span>\n</span><span id=\"__span-5-28\"><a id=\"__codelineno-5-28\" name=\"__codelineno-5-28\" href=\"#__codelineno-5-28\"></a><span class=\"w\">  </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"kt\">int</span>\n</span><span id=\"__span-5-29\"><a id=\"__codelineno-5-29\" name=\"__codelineno-5-29\" href=\"#__codelineno-5-29\"></a><span class=\"w\">  </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">options</span><span class=\"p\">.</span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"o\">==</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-30\"><a id=\"__codelineno-5-30\" name=\"__codelineno-5-30\" href=\"#__codelineno-5-30\"></a><span class=\"w\">    </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">defaultHTTPPort</span>\n</span><span id=\"__span-5-31\"><a id=\"__codelineno-5-31\" name=\"__codelineno-5-31\" href=\"#__codelineno-5-31\"></a><span class=\"w\">  </span><span class=\"p\">}</span><span class=\"w\"> </span><span class=\"k\">else</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-32\"><a id=\"__codelineno-5-32\" name=\"__codelineno-5-32\" href=\"#__codelineno-5-32\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">options</span><span class=\"p\">.</span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"o\">==</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-33\"><a id=\"__codelineno-5-33\" name=\"__codelineno-5-33\" href=\"#__codelineno-5-33\"></a><span class=\"w\">      </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">randomPort</span><span class=\"p\">()</span>\n</span><span id=\"__span-5-34\"><a id=\"__codelineno-5-34\" name=\"__codelineno-5-34\" href=\"#__codelineno-5-34\"></a><span class=\"w\">    </span><span class=\"p\">}</span><span class=\"w\"> </span><span class=\"k\">else</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-35\"><a id=\"__codelineno-5-35\" name=\"__codelineno-5-35\" href=\"#__codelineno-5-35\"></a><span class=\"w\">      </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">options</span><span class=\"p\">.</span><span class=\"nx\">port</span>\n</span><span id=\"__span-5-36\"><a id=\"__codelineno-5-36\" name=\"__codelineno-5-36\" href=\"#__codelineno-5-36\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-37\"><a id=\"__codelineno-5-37\" name=\"__codelineno-5-37\" href=\"#__codelineno-5-37\"></a><span class=\"w\">  </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-38\"><a id=\"__codelineno-5-38\" name=\"__codelineno-5-38\" href=\"#__codelineno-5-38\"></a>\n</span><span id=\"__span-5-39\"><a id=\"__codelineno-5-39\" name=\"__codelineno-5-39\" href=\"#__codelineno-5-39\"></a><span class=\"w\">  </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-5-40\"><a id=\"__codelineno-5-40\" name=\"__codelineno-5-40\" href=\"#__codelineno-5-40\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>The functional options pattern provides a handy and API-friendly way to handle options. Although the builder pattern can be a valid option, it has some minor downsides (having to pass a config struct that can be empty or a less handy way to handle error management) that tend to make the functional options pattern the idiomatic way to deal with these kind of problems in Go.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/11-functional-options/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"project-misorganization-project-structure-and-package-organization-12\">Project misorganization (project structure and package organization) (#12)</h3>\n<p>Regarding the overall organization, there are different schools of thought. For example, should we organize our application by context or by layer? It depends on our preferences. We may favor grouping code per context (such as the customer context, the contract context, etc.), or we may favor following hexagonal architecture principles and group per technical layer. If the decision we make fits our use case, it cannot be a wrong decision, as long as we remain consistent with it.</p>\n<p>Regarding packages, there are multiple best practices that we should follow. First, we should avoid premature packaging because it might cause us to overcomplicate a project. Sometimes, it’s better to use a simple organization and have our project evolve when we understand what it contains rather than forcing ourselves to make the perfect structure up front.\nGranularity is another essential thing to consider. We should avoid having dozens of nano packages containing only one or two files. If we do, it’s because we have probably missed some logical connections across these packages, making our project harder for readers to understand. Conversely, we should also avoid huge packages that dilute the meaning of a package name.</p>\n<p>Package naming should also be considered with care. As we all know (as developers), naming is hard. To help clients understand a Go project, we should name our packages after what they provide, not what they contain. Also, naming should be meaningful. Therefore, a package name should be short, concise, expressive, and, by convention, a single lowercase word.</p>\n<p>Regarding what to export, the rule is pretty straightforward. We should minimize what should be exported as much as possible to reduce the coupling between packages and keep unnecessary exported elements hidden. If we are unsure whether to export an element or not, we should default to not exporting it. Later, if we discover that we need to export it, we can adjust our code. Let’s also keep in mind some exceptions, such as making fields exported so that a struct can be unmarshaled with encoding/json.</p>\n<p>Organizing a project isn’t straightforward, but following these rules should help make it easier to maintain. However, remember that consistency is also vital to ease maintainability. Therefore, let’s make sure that we keep things as consistent as possible within a codebase.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>In 2023, the Go team has published an official guideline for organizing / structuring a Go project: <a href=\"https://go.dev/doc/modules/layout\">go.dev/doc/modules/layout</a></p>\n</details>\n<h3 id=\"creating-utility-packages-13\">Creating utility packages (#13)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Naming is a critical piece of application design. Creating packages such as <code>common</code>, <code>util</code>, and <code>shared</code> doesn’t bring much value for the reader. Refactor such packages into meaningful and specific package names.</p>\n</details>\n<p>Also, bear in mind that naming a package after what it provides and not what it contains can be an efficient way to increase its expressiveness.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/13-utility-packages/stringset.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"ignoring-package-name-collisions-14\">Ignoring package name collisions (#14)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>To avoid naming collisions between variables and packages, leading to confusion or perhaps even bugs, use unique names for each one. If this isn’t feasible, use an import alias to change the qualifier to differentiate the package name from the variable name, or think of a better name.</p>\n</details>\n<p>Package collisions occur when a variable name collides with an existing package name, preventing the package from being reused. We should prevent variable name collisions to avoid ambiguity. If we face a collision, we should either find another meaningful name or use an import alias.</p>\n<h3 id=\"missing-code-documentation-15\">Missing code documentation (#15)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>To help clients and maintainers understand your code’s purpose, document exported elements.</p>\n</details>\n<p>Documentation is an important aspect of coding. It simplifies how clients can consume an API but can also help in maintaining a project. In Go, we should follow some rules to make our code idiomatic:</p>\n<p>First, every exported element must be documented. Whether it is a structure, an interface, a function, or something else, if it’s exported, it must be documented. The convention is to add comments, starting with the name of the exported element.</p>\n<p>As a convention, each comment should be a complete sentence that ends with punctuation. Also bear in mind that when we document a function (or a method), we should highlight what the function intends to do, not how it does it; this belongs to the core of a function and comments, not documentation. Furthermore, the documentation should ideally provide enough information that the consumer does not have to look at our code to understand how to use an exported element.</p>\n<p>When it comes to documenting a variable or a constant, we might be interested in conveying two aspects: its purpose and its content. The former should live as code documentation to be useful for external clients. The latter, though, shouldn’t necessarily be public.</p>\n<p>To help clients and maintainers understand a package’s scope, we should also document each package. The convention is to start the comment with <code>// Package</code> followed by the package name. The first line of a package comment should be concise. That’s because it will appear in the package. Then, we can provide all the information we need in the following lines.</p>\n<p>Documenting our code shouldn’t be a constraint. We should take the opportunity to make sure it helps clients and maintainers to understand the purpose of our code.</p>\n<h3 id=\"not-using-linters-16\">Not using linters (#16)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>To improve code quality and consistency, use linters and formatters.</p>\n</details>\n<p>A linter is an automatic tool to analyze code and catch errors. The scope of this section isn’t to give an exhaustive list of the existing linters; otherwise, it will become deprecated pretty quickly. But we should understand and remember why linters are essential for most Go projects.</p>\n<p>However, if you’re not a regular user of linters, here is a list that you may want to use daily:</p>\n<ul>\n<li><a href=\"https://golang.org/cmd/vet\">https://golang.org/cmd/vet</a>—A standard Go analyzer</li>\n<li><a href=\"https://github.com/kisielk/errcheck\">https://github.com/kisielk/errcheck</a>—An error checker</li>\n<li><a href=\"https://github.com/fzipp/gocyclo\">https://github.com/fzipp/gocyclo</a>—A cyclomatic complexity analyzer</li>\n<li><a href=\"https://github.com/jgautheron/goconst\">https://github.com/jgautheron/goconst</a>—A repeated string constants analyzer</li>\n</ul>\n<p>Besides linters, we should also use code formatters to fix code style. Here is a list of some code formatters for you to try:</p>\n<ul>\n<li><a href=\"https://golang.org/cmd/gofmt\">https://golang.org/cmd/gofmt</a>—A standard Go code formatter</li>\n<li><a href=\"https://godoc.org/golang.org/x/tools/cmd/goimports\">https://godoc.org/golang.org/x/tools/cmd/goimports</a>—A standard Go imports formatter</li>\n</ul>\n<p>Meanwhile, we should also look at golangci-lint (<a href=\"https://github.com/golangci/golangci-lint\">https://github.com/golangci/golangci-lint</a>). It’s a linting tool that provides a facade on top of many useful linters and formatters. Also, it allows running the linters in parallel to improve analysis speed, which is quite handy.</p>\n<p>Linters and formatters are a powerful way to improve the quality and consistency of our codebase. Let’s take the time to understand which one we should use and make sure we automate their execution (such as a CI or Git precommit hook).</p>\n<h2 id=\"data-types\">Data Types</h2>\n<h3 id=\"creating-confusion-with-octal-literals-17\">Creating confusion with octal literals (#17)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>When reading existing code, bear in mind that integer literals starting with <code>0</code> are octal numbers. Also, to improve readability, make octal integers explicit by prefixing them with <code>0o</code>.</p>\n</details>\n<p>Octal numbers start with a 0 (e.g., <code>010</code> is equal to 8 in base 10). To improve readability and avoid potential mistakes for future code readers, we should make octal numbers explicit using the <code>0o</code> prefix (e.g., <code>0o10</code>).</p>\n<p>We should also note the other integer literal representations:</p>\n<ul>\n<li><em>Binary</em>—Uses a <code>0b</code> or <code>0B</code> prefix (for example, <code>0b100</code> is equal to 4 in base 10)</li>\n<li><em>Hexadecimal</em>—Uses an <code>0x</code> or <code>0X</code> prefix (for example, <code>0xF</code> is equal to 15 in base 10)</li>\n<li><em>Imaginary</em>—Uses an <code>i</code> suffix (for example, <code>3i</code>)</li>\n</ul>\n<p>We can also use an underscore character (_) as a separator for readability. For example, we can write 1 billion this way: <code>1_000_000_000</code>. We can also use the underscore character with other representations (for example, <code>0b00_00_01</code>).</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/17-octal-literals/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"neglecting-integer-overflows-18\">Neglecting integer overflows (#18)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Because integer overflows and underflows are handled silently in Go, you can implement your own functions to catch them.</p>\n</details>\n<p>In Go, an integer overflow that can be detected at compile time generates a compilation error. For example,</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-6-1\"><a id=\"__codelineno-6-1\" name=\"__codelineno-6-1\" href=\"#__codelineno-6-1\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">counter</span><span class=\"w\"> </span><span class=\"kt\">int32</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">math</span><span class=\"p\">.</span><span class=\"nx\">MaxInt32</span><span class=\"w\"> </span><span class=\"o\">+</span><span class=\"w\"> </span><span class=\"mi\">1</span>\n</span></code></pre></div>\n<div class=\"language-shell highlight\"><pre><span></span><code><span id=\"__span-7-1\"><a id=\"__codelineno-7-1\" name=\"__codelineno-7-1\" href=\"#__codelineno-7-1\"></a>constant<span class=\"w\"> </span><span class=\"m\">2147483648</span><span class=\"w\"> </span>overflows<span class=\"w\"> </span>int32\n</span></code></pre></div>\n<p>However, at run time, an integer overflow or underflow is silent; this does not lead to an application panic. It is essential to keep this behavior in mind, because it can lead to sneaky bugs (for example, an integer increment or addition of positive integers that leads to a negative result).</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/18-integer-overflows\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-understanding-floating-points-19\">Not understanding floating-points (#19)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Making floating-point comparisons within a given delta can ensure that your code is portable. When performing addition or subtraction, group the operations with a similar order of magnitude to favor accuracy. Also, perform multiplication and division before addition and subtraction.</p>\n</details>\n<p>In Go, there are two floating-point types (if we omit imaginary numbers): float32 and float64. The concept of a floating point was invented to solve the major problem with integers: their inability to represent fractional values. To avoid bad surprises, we need to know that floating-point arithmetic is an approximation of real arithmetic.</p>\n<p>For that, we’ll look at a multiplication example:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-8-1\"><a id=\"__codelineno-8-1\" name=\"__codelineno-8-1\" href=\"#__codelineno-8-1\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">n</span><span class=\"w\"> </span><span class=\"kt\">float32</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"mf\">1.0001</span>\n</span><span id=\"__span-8-2\"><a id=\"__codelineno-8-2\" name=\"__codelineno-8-2\" href=\"#__codelineno-8-2\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">n</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"w\"> </span><span class=\"nx\">n</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>We may expect this code to print the result of 1.0001 * 1.0001 = 1.00020001, right? However, running it on most x86 processors prints 1.0002, instead.</p>\n<p>Because Go’s <code>float32</code> and <code>float64</code> types are approximations, we have to bear a few rules in mind:</p>\n<ul>\n<li>When comparing two floating-point numbers, check that their difference is within an acceptable range.</li>\n<li>When performing additions or subtractions, group operations with a similar order of magnitude for better accuracy.</li>\n<li>To favor accuracy, if a sequence of operations requires addition, subtraction, multiplication, or division, perform the multiplication and division operations first.</li>\n</ul>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/19-floating-points/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-understanding-slice-length-and-capacity-20\">Not understanding slice length and capacity (#20)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Understanding the difference between slice length and capacity should be part of a Go developer’s core knowledge. The slice length is the number of available elements in the slice, whereas the slice capacity is the number of elements in the backing array.</p>\n</details>\n<p>Read the full section <a href=\"20-slice/\">here</a>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/20-slice-length-cap/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"inefficient-slice-initialization-21\">Inefficient slice initialization (#21)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>When creating a slice, initialize it with a given length or capacity if its length is already known. This reduces the number of allocations and improves performance.</p>\n</details>\n<p>While initializing a slice using <code>make</code>, we can provide a length and an optional capacity. Forgetting to pass an appropriate value for both of these parameters when it makes sense is a widespread mistake. Indeed, it can lead to multiple copies and additional effort for the <abbr title=\"Garbage Collector\">GC</abbr> to clean the temporary backing arrays. Performance-wise, there’s no good reason not to give the Go runtime a helping hand.</p>\n<p>Our options are to allocate a slice with either a given capacity or a given length. Of these two solutions, we have seen that the second tends to be slightly faster. But using a given capacity and append can be easier to implement and read in some contexts.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/21-slice-init/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"being-confused-about-nil-vs-empty-slice-22\">Being confused about nil vs. empty slice (#22)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>To prevent common confusions such as when using the <code>encoding/json</code> or the <code>reflect</code> package, you need to understand the difference between nil and empty slices. Both are zero-length, zero-capacity slices, but only a nil slice doesn’t require allocation.</p>\n</details>\n<p>In Go, there is a distinction between nil and empty slices. A nil slice is equals to <code>nil</code>, whereas an empty slice has a length of zero. A nil slice is empty, but an empty slice isn’t necessarily <code>nil</code>. Meanwhile, a nil slice doesn’t require any allocation. We have seen throughout this section how to initialize a slice depending on the context by using</p>\n<ul>\n<li><code>var s []string</code> if we aren’t sure about the final length and the slice can be empty</li>\n<li><code>[]string(nil)</code> as syntactic sugar to create a nil and empty slice</li>\n<li><code>make([]string, length)</code> if the future length is known</li>\n</ul>\n<p>The last option, <code>[]string{}</code>, should be avoided if we initialize the slice without elements. Finally, let’s check whether the libraries we use make the distinctions between nil and empty slices to prevent unexpected behaviors.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/22-nil-empty-slice/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-properly-checking-if-a-slice-is-empty-23\">Not properly checking if a slice is empty (#23)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>To check if a slice doesn’t contain any element, check its length. This check works regardless of whether the slice is <code>nil</code> or empty. The same goes for maps. To design unambiguous APIs, you shouldn’t distinguish between nil and empty slices.</p>\n</details>\n<p>To determine whether a slice has elements, we can either do it by checking if the slice is nil or if its length is equal to 0. Checking the length is the best option to follow as it will cover both if the slice is empty or if the slice is nil.</p>\n<p>Meanwhile, when designing interfaces, we should avoid distinguishing nil and empty slices, which leads to subtle programming errors. When returning slices, it should make neither a semantic nor a technical difference if we return a nil or empty slice. Both should mean the same thing for the callers. This principle is the same with maps. To check if a map is empty, check its length, not whether it’s nil.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/23-checking-slice-empty/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-making-slice-copies-correctly-24\">Not making slice copies correctly (#24)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>To copy one slice to another using the <code>copy</code> built-in function, remember that the number of copied elements corresponds to the minimum between the two slice’s lengths.</p>\n</details>\n<p>Copying elements from one slice to another is a reasonably frequent operation. When using copy, we must recall that the number of elements copied to the destination corresponds to the minimum between the two slices’ lengths. Also bear in mind that other alternatives exist to copy a slice, so we shouldn’t be surprised if we find them in a codebase.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/24-slice-copy/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"unexpected-side-effects-using-slice-append-25\">Unexpected side effects using slice append (#25)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Using copy or the full slice expression is a way to prevent <code>append</code> from creating conflicts if two different functions use slices backed by the same array. However, only a slice copy prevents memory leaks if you want to shrink a large slice.</p>\n</details>\n<p>When using slicing, we must remember that we can face a situation leading to unintended side effects. If the resulting slice has a length smaller than its capacity, append can mutate the original slice. If we want to restrict the range of possible side effects, we can use either a slice copy or the full slice expression, which prevents us from doing a copy.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p><code>s[low:high:max]</code> (full slice expression): This statement creates a slice similar to the one created with <code>s[low:high]</code>, except that the resulting slice’s capacity is equal to <code>max - low</code>.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/25-slice-append/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"slices-and-memory-leaks-26\">Slices and memory leaks (#26)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Working with a slice of pointers or structs with pointer fields, you can avoid memory leaks by marking as nil the elements excluded by a slicing operation.</p>\n</details>\n<h4 id=\"leaking-capacity\">Leaking capacity</h4>\n<p>Remember that slicing a large slice or array can lead to potential high memory consumption. The remaining space won’t be reclaimed by the <abbr title=\"Garbage Collector\">GC</abbr>, and we can keep a large backing array despite using only a few elements. Using a slice copy is the solution to prevent such a case.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/26-slice-memory-leak/capacity-leak\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h4 id=\"slice-and-pointers\">Slice and pointers</h4>\n<p>When we use the slicing operation with pointers or structs with pointer fields, we need to know that the <abbr title=\"Garbage Collector\">GC</abbr> won’t reclaim these elements. In that case, the two options are to either perform a copy or explicitly mark the remaining elements or their fields to <code>nil</code>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/26-slice-memory-leak/slice-pointers\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"inefficient-map-initialization-27\">Inefficient map initialization (#27)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>When creating a map, initialize it with a given length if its length is already known. This reduces the number of allocations and improves performance.</p>\n</details>\n<p>A map provides an unordered collection of key-value pairs in which all the keys are distinct. In Go, a map is based on the hash table data structure. Internally, a hash table is an array of buckets, and each bucket is a pointer to an array of key-value pairs.</p>\n<p>If we know up front the number of elements a map will contain, we should create it by providing an initial size. Doing this avoids potential map growth, which is quite heavy computation-wise because it requires reallocating enough space and rebalancing all the elements.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/27-map-init/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"maps-and-memory-leaks-28\">Maps and memory leaks (#28)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>A map can always grow in memory, but it never shrinks. Hence, if it leads to some memory issues, you can try different options, such as forcing Go to recreate the map or using pointers.</p>\n</details>\n<p>Read the full section <a href=\"28-maps-memory-leaks/\">here</a>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/28-map-memory-leak/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"comparing-values-incorrectly-29\">Comparing values incorrectly (#29)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>To compare types in Go, you can use the == and != operators if two types are comparable: Booleans, numerals, strings, pointers, channels, and structs are composed entirely of comparable types. Otherwise, you can either use <code>reflect.DeepEqual</code> and pay the price of reflection or use custom implementations and libraries.</p>\n</details>\n<p>It’s essential to understand how to use <code>==</code> and <code>!=</code> to make comparisons effectively. We can use these operators on operands that are comparable:</p>\n<ul>\n<li><em>Booleans</em>—Compare whether two Booleans are equal.</li>\n<li><em>Numerics (int, float, and complex types)</em>—Compare whether two numerics are equal.</li>\n<li><em>Strings</em>—Compare whether two strings are equal.</li>\n<li><em>Channels</em>—Compare whether two channels were created by the same call to make or if both are nil.</li>\n<li><em>Interfaces</em>—Compare whether two interfaces have identical dynamic types and equal dynamic values or if both are nil.</li>\n<li><em>Pointers</em>—Compare whether two pointers point to the same value in memory or if both are nil.</li>\n<li><em>Structs and arrays</em>—Compare whether they are composed of similar types.</li>\n</ul>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>We can also use the <code>?</code>, <code>&gt;=</code>, <code>&lt;</code>, and <code>&gt;</code> operators with numeric types to compare values and with strings to compare their lexical order.</p>\n</details>\n<p>If operands are not comparable (e.g., slices and maps), we have to use other options such as reflection. Reflection is a form of metaprogramming, and it refers to the ability of an application to introspect and modify its structure and behavior. For example, in Go, we can use <code>reflect.DeepEqual</code>. This function reports whether two elements are deeply equal by recursively traversing two values. The elements it accepts are basic types plus arrays, structs, slices, maps, pointers, interfaces, and functions. Yet, the main catch is the performance penalty.</p>\n<p>If performance is crucial at run time, implementing our custom method might be the best solution.\nOne additional note: we must remember that the standard library has some existing comparison methods. For example, we can use the optimized <code>bytes.Compare</code> function to compare two slices of bytes. Before implementing a custom method, we need to make sure we don’t reinvent the wheel.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/29-comparing-values/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h2 id=\"control-structures\">Control Structures</h2>\n<h3 id=\"ignoring-that-elements-are-copied-in-range-loops-30\">Ignoring that elements are copied in <code>range</code> loops (#30)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>The value element in a <code>range</code> loop is a copy. Therefore, to mutate a struct, for example, access it via its index or via a classic <code>for</code> loop (unless the element or the field you want to modify is a pointer).</p>\n</details>\n<p>A range loop allows iterating over different data structures:</p>\n<ul>\n<li>String</li>\n<li>Array</li>\n<li>Pointer to an array</li>\n<li>Slice</li>\n<li>Map</li>\n<li>Receiving channel</li>\n</ul>\n<p>Compared to a classic for <code>loop</code>, a <code>range</code> loop is a convenient way to iterate over all the elements of one of these data structures, thanks to its concise syntax.</p>\n<p>Yet, we should remember that the value element in a range loop is a copy. Therefore, if the value is a struct we need to mutate, we will only update the copy, not the element itself, unless the value or field we modify is a pointer. The favored options are to access the element via the index using a range loop or a classic for loop.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/30-range-loop-element-copied/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"ignoring-how-arguments-are-evaluated-in-range-loops-channels-and-arrays-31\">Ignoring how arguments are evaluated in <code>range</code> loops (channels and arrays) (#31)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Understanding that the expression passed to the <code>range</code> operator is evaluated only once before the beginning of the loop can help you avoid common mistakes such as inefficient assignment in channel or slice iteration.</p>\n</details>\n<p>The range loop evaluates the provided expression only once, before the beginning of the loop, by doing a copy (regardless of the type). We should remember this behavior to avoid common mistakes that might, for example, lead us to access the wrong element. For example:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-9-1\"><a id=\"__codelineno-9-1\" name=\"__codelineno-9-1\" href=\"#__codelineno-9-1\"></a><span class=\"nx\">a</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">]</span><span class=\"kt\">int</span><span class=\"p\">{</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"p\">}</span>\n</span><span id=\"__span-9-2\"><a id=\"__codelineno-9-2\" name=\"__codelineno-9-2\" href=\"#__codelineno-9-2\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">a</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-9-3\"><a id=\"__codelineno-9-3\" name=\"__codelineno-9-3\" href=\"#__codelineno-9-3\"></a><span class=\"w\">    </span><span class=\"nx\">a</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">]</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"mi\">10</span>\n</span><span id=\"__span-9-4\"><a id=\"__codelineno-9-4\" name=\"__codelineno-9-4\" href=\"#__codelineno-9-4\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">==</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-9-5\"><a id=\"__codelineno-9-5\" name=\"__codelineno-9-5\" href=\"#__codelineno-9-5\"></a><span class=\"w\">        </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">v</span><span class=\"p\">)</span>\n</span><span id=\"__span-9-6\"><a id=\"__codelineno-9-6\" name=\"__codelineno-9-6\" href=\"#__codelineno-9-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-9-7\"><a id=\"__codelineno-9-7\" name=\"__codelineno-9-7\" href=\"#__codelineno-9-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>This code updates the last index to 10. However, if we run this code, it does not print 10; it prints 2.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/31-range-loop-arg-evaluation/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"ignoring-the-impacts-of-using-pointer-elements-in-range-loops-32\"><img alt=\"⚠\" class=\"twemoji\" src=\"https://cdn.jsdelivr.net/gh/jdecked/twemoji@15.1.0/assets/svg/26a0.svg\" title=\":warning:\"> Ignoring the impacts of using pointer elements in <code>range</code> loops (#32)</h3>\n<details class=\"warning\" open=\"open\">\n<summary>Warning</summary>\n<p>This mistake isn't relevant anymore from Go 1.22 (<a href=\"https://go.dev/blog/loopvar-preview\">details</a>).</p>\n</details>\n<h3 id=\"making-wrong-assumptions-during-map-iterations-ordering-and-map-insert-during-iteration-33\">Making wrong assumptions during map iterations (ordering and map insert during iteration) (#33)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>To ensure predictable outputs when using maps, remember that a map data structure:</p>\n</details>\n<ul>\n<li>Doesn’t order the data by keys</li>\n<li>Doesn’t preserve the insertion order</li>\n<li>Doesn’t have a deterministic iteration order</li>\n<li>Doesn’t guarantee that an element added during an iteration will be produced during this iteration</li>\n</ul>\n<!-- TODO -->\n\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/33-map-iteration/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"ignoring-how-the-break-statement-works-34\">Ignoring how the <code>break</code> statement works (#34)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Using <code>break</code> or <code>continue</code> with a label enforces breaking a specific statement. This can be helpful with <code>switch</code> or <code>select</code> statements inside loops.</p>\n</details>\n<p>A break statement is commonly used to terminate the execution of a loop. When loops are used in conjunction with switch or select, developers frequently make the mistake of breaking the wrong statement. For example:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-10-1\"><a id=\"__codelineno-10-1\" name=\"__codelineno-10-1\" href=\"#__codelineno-10-1\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">5</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-10-2\"><a id=\"__codelineno-10-2\" name=\"__codelineno-10-2\" href=\"#__codelineno-10-2\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"%d \"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">)</span>\n</span><span id=\"__span-10-3\"><a id=\"__codelineno-10-3\" name=\"__codelineno-10-3\" href=\"#__codelineno-10-3\"></a>\n</span><span id=\"__span-10-4\"><a id=\"__codelineno-10-4\" name=\"__codelineno-10-4\" href=\"#__codelineno-10-4\"></a><span class=\"w\">    </span><span class=\"k\">switch</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-10-5\"><a id=\"__codelineno-10-5\" name=\"__codelineno-10-5\" href=\"#__codelineno-10-5\"></a><span class=\"w\">    </span><span class=\"k\">default</span><span class=\"p\">:</span>\n</span><span id=\"__span-10-6\"><a id=\"__codelineno-10-6\" name=\"__codelineno-10-6\" href=\"#__codelineno-10-6\"></a><span class=\"w\">    </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"p\">:</span>\n</span><span id=\"__span-10-7\"><a id=\"__codelineno-10-7\" name=\"__codelineno-10-7\" href=\"#__codelineno-10-7\"></a><span class=\"w\">        </span><span class=\"k\">break</span>\n</span><span id=\"__span-10-8\"><a id=\"__codelineno-10-8\" name=\"__codelineno-10-8\" href=\"#__codelineno-10-8\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-10-9\"><a id=\"__codelineno-10-9\" name=\"__codelineno-10-9\" href=\"#__codelineno-10-9\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>The break statement doesn’t terminate the <code>for</code> loop: it terminates the <code>switch</code> statement, instead. Hence, instead of iterating from 0 to 2, this code iterates from 0 to 4: <code>0 1 2 3 4</code>.</p>\n<p>One essential rule to keep in mind is that a <code>break</code> statement terminates the execution of the innermost <code>for</code>, <code>switch</code>, or <code>select</code> statement. In the previous example, it terminates the <code>switch</code> statement.</p>\n<p>To break the loop instead of the <code>switch</code> statement, the most idiomatic way is to use a label:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-11-1\"><a id=\"__codelineno-11-1\" name=\"__codelineno-11-1\" href=\"#__codelineno-11-1\"></a><span class=\"hll\"><span class=\"nx\">loop</span><span class=\"p\">:</span>\n</span></span><span id=\"__span-11-2\"><a id=\"__codelineno-11-2\" name=\"__codelineno-11-2\" href=\"#__codelineno-11-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">5</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-11-3\"><a id=\"__codelineno-11-3\" name=\"__codelineno-11-3\" href=\"#__codelineno-11-3\"></a><span class=\"w\">        </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"%d \"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">)</span>\n</span><span id=\"__span-11-4\"><a id=\"__codelineno-11-4\" name=\"__codelineno-11-4\" href=\"#__codelineno-11-4\"></a>\n</span><span id=\"__span-11-5\"><a id=\"__codelineno-11-5\" name=\"__codelineno-11-5\" href=\"#__codelineno-11-5\"></a><span class=\"w\">        </span><span class=\"k\">switch</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-11-6\"><a id=\"__codelineno-11-6\" name=\"__codelineno-11-6\" href=\"#__codelineno-11-6\"></a><span class=\"w\">        </span><span class=\"k\">default</span><span class=\"p\">:</span>\n</span><span id=\"__span-11-7\"><a id=\"__codelineno-11-7\" name=\"__codelineno-11-7\" href=\"#__codelineno-11-7\"></a><span class=\"w\">        </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"p\">:</span>\n</span><span id=\"__span-11-8\"><a id=\"__codelineno-11-8\" name=\"__codelineno-11-8\" href=\"#__codelineno-11-8\"></a><span class=\"hll\"><span class=\"w\">            </span><span class=\"k\">break</span><span class=\"w\"> </span><span class=\"nx\">loop</span>\n</span></span><span id=\"__span-11-9\"><a id=\"__codelineno-11-9\" name=\"__codelineno-11-9\" href=\"#__codelineno-11-9\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-11-10\"><a id=\"__codelineno-11-10\" name=\"__codelineno-11-10\" href=\"#__codelineno-11-10\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Here, we associate the <code>loop</code> label with the <code>for</code> loop. Then, because we provide the <code>loop</code> label to the <code>break</code> statement, it breaks the loop, not the switch. Therefore, this new version will print <code>0 1 2</code>, as we expected.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/34-break/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"using-defer-inside-a-loop-35\">Using <code>defer</code> inside a loop (#35)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Extracting loop logic inside a function leads to executing a <code>defer</code> statement at the end of each iteration.</p>\n</details>\n<p>The <code>defer</code> statement delays a call’s execution until the surrounding function returns. It’s mainly used to reduce boilerplate code. For example, if a resource has to be closed eventually, we can use <code>defer</code> to avoid repeating the closure calls before every single <code>return</code>.</p>\n<p>One common mistake with <code>defer</code> is to forget that it schedules a function call when the <em>surrounding</em> function returns. For example:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-12-1\"><a id=\"__codelineno-12-1\" name=\"__codelineno-12-1\" href=\"#__codelineno-12-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">readFiles</span><span class=\"p\">(</span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-12-2\"><a id=\"__codelineno-12-2\" name=\"__codelineno-12-2\" href=\"#__codelineno-12-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">path</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-12-3\"><a id=\"__codelineno-12-3\" name=\"__codelineno-12-3\" href=\"#__codelineno-12-3\"></a><span class=\"w\">        </span><span class=\"nx\">file</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">os</span><span class=\"p\">.</span><span class=\"nx\">Open</span><span class=\"p\">(</span><span class=\"nx\">path</span><span class=\"p\">)</span>\n</span><span id=\"__span-12-4\"><a id=\"__codelineno-12-4\" name=\"__codelineno-12-4\" href=\"#__codelineno-12-4\"></a><span class=\"w\">        </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-12-5\"><a id=\"__codelineno-12-5\" name=\"__codelineno-12-5\" href=\"#__codelineno-12-5\"></a><span class=\"w\">            </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-12-6\"><a id=\"__codelineno-12-6\" name=\"__codelineno-12-6\" href=\"#__codelineno-12-6\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-12-7\"><a id=\"__codelineno-12-7\" name=\"__codelineno-12-7\" href=\"#__codelineno-12-7\"></a>\n</span><span id=\"__span-12-8\"><a id=\"__codelineno-12-8\" name=\"__codelineno-12-8\" href=\"#__codelineno-12-8\"></a><span class=\"w\">        </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">file</span><span class=\"p\">.</span><span class=\"nx\">Close</span><span class=\"p\">()</span>\n</span><span id=\"__span-12-9\"><a id=\"__codelineno-12-9\" name=\"__codelineno-12-9\" href=\"#__codelineno-12-9\"></a>\n</span><span id=\"__span-12-10\"><a id=\"__codelineno-12-10\" name=\"__codelineno-12-10\" href=\"#__codelineno-12-10\"></a><span class=\"w\">        </span><span class=\"c1\">// Do something with file</span>\n</span><span id=\"__span-12-11\"><a id=\"__codelineno-12-11\" name=\"__codelineno-12-11\" href=\"#__codelineno-12-11\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-12-12\"><a id=\"__codelineno-12-12\" name=\"__codelineno-12-12\" href=\"#__codelineno-12-12\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-12-13\"><a id=\"__codelineno-12-13\" name=\"__codelineno-12-13\" href=\"#__codelineno-12-13\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>The <code>defer</code> calls are executed not during each loop iteration but when the <code>readFiles</code> function returns. If <code>readFiles</code> doesn’t return, the file descriptors will be kept open forever, causing leaks.</p>\n<p>One common option to fix this problem is to create a surrounding function after <code>defer</code>, called during each iteration:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-13-1\"><a id=\"__codelineno-13-1\" name=\"__codelineno-13-1\" href=\"#__codelineno-13-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">readFiles</span><span class=\"p\">(</span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-2\"><a id=\"__codelineno-13-2\" name=\"__codelineno-13-2\" href=\"#__codelineno-13-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">path</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-3\"><a id=\"__codelineno-13-3\" name=\"__codelineno-13-3\" href=\"#__codelineno-13-3\"></a><span class=\"w\">        </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">readFile</span><span class=\"p\">(</span><span class=\"nx\">path</span><span class=\"p\">);</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-4\"><a id=\"__codelineno-13-4\" name=\"__codelineno-13-4\" href=\"#__codelineno-13-4\"></a><span class=\"w\">            </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-13-5\"><a id=\"__codelineno-13-5\" name=\"__codelineno-13-5\" href=\"#__codelineno-13-5\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-13-6\"><a id=\"__codelineno-13-6\" name=\"__codelineno-13-6\" href=\"#__codelineno-13-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-13-7\"><a id=\"__codelineno-13-7\" name=\"__codelineno-13-7\" href=\"#__codelineno-13-7\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-13-8\"><a id=\"__codelineno-13-8\" name=\"__codelineno-13-8\" href=\"#__codelineno-13-8\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-13-9\"><a id=\"__codelineno-13-9\" name=\"__codelineno-13-9\" href=\"#__codelineno-13-9\"></a>\n</span><span id=\"__span-13-10\"><a id=\"__codelineno-13-10\" name=\"__codelineno-13-10\" href=\"#__codelineno-13-10\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">readFile</span><span class=\"p\">(</span><span class=\"nx\">path</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-11\"><a id=\"__codelineno-13-11\" name=\"__codelineno-13-11\" href=\"#__codelineno-13-11\"></a><span class=\"w\">    </span><span class=\"nx\">file</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">os</span><span class=\"p\">.</span><span class=\"nx\">Open</span><span class=\"p\">(</span><span class=\"nx\">path</span><span class=\"p\">)</span>\n</span><span id=\"__span-13-12\"><a id=\"__codelineno-13-12\" name=\"__codelineno-13-12\" href=\"#__codelineno-13-12\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-13\"><a id=\"__codelineno-13-13\" name=\"__codelineno-13-13\" href=\"#__codelineno-13-13\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-13-14\"><a id=\"__codelineno-13-14\" name=\"__codelineno-13-14\" href=\"#__codelineno-13-14\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-13-15\"><a id=\"__codelineno-13-15\" name=\"__codelineno-13-15\" href=\"#__codelineno-13-15\"></a>\n</span><span id=\"__span-13-16\"><a id=\"__codelineno-13-16\" name=\"__codelineno-13-16\" href=\"#__codelineno-13-16\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">file</span><span class=\"p\">.</span><span class=\"nx\">Close</span><span class=\"p\">()</span>\n</span><span id=\"__span-13-17\"><a id=\"__codelineno-13-17\" name=\"__codelineno-13-17\" href=\"#__codelineno-13-17\"></a>\n</span><span id=\"__span-13-18\"><a id=\"__codelineno-13-18\" name=\"__codelineno-13-18\" href=\"#__codelineno-13-18\"></a><span class=\"w\">    </span><span class=\"c1\">// Do something with file</span>\n</span><span id=\"__span-13-19\"><a id=\"__codelineno-13-19\" name=\"__codelineno-13-19\" href=\"#__codelineno-13-19\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-13-20\"><a id=\"__codelineno-13-20\" name=\"__codelineno-13-20\" href=\"#__codelineno-13-20\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Another solution is to make the <code>readFile</code> function a closure but intrinsically, this remains the same solution: adding another surrounding function to execute the <code>defer</code> calls during each iteration.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/35-defer-loop/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h2 id=\"strings\">Strings</h2>\n<h3 id=\"not-understanding-the-concept-of-rune-36\">Not understanding the concept of rune (#36)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Understanding that a rune corresponds to the concept of a Unicode code point and that it can be composed of multiple bytes should be part of the Go developer’s core knowledge to work accurately with strings.</p>\n</details>\n<p>As runes are everywhere in Go, it's important to understand the following:</p>\n<ul>\n<li>A charset is a set of characters, whereas an encoding describes how to translate a charset into binary.</li>\n<li>In Go, a string references an immutable slice of arbitrary bytes.</li>\n<li>Go source code is encoded using UTF-8. Hence, all string literals are UTF-8 strings. But because a string can contain arbitrary bytes, if it’s obtained from somewhere else (not the source code), it isn’t guaranteed to be based on the UTF-8 encoding.</li>\n<li>A <code>rune</code> corresponds to the concept of a Unicode code point, meaning an item represented by a single value.</li>\n<li>Using UTF-8, a Unicode code point can be encoded into 1 to 4 bytes.</li>\n<li>Using <code>len()</code> on a string in Go returns the number of bytes, not the number of runes.</li>\n</ul>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/36-rune/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"inaccurate-string-iteration-37\">Inaccurate string iteration (#37)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Iterating on a string with the <code>range</code> operator iterates on the runes with the index corresponding to the starting index of the rune’s byte sequence. To access a specific rune index (such as the third rune), convert the string into a <code>[]rune</code>.</p>\n</details>\n<p>Iterating on a string is a common operation for developers. Perhaps we want to perform an operation for each rune in the string or implement a custom function to search for a specific substring. In both cases, we have to iterate on the different runes of a string. But it’s easy to get confused about how iteration works.</p>\n<p>For example, consider the following example:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-14-1\"><a id=\"__codelineno-14-1\" name=\"__codelineno-14-1\" href=\"#__codelineno-14-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"s\">\"hêllo\"</span>\n</span><span id=\"__span-14-2\"><a id=\"__codelineno-14-2\" name=\"__codelineno-14-2\" href=\"#__codelineno-14-2\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-14-3\"><a id=\"__codelineno-14-3\" name=\"__codelineno-14-3\" href=\"#__codelineno-14-3\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"position %d: %c\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"p\">[</span><span class=\"nx\">i</span><span class=\"p\">])</span>\n</span><span id=\"__span-14-4\"><a id=\"__codelineno-14-4\" name=\"__codelineno-14-4\" href=\"#__codelineno-14-4\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-14-5\"><a id=\"__codelineno-14-5\" name=\"__codelineno-14-5\" href=\"#__codelineno-14-5\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"len=%d\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">))</span>\n</span></code></pre></div>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-15-1\"><a id=\"__codelineno-15-1\" name=\"__codelineno-15-1\" href=\"#__codelineno-15-1\"></a>position 0: h\n</span><span id=\"__span-15-2\"><a id=\"__codelineno-15-2\" name=\"__codelineno-15-2\" href=\"#__codelineno-15-2\"></a>position 1: Ã\n</span><span id=\"__span-15-3\"><a id=\"__codelineno-15-3\" name=\"__codelineno-15-3\" href=\"#__codelineno-15-3\"></a>position 3: l\n</span><span id=\"__span-15-4\"><a id=\"__codelineno-15-4\" name=\"__codelineno-15-4\" href=\"#__codelineno-15-4\"></a>position 4: l\n</span><span id=\"__span-15-5\"><a id=\"__codelineno-15-5\" name=\"__codelineno-15-5\" href=\"#__codelineno-15-5\"></a>position 5: o\n</span><span id=\"__span-15-6\"><a id=\"__codelineno-15-6\" name=\"__codelineno-15-6\" href=\"#__codelineno-15-6\"></a>len=6\n</span></code></pre></div>\n<p>Let's highlight three points that might be confusing:</p>\n<ul>\n<li>The second rune is Ã in the output instead of ê.</li>\n<li>We jumped from position 1 to position 3: what is at position 2?</li>\n<li>len returns a count of 6, whereas s contains only 5 runes.</li>\n</ul>\n<p>Let’s start with the last observation. We already mentioned that len returns the number of bytes in a string, not the number of runes. Because we assigned a string literal to <code>s</code>, <code>s</code> is a UTF-8 string. Meanwhile, the special character \"ê\" isn’t encoded in a single byte; it requires 2 bytes. Therefore, calling <code>len(s)</code> returns 6.</p>\n<p>Meanwhile, in the previous example, we have to understand that we don't iterate over each rune; instead, we iterate over each starting index of a rune:</p>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"img/rune.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"img/rune.png\"></a></p>\n<p>Printing <code>s[i]</code> doesn’t print the ith rune; it prints the UTF-8 representation of the byte at index <code>i</code>. Hence, we printed \"hÃllo\" instead of \"hêllo\".</p>\n<p>If we want to print all the different runes, we can either use the value element of the <code>range</code> operator:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-16-1\"><a id=\"__codelineno-16-1\" name=\"__codelineno-16-1\" href=\"#__codelineno-16-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"s\">\"hêllo\"</span>\n</span><span id=\"__span-16-2\"><a id=\"__codelineno-16-2\" name=\"__codelineno-16-2\" href=\"#__codelineno-16-2\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-16-3\"><a id=\"__codelineno-16-3\" name=\"__codelineno-16-3\" href=\"#__codelineno-16-3\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"position %d: %c\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"p\">)</span>\n</span><span id=\"__span-16-4\"><a id=\"__codelineno-16-4\" name=\"__codelineno-16-4\" href=\"#__codelineno-16-4\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Or, we can convert the string into a slice of runes and iterate over it:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-17-1\"><a id=\"__codelineno-17-1\" name=\"__codelineno-17-1\" href=\"#__codelineno-17-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"s\">\"hêllo\"</span>\n</span><span id=\"__span-17-2\"><a id=\"__codelineno-17-2\" name=\"__codelineno-17-2\" href=\"#__codelineno-17-2\"></a><span class=\"hll\"><span class=\"nx\">runes</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"nb\">rune</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-17-3\"><a id=\"__codelineno-17-3\" name=\"__codelineno-17-3\" href=\"#__codelineno-17-3\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">runes</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-17-4\"><a id=\"__codelineno-17-4\" name=\"__codelineno-17-4\" href=\"#__codelineno-17-4\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"position %d: %c\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"p\">)</span>\n</span><span id=\"__span-17-5\"><a id=\"__codelineno-17-5\" name=\"__codelineno-17-5\" href=\"#__codelineno-17-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Note that this solution introduces a run-time overhead compared to the previous one. Indeed, converting a string into a slice of runes requires allocating an additional slice and converting the bytes into runes: an O(n) time complexity with n the number of bytes in the string. Therefore, if we want to iterate over all the runes, we should use the first solution.</p>\n<p>However, if we want to access the ith rune of a string with the first option, we don’t have access to the rune index; rather, we know the starting index of a rune in the byte sequence.</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-18-1\"><a id=\"__codelineno-18-1\" name=\"__codelineno-18-1\" href=\"#__codelineno-18-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"s\">\"hêllo\"</span>\n</span><span id=\"__span-18-2\"><a id=\"__codelineno-18-2\" name=\"__codelineno-18-2\" href=\"#__codelineno-18-2\"></a><span class=\"nx\">r</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"nb\">rune</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)[</span><span class=\"mi\">4</span><span class=\"p\">]</span>\n</span><span id=\"__span-18-3\"><a id=\"__codelineno-18-3\" name=\"__codelineno-18-3\" href=\"#__codelineno-18-3\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"%c\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// o</span>\n</span></code></pre></div>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/37-string-iteration/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"misusing-trim-functions-38\">Misusing trim functions (#38)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p><code>strings.TrimRight</code>/<code>strings.TrimLeft</code> removes all the trailing/leading runes contained in a given set, whereas <code>strings.TrimSuffix</code>/<code>strings.TrimPrefix</code> returns a string without a provided suffix/prefix.</p>\n</details>\n<p>For example:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-19-1\"><a id=\"__codelineno-19-1\" name=\"__codelineno-19-1\" href=\"#__codelineno-19-1\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">strings</span><span class=\"p\">.</span><span class=\"nx\">TrimRight</span><span class=\"p\">(</span><span class=\"s\">\"123oxo\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s\">\"xo\"</span><span class=\"p\">))</span>\n</span></code></pre></div>\n<p>The example prints 123:</p>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"img/trim.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"img/trim.png\"></a></p>\n<p>Conversely, <code>strings.TrimLeft</code> removes all the leading runes contained in a set.</p>\n<p>On the other side, <code>strings.TrimSuffix</code> / <code>strings.TrimPrefix</code> returns a string without the provided trailing suffix / prefix.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/38-trim/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"under-optimized-strings-concatenation-39\">Under-optimized strings concatenation (#39)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Concatenating a list of strings should be done with <code>strings.Builder</code> to prevent allocating a new string during each iteration.</p>\n</details>\n<p>Let’s consider a <code>concat</code> function that concatenates all the string elements of a slice using the <code>+=</code> operator:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-20-1\"><a id=\"__codelineno-20-1\" name=\"__codelineno-20-1\" href=\"#__codelineno-20-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">concat</span><span class=\"p\">(</span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-20-2\"><a id=\"__codelineno-20-2\" name=\"__codelineno-20-2\" href=\"#__codelineno-20-2\"></a><span class=\"w\">    </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"s\">\"\"</span>\n</span><span id=\"__span-20-3\"><a id=\"__codelineno-20-3\" name=\"__codelineno-20-3\" href=\"#__codelineno-20-3\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">value</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-20-4\"><a id=\"__codelineno-20-4\" name=\"__codelineno-20-4\" href=\"#__codelineno-20-4\"></a><span class=\"w\">        </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"nx\">value</span>\n</span><span id=\"__span-20-5\"><a id=\"__codelineno-20-5\" name=\"__codelineno-20-5\" href=\"#__codelineno-20-5\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-20-6\"><a id=\"__codelineno-20-6\" name=\"__codelineno-20-6\" href=\"#__codelineno-20-6\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">s</span>\n</span><span id=\"__span-20-7\"><a id=\"__codelineno-20-7\" name=\"__codelineno-20-7\" href=\"#__codelineno-20-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>During each iteration, the <code>+=</code> operator concatenates <code>s</code> with the value string. At first sight, this function may not look wrong. But with this implementation, we forget one of the core characteristics of a string: its immutability. Therefore, each iteration doesn’t update <code>s</code>; it reallocates a new string in memory, which significantly impacts the performance of this function.</p>\n<p>Fortunately, there is a solution to deal with this problem, using <code>strings.Builder</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-21-1\"><a id=\"__codelineno-21-1\" name=\"__codelineno-21-1\" href=\"#__codelineno-21-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">concat</span><span class=\"p\">(</span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-21-2\"><a id=\"__codelineno-21-2\" name=\"__codelineno-21-2\" href=\"#__codelineno-21-2\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"nx\">sb</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">strings</span><span class=\"p\">.</span><span class=\"nx\">Builder</span><span class=\"p\">{}</span>\n</span></span><span id=\"__span-21-3\"><a id=\"__codelineno-21-3\" name=\"__codelineno-21-3\" href=\"#__codelineno-21-3\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">value</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-21-4\"><a id=\"__codelineno-21-4\" name=\"__codelineno-21-4\" href=\"#__codelineno-21-4\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">sb</span><span class=\"p\">.</span><span class=\"nx\">WriteString</span><span class=\"p\">(</span><span class=\"nx\">value</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-21-5\"><a id=\"__codelineno-21-5\" name=\"__codelineno-21-5\" href=\"#__codelineno-21-5\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-21-6\"><a id=\"__codelineno-21-6\" name=\"__codelineno-21-6\" href=\"#__codelineno-21-6\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">sb</span><span class=\"p\">.</span><span class=\"nx\">String</span><span class=\"p\">()</span>\n</span><span id=\"__span-21-7\"><a id=\"__codelineno-21-7\" name=\"__codelineno-21-7\" href=\"#__codelineno-21-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>During each iteration, we constructed the resulting string by calling the <code>WriteString</code> method that appends the content of value to its internal buffer, hence minimizing memory copying.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p><code>WriteString</code> returns an error as the second output, but we purposely ignore it. Indeed, this method will never return a non-nil error. So what’s the purpose of this method returning an error as part of its signature? <code>strings.Builder</code> implements the <code>io.StringWriter</code> interface, which contains a single method: <code>WriteString(s string) (n int, err error)</code>. Hence, to comply with this interface, <code>WriteString</code> must return an error.</p>\n</details>\n<p>Internally, <code>strings.Builder</code> holds a byte slice. Each call to <code>WriteString</code> results in a call to append on this slice. There are two impacts. First, this struct shouldn’t be used concurrently, as the calls to <code>append</code> would lead to race conditions. The second impact is something that we saw in <a href=\"#inefficient-slice-initialization-21\">mistake #21, \"Inefficient slice initialization\"</a>: if the future length of a slice is already known, we should preallocate it. For that purpose, <code>strings.Builder</code> exposes a method <code>Grow(n int)</code> to guarantee space for another <code>n</code> bytes:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-22-1\"><a id=\"__codelineno-22-1\" name=\"__codelineno-22-1\" href=\"#__codelineno-22-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">concat</span><span class=\"p\">(</span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-22-2\"><a id=\"__codelineno-22-2\" name=\"__codelineno-22-2\" href=\"#__codelineno-22-2\"></a><span class=\"w\">    </span><span class=\"nx\">total</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span>\n</span><span id=\"__span-22-3\"><a id=\"__codelineno-22-3\" name=\"__codelineno-22-3\" href=\"#__codelineno-22-3\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">values</span><span class=\"p\">);</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-22-4\"><a id=\"__codelineno-22-4\" name=\"__codelineno-22-4\" href=\"#__codelineno-22-4\"></a><span class=\"w\">        </span><span class=\"nx\">total</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">values</span><span class=\"p\">[</span><span class=\"nx\">i</span><span class=\"p\">])</span>\n</span><span id=\"__span-22-5\"><a id=\"__codelineno-22-5\" name=\"__codelineno-22-5\" href=\"#__codelineno-22-5\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-22-6\"><a id=\"__codelineno-22-6\" name=\"__codelineno-22-6\" href=\"#__codelineno-22-6\"></a>\n</span><span id=\"__span-22-7\"><a id=\"__codelineno-22-7\" name=\"__codelineno-22-7\" href=\"#__codelineno-22-7\"></a><span class=\"w\">    </span><span class=\"nx\">sb</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">strings</span><span class=\"p\">.</span><span class=\"nx\">Builder</span><span class=\"p\">{}</span>\n</span><span id=\"__span-22-8\"><a id=\"__codelineno-22-8\" name=\"__codelineno-22-8\" href=\"#__codelineno-22-8\"></a><span class=\"w\">    </span><span class=\"nx\">sb</span><span class=\"p\">.</span><span class=\"nx\">Grow</span><span class=\"p\">(</span><span class=\"nx\">total</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n</span><span id=\"__span-22-9\"><a id=\"__codelineno-22-9\" name=\"__codelineno-22-9\" href=\"#__codelineno-22-9\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">value</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-22-10\"><a id=\"__codelineno-22-10\" name=\"__codelineno-22-10\" href=\"#__codelineno-22-10\"></a><span class=\"w\">        </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">sb</span><span class=\"p\">.</span><span class=\"nx\">WriteString</span><span class=\"p\">(</span><span class=\"nx\">value</span><span class=\"p\">)</span>\n</span><span id=\"__span-22-11\"><a id=\"__codelineno-22-11\" name=\"__codelineno-22-11\" href=\"#__codelineno-22-11\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-22-12\"><a id=\"__codelineno-22-12\" name=\"__codelineno-22-12\" href=\"#__codelineno-22-12\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">sb</span><span class=\"p\">.</span><span class=\"nx\">String</span><span class=\"p\">()</span>\n</span><span id=\"__span-22-13\"><a id=\"__codelineno-22-13\" name=\"__codelineno-22-13\" href=\"#__codelineno-22-13\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Let’s run a benchmark to compare the three versions (v1 using <code>+=</code>; v2 using <code>strings.Builder{}</code> without preallocation; and v3 using <code>strings.Builder{}</code> with preallocation). The input slice contains 1,000 strings, and each string contains 1,000 bytes:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-23-1\"><a id=\"__codelineno-23-1\" name=\"__codelineno-23-1\" href=\"#__codelineno-23-1\"></a>BenchmarkConcatV1-4             16      72291485 ns/op\n</span><span id=\"__span-23-2\"><a id=\"__codelineno-23-2\" name=\"__codelineno-23-2\" href=\"#__codelineno-23-2\"></a>BenchmarkConcatV2-4           1188        878962 ns/op\n</span><span id=\"__span-23-3\"><a id=\"__codelineno-23-3\" name=\"__codelineno-23-3\" href=\"#__codelineno-23-3\"></a>BenchmarkConcatV3-4           5922        190340 ns/op\n</span></code></pre></div>\n<p>As we can see, the latest version is by far the most efficient: 99% faster than v1 and 78% faster than v2.</p>\n<p><code>strings.Builder</code> is the recommended solution to concatenate a list of strings. Usually, this solution should be used within a loop. Indeed, if we just have to concatenate a few strings (such as a name and a surname), using <code>strings.Builder</code> is not recommended as doing so will make the code a bit less readable than using the <code>+=</code> operator or <code>fmt.Sprintf</code>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/39-string-concat/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"useless-string-conversions-40\">Useless string conversions (#40)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Remembering that the <code>bytes</code> package offers the same operations as the <code>strings</code> package can help avoid extra byte/string conversions.</p>\n</details>\n<p>When choosing to work with a string or a <code>[]byte</code>, most programmers tend to favor strings for convenience. But most I/O is actually done with <code>[]byte</code>. For example, <code>io.Reader</code>, <code>io.Writer</code>, and <code>io.ReadAll</code> work with <code>[]byte</code>, not strings.</p>\n<p>When we’re wondering whether we should work with strings or <code>[]byte</code>, let’s recall that working with <code>[]byte</code> isn’t necessarily less convenient. Indeed, all the exported functions of the strings package also have alternatives in the <code>bytes</code> package: <code>Split</code>, <code>Count</code>, <code>Contains</code>, <code>Index</code>, and so on. Hence, whether we’re doing I/O or not, we should first check whether we could implement a whole workflow using bytes instead of strings and avoid the price of additional conversions.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/40-string-conversion/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"substring-and-memory-leaks-41\">Substring and memory leaks (#41)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Using copies instead of substrings can prevent memory leaks, as the string returned by a substring operation will be backed by the same byte array.</p>\n</details>\n<p>In mistake <a href=\"#slice-and-memory-leaks--26-\">#26, “Slices and memory leaks,”</a> we saw how slicing a slice or array may lead to memory leak situations. This principle also applies to string and substring operations.</p>\n<p>We need to keep two things in mind while using the substring operation in Go. First, the interval provided is based on the number of bytes, not the number of runes. Second, a substring operation may lead to a memory leak as the resulting substring will share the same backing array as the initial string. The solutions to prevent this case from happening are to perform a string copy manually or to use <code>strings.Clone</code> from Go 1.18.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/41-substring-memory-leak/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h2 id=\"functions-and-methods\">Functions and Methods</h2>\n<h3 id=\"not-knowing-which-type-of-receiver-to-use-42\">Not knowing which type of receiver to use (#42)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>The decision whether to use a value or a pointer receiver should be made based on factors such as the type, whether it has to be mutated, whether it contains a field that can’t be copied, and how large the object is. When in doubt, use a pointer receiver.</p>\n</details>\n<p>Choosing between value and pointer receivers isn’t always straightforward. Let’s discuss some of the conditions to help us choose.</p>\n<p>A receiver <em>must</em> be a pointer</p>\n<ul>\n<li>If the method needs to mutate the receiver. This rule is also valid if the receiver is a slice and a method needs to append elements:</li>\n</ul>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-24-1\"><a id=\"__codelineno-24-1\" name=\"__codelineno-24-1\" href=\"#__codelineno-24-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">slice</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">int</span>\n</span><span id=\"__span-24-2\"><a id=\"__codelineno-24-2\" name=\"__codelineno-24-2\" href=\"#__codelineno-24-2\"></a>\n</span><span id=\"__span-24-3\"><a id=\"__codelineno-24-3\" name=\"__codelineno-24-3\" href=\"#__codelineno-24-3\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">slice</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">add</span><span class=\"p\">(</span><span class=\"nx\">element</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-24-4\"><a id=\"__codelineno-24-4\" name=\"__codelineno-24-4\" href=\"#__codelineno-24-4\"></a><span class=\"w\">    </span><span class=\"o\">*</span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">element</span><span class=\"p\">)</span>\n</span><span id=\"__span-24-5\"><a id=\"__codelineno-24-5\" name=\"__codelineno-24-5\" href=\"#__codelineno-24-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<ul>\n<li>If the method receiver contains a field that cannot be copied: for example, a type part of the sync package (see <a href=\"#copying-a-sync-type--74-\">#74, “Copying a sync type”</a>).</li>\n</ul>\n<p>A receiver <em>should</em> be a pointer</p>\n<ul>\n<li>If the receiver is a large object. Using a pointer can make the call more efficient, as doing so prevents making an extensive copy. When in doubt about how large is large, benchmarking can be the solution; it’s pretty much impossible to state a specific size, because it depends on many factors.</li>\n</ul>\n<p>A receiver <em>must</em> be a value</p>\n<ul>\n<li>If we have to enforce a receiver’s immutability.</li>\n<li>If the receiver is a map, function, or channel. Otherwise, a compilation error\n  occurs.</li>\n</ul>\n<p>A receiver <em>should</em> be a value</p>\n<ul>\n<li>If the receiver is a slice that doesn’t have to be mutated.</li>\n<li>If the receiver is a small array or struct that is naturally a value type without mutable fields, such as <code>time.Time</code>.</li>\n<li>If the receiver is a basic type such as <code>int</code>, <code>float64</code>, or <code>string</code>.</li>\n</ul>\n<p>Of course, it’s impossible to be exhaustive, as there will always be edge cases, but this section’s goal was to provide guidance to cover most cases. By default, we can choose to go with a value receiver unless there’s a good reason not to do so. In doubt, we should use a pointer receiver.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/42-receiver/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"never-using-named-result-parameters-43\">Never using named result parameters (#43)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Using named result parameters can be an efficient way to improve the readability of a function/method, especially if multiple result parameters have the same type. In some cases, this approach can also be convenient because named result parameters are initialized to their zero value. But be cautious about potential side effects.</p>\n</details>\n<p>When we return parameters in a function or a method, we can attach names to these parameters and use them as regular variables. When a result parameter is named, it’s initialized to its zero value when the function/method begins. With named result parameters, we can also call a naked return statement (without arguments). In that case, the current values of the result parameters are used as the returned values.</p>\n<p>Here’s an example that uses a named result parameter <code>b</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-25-1\"><a id=\"__codelineno-25-1\" name=\"__codelineno-25-1\" href=\"#__codelineno-25-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">(</span><span class=\"nx\">a</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-25-2\"><a id=\"__codelineno-25-2\" name=\"__codelineno-25-2\" href=\"#__codelineno-25-2\"></a><span class=\"w\">    </span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">a</span>\n</span><span id=\"__span-25-3\"><a id=\"__codelineno-25-3\" name=\"__codelineno-25-3\" href=\"#__codelineno-25-3\"></a><span class=\"w\">    </span><span class=\"k\">return</span>\n</span><span id=\"__span-25-4\"><a id=\"__codelineno-25-4\" name=\"__codelineno-25-4\" href=\"#__codelineno-25-4\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>In this example, we attach a name to the result parameter: <code>b</code>. When we call return without arguments, it returns the current value of <code>b</code>.</p>\n<p>In some cases, named result parameters can also increase readability: for example, if two parameters have the same type. In other cases, they can also be used for convenience. Therefore, we should use named result parameters sparingly when there’s a clear benefit.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/43-named-result-parameters/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"unintended-side-effects-with-named-result-parameters-44\">Unintended side effects with named result parameters (#44)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>See <a href=\"#never-using-named-result-parameters-43\">#43</a>.</p>\n</details>\n<p>We mentioned why named result parameters can be useful in some situations. But as these result parameters are initialized to their zero value, using them can sometimes lead to subtle bugs if we’re not careful enough. For example, can you spot what’s wrong with this code?</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-26-1\"><a id=\"__codelineno-26-1\" name=\"__codelineno-26-1\" href=\"#__codelineno-26-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">l</span><span class=\"w\"> </span><span class=\"nx\">loc</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">getCoordinates</span><span class=\"p\">(</span><span class=\"nx\">ctx</span><span class=\"w\"> </span><span class=\"nx\">context</span><span class=\"p\">.</span><span class=\"nx\">Context</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">address</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span>\n</span><span id=\"__span-26-2\"><a id=\"__codelineno-26-2\" name=\"__codelineno-26-2\" href=\"#__codelineno-26-2\"></a><span class=\"w\">    </span><span class=\"nx\">lat</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">lng</span><span class=\"w\"> </span><span class=\"kt\">float32</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-26-3\"><a id=\"__codelineno-26-3\" name=\"__codelineno-26-3\" href=\"#__codelineno-26-3\"></a><span class=\"w\">    </span><span class=\"nx\">isValid</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">l</span><span class=\"p\">.</span><span class=\"nx\">validateAddress</span><span class=\"p\">(</span><span class=\"nx\">address</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-26-4\"><a id=\"__codelineno-26-4\" name=\"__codelineno-26-4\" href=\"#__codelineno-26-4\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"p\">!</span><span class=\"nx\">isValid</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-26-5\"><a id=\"__codelineno-26-5\" name=\"__codelineno-26-5\" href=\"#__codelineno-26-5\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">errors</span><span class=\"p\">.</span><span class=\"nx\">New</span><span class=\"p\">(</span><span class=\"s\">\"invalid address\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-26-6\"><a id=\"__codelineno-26-6\" name=\"__codelineno-26-6\" href=\"#__codelineno-26-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-26-7\"><a id=\"__codelineno-26-7\" name=\"__codelineno-26-7\" href=\"#__codelineno-26-7\"></a>\n</span><span id=\"__span-26-8\"><a id=\"__codelineno-26-8\" name=\"__codelineno-26-8\" href=\"#__codelineno-26-8\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">ctx</span><span class=\"p\">.</span><span class=\"nx\">Err</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n</span><span id=\"__span-26-9\"><a id=\"__codelineno-26-9\" name=\"__codelineno-26-9\" href=\"#__codelineno-26-9\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-26-10\"><a id=\"__codelineno-26-10\" name=\"__codelineno-26-10\" href=\"#__codelineno-26-10\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-26-11\"><a id=\"__codelineno-26-11\" name=\"__codelineno-26-11\" href=\"#__codelineno-26-11\"></a>\n</span><span id=\"__span-26-12\"><a id=\"__codelineno-26-12\" name=\"__codelineno-26-12\" href=\"#__codelineno-26-12\"></a><span class=\"w\">    </span><span class=\"c1\">// Get and return coordinates</span>\n</span><span id=\"__span-26-13\"><a id=\"__codelineno-26-13\" name=\"__codelineno-26-13\" href=\"#__codelineno-26-13\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>The error might not be obvious at first glance. Here, the error returned in the <code>if ctx.Err() != nil</code> scope is <code>err</code>. But we haven’t assigned any value to the <code>err</code> variable. It’s still assigned to the zero value of an <code>error</code> type: <code>nil</code>. Hence, this code will always return a nil error.</p>\n<p>When using named result parameters, we must recall that each parameter is initialized to its zero value. As we have seen in this section, this can lead to subtle bugs that aren’t always straightforward to spot while reading code. Therefore, let’s remain cautious when using named result parameters, to avoid potential side effects.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/44-side-effects-named-result-parameters/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"returning-a-nil-receiver-45\">Returning a nil receiver (#45)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>When returning an interface, be cautious about not returning a nil pointer but an explicit nil value. Otherwise, unintended consequences may occur and the caller will receive a non-nil value.</p>\n</details>\n<!-- TODO -->\n\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/45-nil-receiver/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"using-a-filename-as-a-function-input-46\">Using a filename as a function input (#46)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Designing functions to receive <code>io.Reader</code> types instead of filenames improves the reusability of a function and makes testing easier.</p>\n</details>\n<p>Accepting a filename as a function input to read from a file should, in most cases, be considered a code smell (except in specific functions such as <code>os.Open</code>). Indeed, it makes unit tests more complex because we may have to create multiple files. It also reduces the reusability of a function (although not all functions are meant to be reused). Using the <code>io.Reader</code> interface abstracts the data source. Regardless of whether the input is a file, a string, an HTTP request, or a gRPC request, the implementation can be reused and easily tested.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/46-function-input/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"ignoring-how-defer-arguments-and-receivers-are-evaluated-argument-evaluation-pointer-and-value-receivers-47\">Ignoring how <code>defer</code> arguments and receivers are evaluated (argument evaluation, pointer, and value receivers) (#47)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Passing a pointer to a <code>defer</code> function and wrapping a call inside a closure are two possible solutions to overcome the immediate evaluation of arguments and receivers.</p>\n</details>\n<p>In a <code>defer</code> function the arguments are evaluated right away, not once the surrounding function returns. For example, in this code, we always call <code>notify</code> and <code>incrementCounter</code> with the same status: an empty string.</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-27-1\"><a id=\"__codelineno-27-1\" name=\"__codelineno-27-1\" href=\"#__codelineno-27-1\"></a><span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"p\">(</span>\n</span><span id=\"__span-27-2\"><a id=\"__codelineno-27-2\" name=\"__codelineno-27-2\" href=\"#__codelineno-27-2\"></a><span class=\"w\">    </span><span class=\"nx\">StatusSuccess</span><span class=\"w\">  </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"s\">\"success\"</span>\n</span><span id=\"__span-27-3\"><a id=\"__codelineno-27-3\" name=\"__codelineno-27-3\" href=\"#__codelineno-27-3\"></a><span class=\"w\">    </span><span class=\"nx\">StatusErrorFoo</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"s\">\"error_foo\"</span>\n</span><span id=\"__span-27-4\"><a id=\"__codelineno-27-4\" name=\"__codelineno-27-4\" href=\"#__codelineno-27-4\"></a><span class=\"w\">    </span><span class=\"nx\">StatusErrorBar</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"s\">\"error_bar\"</span>\n</span><span id=\"__span-27-5\"><a id=\"__codelineno-27-5\" name=\"__codelineno-27-5\" href=\"#__codelineno-27-5\"></a><span class=\"p\">)</span>\n</span><span id=\"__span-27-6\"><a id=\"__codelineno-27-6\" name=\"__codelineno-27-6\" href=\"#__codelineno-27-6\"></a>\n</span><span id=\"__span-27-7\"><a id=\"__codelineno-27-7\" name=\"__codelineno-27-7\" href=\"#__codelineno-27-7\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-27-8\"><a id=\"__codelineno-27-8\" name=\"__codelineno-27-8\" href=\"#__codelineno-27-8\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"kt\">string</span>\n</span><span id=\"__span-27-9\"><a id=\"__codelineno-27-9\" name=\"__codelineno-27-9\" href=\"#__codelineno-27-9\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">notify</span><span class=\"p\">(</span><span class=\"nx\">status</span><span class=\"p\">)</span>\n</span><span id=\"__span-27-10\"><a id=\"__codelineno-27-10\" name=\"__codelineno-27-10\" href=\"#__codelineno-27-10\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">incrementCounter</span><span class=\"p\">(</span><span class=\"nx\">status</span><span class=\"p\">)</span>\n</span><span id=\"__span-27-11\"><a id=\"__codelineno-27-11\" name=\"__codelineno-27-11\" href=\"#__codelineno-27-11\"></a>\n</span><span id=\"__span-27-12\"><a id=\"__codelineno-27-12\" name=\"__codelineno-27-12\" href=\"#__codelineno-27-12\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">foo</span><span class=\"p\">();</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-27-13\"><a id=\"__codelineno-27-13\" name=\"__codelineno-27-13\" href=\"#__codelineno-27-13\"></a><span class=\"w\">        </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">StatusErrorFoo</span>\n</span><span id=\"__span-27-14\"><a id=\"__codelineno-27-14\" name=\"__codelineno-27-14\" href=\"#__codelineno-27-14\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-27-15\"><a id=\"__codelineno-27-15\" name=\"__codelineno-27-15\" href=\"#__codelineno-27-15\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-27-16\"><a id=\"__codelineno-27-16\" name=\"__codelineno-27-16\" href=\"#__codelineno-27-16\"></a>\n</span><span id=\"__span-27-17\"><a id=\"__codelineno-27-17\" name=\"__codelineno-27-17\" href=\"#__codelineno-27-17\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">bar</span><span class=\"p\">();</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-27-18\"><a id=\"__codelineno-27-18\" name=\"__codelineno-27-18\" href=\"#__codelineno-27-18\"></a><span class=\"w\">        </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">StatusErrorBar</span>\n</span><span id=\"__span-27-19\"><a id=\"__codelineno-27-19\" name=\"__codelineno-27-19\" href=\"#__codelineno-27-19\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-27-20\"><a id=\"__codelineno-27-20\" name=\"__codelineno-27-20\" href=\"#__codelineno-27-20\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-27-21\"><a id=\"__codelineno-27-21\" name=\"__codelineno-27-21\" href=\"#__codelineno-27-21\"></a>\n</span><span id=\"__span-27-22\"><a id=\"__codelineno-27-22\" name=\"__codelineno-27-22\" href=\"#__codelineno-27-22\"></a><span class=\"w\">    </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">StatusSuccess</span>\n</span><span id=\"__span-27-23\"><a id=\"__codelineno-27-23\" name=\"__codelineno-27-23\" href=\"#__codelineno-27-23\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-27-24\"><a id=\"__codelineno-27-24\" name=\"__codelineno-27-24\" href=\"#__codelineno-27-24\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Indeed, we call <code>notify(status)</code> and <code>incrementCounter(status)</code> as <code>defer</code> functions. Therefore, Go will delay these calls to be executed once <code>f</code> returns with the current value of status at the stage we used defer, hence passing an empty string.</p>\n<p>Two leading options if we want to keep using <code>defer</code>.</p>\n<p>The first solution is to pass a string pointer:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-28-1\"><a id=\"__codelineno-28-1\" name=\"__codelineno-28-1\" href=\"#__codelineno-28-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-28-2\"><a id=\"__codelineno-28-2\" name=\"__codelineno-28-2\" href=\"#__codelineno-28-2\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"kt\">string</span>\n</span><span id=\"__span-28-3\"><a id=\"__codelineno-28-3\" name=\"__codelineno-28-3\" href=\"#__codelineno-28-3\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">notify</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">status</span><span class=\"p\">)</span><span class=\"w\"> </span>\n</span></span><span id=\"__span-28-4\"><a id=\"__codelineno-28-4\" name=\"__codelineno-28-4\" href=\"#__codelineno-28-4\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">incrementCounter</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">status</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-28-5\"><a id=\"__codelineno-28-5\" name=\"__codelineno-28-5\" href=\"#__codelineno-28-5\"></a>\n</span><span id=\"__span-28-6\"><a id=\"__codelineno-28-6\" name=\"__codelineno-28-6\" href=\"#__codelineno-28-6\"></a><span class=\"w\">    </span><span class=\"c1\">// The rest of the function unchanged</span>\n</span><span id=\"__span-28-7\"><a id=\"__codelineno-28-7\" name=\"__codelineno-28-7\" href=\"#__codelineno-28-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Using <code>defer</code> evaluates the arguments right away: here, the address of status. Yes, status itself is modified throughout the function, but its address remains constant, regardless of the assignments. Hence, if <code>notify</code> or <code>incrementCounter</code> uses the value referenced by the string pointer, it will work as expected. But this solution requires changing the signature of the two functions, which may not always be possible.</p>\n<p>There’s another solution: calling a closure (an anonymous function value that references variables from outside its body) as a <code>defer</code> statement:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-29-1\"><a id=\"__codelineno-29-1\" name=\"__codelineno-29-1\" href=\"#__codelineno-29-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-29-2\"><a id=\"__codelineno-29-2\" name=\"__codelineno-29-2\" href=\"#__codelineno-29-2\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"kt\">string</span>\n</span><span id=\"__span-29-3\"><a id=\"__codelineno-29-3\" name=\"__codelineno-29-3\" href=\"#__codelineno-29-3\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span></span><span id=\"__span-29-4\"><a id=\"__codelineno-29-4\" name=\"__codelineno-29-4\" href=\"#__codelineno-29-4\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"nx\">notify</span><span class=\"p\">(</span><span class=\"nx\">status</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-29-5\"><a id=\"__codelineno-29-5\" name=\"__codelineno-29-5\" href=\"#__codelineno-29-5\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"nx\">incrementCounter</span><span class=\"p\">(</span><span class=\"nx\">status</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-29-6\"><a id=\"__codelineno-29-6\" name=\"__codelineno-29-6\" href=\"#__codelineno-29-6\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span></span><span id=\"__span-29-7\"><a id=\"__codelineno-29-7\" name=\"__codelineno-29-7\" href=\"#__codelineno-29-7\"></a>\n</span><span id=\"__span-29-8\"><a id=\"__codelineno-29-8\" name=\"__codelineno-29-8\" href=\"#__codelineno-29-8\"></a><span class=\"w\">    </span><span class=\"c1\">// The rest of the function unchanged</span>\n</span><span id=\"__span-29-9\"><a id=\"__codelineno-29-9\" name=\"__codelineno-29-9\" href=\"#__codelineno-29-9\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Here, we wrap the calls to both <code>notify</code> and <code>incrementCounter</code> within a closure. This closure references the status variable from outside its body. Therefore, <code>status</code> is evaluated once the closure is executed, not when we call <code>defer</code>. This solution also works and doesn’t require <code>notify</code> and <code>incrementCounter</code> to change their signature.</p>\n<p>Let's also note this behavior applies with method receiver: the receiver is evaluated immediately.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/47-defer-evaluation/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h2 id=\"error-management\">Error Management</h2>\n<h3 id=\"panicking-48\">Panicking (#48)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Using <code>panic</code> is an option to deal with errors in Go. However, it should only be used sparingly in unrecoverable conditions: for example, to signal a programmer error or when you fail to load a mandatory dependency.</p>\n</details>\n<p>In Go, panic is a built-in function that stops the ordinary flow:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-30-1\"><a id=\"__codelineno-30-1\" name=\"__codelineno-30-1\" href=\"#__codelineno-30-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-30-2\"><a id=\"__codelineno-30-2\" name=\"__codelineno-30-2\" href=\"#__codelineno-30-2\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"s\">\"a\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-30-3\"><a id=\"__codelineno-30-3\" name=\"__codelineno-30-3\" href=\"#__codelineno-30-3\"></a><span class=\"w\">    </span><span class=\"nb\">panic</span><span class=\"p\">(</span><span class=\"s\">\"foo\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-30-4\"><a id=\"__codelineno-30-4\" name=\"__codelineno-30-4\" href=\"#__codelineno-30-4\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"s\">\"b\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-30-5\"><a id=\"__codelineno-30-5\" name=\"__codelineno-30-5\" href=\"#__codelineno-30-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>This code prints a and then stops before printing b:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-31-1\"><a id=\"__codelineno-31-1\" name=\"__codelineno-31-1\" href=\"#__codelineno-31-1\"></a>a\n</span><span id=\"__span-31-2\"><a id=\"__codelineno-31-2\" name=\"__codelineno-31-2\" href=\"#__codelineno-31-2\"></a>panic: foo\n</span><span id=\"__span-31-3\"><a id=\"__codelineno-31-3\" name=\"__codelineno-31-3\" href=\"#__codelineno-31-3\"></a>\n</span><span id=\"__span-31-4\"><a id=\"__codelineno-31-4\" name=\"__codelineno-31-4\" href=\"#__codelineno-31-4\"></a>goroutine 1 [running]:\n</span><span id=\"__span-31-5\"><a id=\"__codelineno-31-5\" name=\"__codelineno-31-5\" href=\"#__codelineno-31-5\"></a>main.main()\n</span><span id=\"__span-31-6\"><a id=\"__codelineno-31-6\" name=\"__codelineno-31-6\" href=\"#__codelineno-31-6\"></a>        main.go:7 +0xb3\n</span></code></pre></div>\n<p>Panicking in Go should be used sparingly. There are two prominent cases, one to signal a programmer error (e.g., <a href=\"https://cs.opensource.google/go/go/+/refs/tags/go1.20.7:src/database/sql/sql.go;l=44\"><code>sql.Register</code></a> that panics if the driver is <code>nil</code> or has already been register) and another where our application fails to create a mandatory dependency. Hence, exceptional conditions that lead us to stop the application. In most other cases, error management should be done with a function that returns a proper error type as the last return argument.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/48-panic/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"ignoring-when-to-wrap-an-error-49\">Ignoring when to wrap an error (#49)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Wrapping an error allows you to mark an error and/or provide additional context. However, error wrapping creates potential coupling as it makes the source error available for the caller. If you want to prevent that, don’t use error wrapping.</p>\n</details>\n<p>Since Go 1.13, the %w directive allows us to wrap errors conveniently. Error wrapping is about wrapping or packing an error inside a wrapper container that also makes the source error available. In general, the two main use cases for error wrapping are the following:</p>\n<ul>\n<li>Adding additional context to an error</li>\n<li>Marking an error as a specific error</li>\n</ul>\n<p>When handling an error, we can decide to wrap it. Wrapping is about adding additional context to an error and/or marking an error as a specific type. If we need to mark an error, we should create a custom error type. However, if we just want to add extra context, we should use fmt.Errorf with the %w directive as it doesn’t require creating a new error type. Yet, error wrapping creates potential coupling as it makes the source error available for the caller. If we want to prevent it, we shouldn’t use error wrapping but error transformation, for example, using fmt.Errorf with the %v directive.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/49-error-wrapping/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"comparing-an-error-type-inaccurately-50\">Comparing an error type inaccurately (#50)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>If you use Go 1.13 error wrapping with the <code>%w</code> directive and <code>fmt.Errorf</code>, comparing an error against a type has to be done using <code>errors.As</code>. Otherwise, if the returned error you want to check is wrapped, it will fail the checks.</p>\n</details>\n<!-- TODO -->\n\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/50-compare-error-type/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"comparing-an-error-value-inaccurately-51\">Comparing an error value inaccurately (#51)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>If you use Go 1.13 error wrapping with the <code>%w</code> directive and <code>fmt.Errorf</code>, comparing an error against or a value has to be done using <code>errors.As</code>. Otherwise, if the returned error you want to check is wrapped, it will fail the checks.</p>\n</details>\n<p>A sentinel error is an error defined as a global variable:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-32-1\"><a id=\"__codelineno-32-1\" name=\"__codelineno-32-1\" href=\"#__codelineno-32-1\"></a><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"s\">\"errors\"</span>\n</span><span id=\"__span-32-2\"><a id=\"__codelineno-32-2\" name=\"__codelineno-32-2\" href=\"#__codelineno-32-2\"></a>\n</span><span id=\"__span-32-3\"><a id=\"__codelineno-32-3\" name=\"__codelineno-32-3\" href=\"#__codelineno-32-3\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">ErrFoo</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">errors</span><span class=\"p\">.</span><span class=\"nx\">New</span><span class=\"p\">(</span><span class=\"s\">\"foo\"</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>In general, the convention is to start with <code>Err</code> followed by the error type: here, <code>ErrFoo</code>. A sentinel error conveys an <em>expected</em> error, an error that clients will expect to check. As general guidelines:</p>\n<ul>\n<li>Expected errors should be designed as error values (sentinel errors): <code>var ErrFoo = errors.New(\"foo\")</code>.</li>\n<li>Unexpected errors should be designed as error types: <code>type BarError struct { ... }</code>, with <code>BarError</code> implementing the <code>error</code> interface.</li>\n</ul>\n<p>If we use error wrapping in our application with the <code>%w</code> directive and <code>fmt.Errorf</code>, checking an error against a specific value should be done using <code>errors.Is</code> instead of <code>==</code>. Thus, even if the sentinel error is wrapped, <code>errors.Is</code> can recursively unwrap it and compare each error in the chain against the provided value.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/51-comparing-error-value/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"handling-an-error-twice-52\">Handling an error twice (#52)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>In most situations, an error should be handled only once. Logging an error is handling an error. Therefore, you have to choose between logging or returning an error. In many cases, error wrapping is the solution as it allows you to provide additional context to an error and return the source error.</p>\n</details>\n<p>Handling an error multiple times is a mistake made frequently by developers, not specifically in Go. This can cause situations where the same error is logged multiple times make debugging harder.</p>\n<p>Let's remind us that handling an error should be done only once. Logging an error is handling an error. Hence, we should either log or return an error. By doing this, we simplify our code and gain better insights into the error situation. Using error wrapping is the most convenient approach as it allows us to propagate the source error and add context to an error.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/52-handling-error-twice/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-handling-an-error-53\">Not handling an error (#53)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Ignoring an error, whether during a function call or in a <code>defer</code> function, should be done explicitly using the blank identifier. Otherwise, future readers may be confused about whether it was intentional or a miss.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/53-not-handling-error/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-handling-defer-errors-54\">Not handling <code>defer</code> errors (#54)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>In many cases, you shouldn’t ignore an error returned by a <code>defer</code> function. Either handle it directly or propagate it to the caller, depending on the context. If you want to ignore it, use the blank identifier.</p>\n</details>\n<p>Consider the following code:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-33-1\"><a id=\"__codelineno-33-1\" name=\"__codelineno-33-1\" href=\"#__codelineno-33-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-33-2\"><a id=\"__codelineno-33-2\" name=\"__codelineno-33-2\" href=\"#__codelineno-33-2\"></a><span class=\"w\">  </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-33-3\"><a id=\"__codelineno-33-3\" name=\"__codelineno-33-3\" href=\"#__codelineno-33-3\"></a><span class=\"w\">  </span><span class=\"nx\">notify</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// Error handling is omitted</span>\n</span><span id=\"__span-33-4\"><a id=\"__codelineno-33-4\" name=\"__codelineno-33-4\" href=\"#__codelineno-33-4\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-33-5\"><a id=\"__codelineno-33-5\" name=\"__codelineno-33-5\" href=\"#__codelineno-33-5\"></a>\n</span><span id=\"__span-33-6\"><a id=\"__codelineno-33-6\" name=\"__codelineno-33-6\" href=\"#__codelineno-33-6\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">notify</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-33-7\"><a id=\"__codelineno-33-7\" name=\"__codelineno-33-7\" href=\"#__codelineno-33-7\"></a><span class=\"w\">  </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-33-8\"><a id=\"__codelineno-33-8\" name=\"__codelineno-33-8\" href=\"#__codelineno-33-8\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>From a maintainability perspective, the code can lead to some issues. Let’s consider a new reader looking at it. This reader notices that notify returns an error but that the error isn’t handled by the parent function. How can they guess whether or not handling the error was intentional? How can they know whether the previous developer forgot to handle it or did it purposely?</p>\n<p>For these reasons, when we want to ignore an error, there's only one way to do it, using the blank identifier (<code>_</code>):</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-34-1\"><a id=\"__codelineno-34-1\" name=\"__codelineno-34-1\" href=\"#__codelineno-34-1\"></a><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">notify</span>\n</span></code></pre></div>\n<p>In terms of compilation and run time, this approach doesn’t change anything compared to the first piece of code. But this new version makes explicit that we aren’t interested in the error. Also, we can add a comment that indicates the rationale for why an error is ignored:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-35-1\"><a id=\"__codelineno-35-1\" name=\"__codelineno-35-1\" href=\"#__codelineno-35-1\"></a><span class=\"c1\">// At-most once delivery.</span>\n</span><span id=\"__span-35-2\"><a id=\"__codelineno-35-2\" name=\"__codelineno-35-2\" href=\"#__codelineno-35-2\"></a><span class=\"c1\">// Hence, it's accepted to miss some of them in case of errors.</span>\n</span><span id=\"__span-35-3\"><a id=\"__codelineno-35-3\" name=\"__codelineno-35-3\" href=\"#__codelineno-35-3\"></a><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">notify</span><span class=\"p\">()</span>\n</span></code></pre></div>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/54-defer-errors/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h2 id=\"concurrency-foundations\">Concurrency: Foundations</h2>\n<h3 id=\"mixing-up-concurrency-and-parallelism-55\">Mixing up concurrency and parallelism (#55)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Understanding the fundamental differences between concurrency and parallelism is a cornerstone of the Go developer’s knowledge. Concurrency is about structure, whereas parallelism is about execution.</p>\n</details>\n<p>Concurrency and parallelism are not the same:</p>\n<ul>\n<li>Concurrency is about structure. We can change a sequential implementation into a concurrent one by introducing different steps that separate concurrent goroutines can tackle.</li>\n<li>Meanwhile, parallelism is about execution. We can use parallism at the steps level by adding more parallel goroutines.</li>\n</ul>\n<p>In summary, concurrency provides a structure to solve a problem with parts that may be parallelized. Therefore, <em>concurrency enables parallelism</em>.</p>\n<!-- TODO Include Rob Pike's talk link-->\n\n<h3 id=\"thinking-concurrency-is-always-faster-56\">Thinking concurrency is always faster (#56)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>To be a proficient developer, you must acknowledge that concurrency isn’t always faster. Solutions involving parallelization of minimal workloads may not necessarily be faster than a sequential implementation. Benchmarking sequential versus concurrent solutions should be the way to validate assumptions.</p>\n</details>\n<p>Read the full section <a href=\"56-concurrency-faster/\">here</a>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/56-faster/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"being-puzzled-about-when-to-use-channels-or-mutexes-57\">Being puzzled about when to use channels or mutexes (#57)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Being aware of goroutine interactions can also be helpful when deciding between channels and mutexes. In general, parallel goroutines require synchronization and hence mutexes. Conversely, concurrent goroutines generally require coordination and orchestration and hence channels.</p>\n</details>\n<p>Given a concurrency problem, it may not always be clear whether we can implement a\nsolution using channels or mutexes. Because Go promotes sharing memory by communication, one mistake could be to always force the use of channels, regardless of\nthe use case. However, we should see the two options as complementary. </p>\n<p>When should we use channels or mutexes? We will use the example in the next figure as a backbone. Our example has three different goroutines with specific relationships:</p>\n<ul>\n<li>G1 and G2 are parallel goroutines. They may be two goroutines executing the same function that keeps receiving messages from a channel, or perhaps two goroutines executing the same HTTP handler at the same time.</li>\n<li>On the other hand, G1 and G3 are concurrent goroutines, as are G2 and G3. All the goroutines are part of an overall concurrent structure, but G1 and G2 perform the first step, whereas G3 does the next step.</li>\n</ul>\n<!-- TODO Include figure-->\n\n<p>In general, parallel goroutines have to <em>synchronize</em>: for example, when they need to access or mutate a shared resource such as a slice. Synchronization is enforced with mutexes but not with any channel types (not with buffered channels). Hence, in general, synchronization between parallel goroutines should be achieved via mutexes.</p>\n<p>Conversely, in general, concurrent goroutines have to <em>coordinate and orchestrate</em>. For example, if G3 needs to aggregate results from both G1 and G2, G1 and G2 need to signal to G3 that a new intermediate result is available. This coordination falls under the scope of communication—therefore, channels.</p>\n<p>Regarding concurrent goroutines, there’s also the case where we want to transfer the ownership of a resource from one step (G1 and G2) to another (G3); for example, if G1 and G2 are enriching a shared resource and at some point, we consider this job as complete. Here, we should use channels to signal that a specific resource is ready and handle the ownership transfer.</p>\n<p>Mutexes and channels have different semantics. Whenever we want to share a state or access a shared resource, mutexes ensure exclusive access to this resource. Conversely, channels are a mechanic for signaling with or without data (<code>chan struct{}</code> or not). Coordination or ownership transfer should be achieved via channels. It’s important to know whether goroutines are parallel or concurrent because, in general, we need mutexes for parallel goroutines and channels for concurrent ones.</p>\n<h3 id=\"not-understanding-race-problems-data-races-vs-race-conditions-and-the-go-memory-model-58\">Not understanding race problems (data races vs. race conditions and the Go memory model) (#58)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Being proficient in concurrency also means understanding that data races and race conditions are different concepts. Data races occur when multiple goroutines simultaneously access the same memory location and at least one of them is writing. Meanwhile, being data-race-free doesn’t necessarily mean deterministic execution. When a behavior depends on the sequence or the timing of events that can’t be controlled, this is a race condition.</p>\n</details>\n<p>Race problems can be among the hardest and most insidious bugs a programmer can face. As Go developers, we must understand crucial aspects such as data races and race conditions, their possible impacts, and how to avoid them.</p>\n<h4 id=\"data-race\">Data Race</h4>\n<p>A data race occurs when two or more goroutines simultaneously access the same memory location and at least one is writing. In this case, the result can be hazardous. Even worse, in some situations, the memory location may end up holding a value containing a meaningless combination of bits.</p>\n<p>We can prevent a data race from happening using different techniques. For example: </p>\n<ul>\n<li>Using the <code>sync/atomic</code> package</li>\n<li>In synchronizing the two goroutines with an ad hoc data structure like a mutex</li>\n<li>Using channels to make the two goroutines communicating to ensure that a variable is updated by only one goroutine at a time</li>\n</ul>\n<h4 id=\"race-condition\">Race Condition</h4>\n<p>Depending on the operation we want to perform, does a data-race-free application necessarily mean a deterministic result? Not necessarily.</p>\n<p>A race condition occurs when the behavior depends on the sequence or the timing of events that can’t be controlled. Here, the timing of events is the goroutines’ execution order.</p>\n<p>In summary, when we work in concurrent applications, it’s essential to understand that a data race is different from a race condition. A data race occurs when multiple goroutines simultaneously access the same memory location and at least one of them is writing. A data race means unexpected behavior. However, a data-race-free application doesn’t necessarily mean deterministic results. An application can be free of data races but still have behavior that depends on uncontrolled events (such as goroutine execution, how fast a message is published to a channel, or how long a call to a database lasts); this is a race condition. Understanding both concepts is crucial to becoming proficient in designing concurrent applications.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/58-races/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-understanding-the-concurrency-impacts-of-a-workload-type-59\">Not understanding the concurrency impacts of a workload type (#59)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>When creating a certain number of goroutines, consider the workload type. Creating CPU-bound goroutines means bounding this number close to the <abbr title=\"The variable defines the limit of OS threads in charge of executing user-level code simultaneously\">GOMAXPROCS</abbr> variable (based by default on the number of CPU cores on the host). Creating I/O-bound goroutines depends on other factors, such as the external system.</p>\n</details>\n<p>In programming, the execution time of a workload is limited by one of the following:</p>\n<ul>\n<li>The speed of the CPU—For example, running a merge sort algorithm. The workload is called CPU-bound.</li>\n<li>The speed of I/O—For example, making a REST call or a database query. The workload is called I/O-bound.</li>\n<li>The amount of available memory—The workload is called memory-bound.</li>\n</ul>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>The last is the rarest nowadays, given that memory has become very cheap in recent decades. Hence, this section focuses on the two first workload types: CPU- and I/O-bound.</p>\n</details>\n<p>If the workload executed by the workers is I/O-bound, the value mainly depends on the external system. Conversely, if the workload is CPU-bound, the optimal number of goroutines is close to the number of available CPU cores (a best practice can be to use <code>runtime.GOMAXPROCS</code>). Knowing the workload type (I/O or CPU) is crucial when designing concurrent applications.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/59-workload-type/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"misunderstanding-go-contexts-60\">Misunderstanding Go contexts (#60)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Go contexts are also one of the cornerstones of concurrency in Go. A context allows you to carry a deadline, a cancellation signal, and/or a list of keys-values.</p>\n</details>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">https://pkg.go.dev/context</p>\n<p>A Context carries a deadline, a cancellation signal, and other values across API boundaries.</p>\n</div>\n<h4 id=\"deadline\">Deadline</h4>\n<p>A deadline refers to a specific point in time determined with one of the following:</p>\n<ul>\n<li>A <code>time.Duration</code> from now (for example, in 250 ms)</li>\n<li>A <code>time.Time</code> (for example, 2023-02-07 00:00:00 UTC)</li>\n</ul>\n<p>The semantics of a deadline convey that an ongoing activity should be stopped if this deadline is met. An activity is, for example, an I/O request or a goroutine waiting to receive a message from a channel.</p>\n<h4 id=\"cancellation-signals\">Cancellation signals</h4>\n<p>Another use case for Go contexts is to carry a cancellation signal. Let’s imagine that we want to create an application that calls <code>CreateFileWatcher(ctx context.Context, filename string)</code> within another goroutine. This function creates a specific file watcher that keeps reading from a file and catches updates. When the provided context expires or is canceled, this function handles it to close the file descriptor.</p>\n<h4 id=\"context-values\">Context values</h4>\n<p>The last use case for Go contexts is to carry a key-value list. What’s the point of having a context carrying a key-value list? Because Go contexts are generic and mainstream, there are infinite use cases.</p>\n<p>For example, if we use tracing, we may want different subfunctions to share the same correlation ID. Some developers may consider this ID too invasive to be part of the function signature. In this regard, we could also decide to include it as part of the provided context.</p>\n<h4 id=\"catching-a-context-cancellation\">Catching a context cancellation</h4>\n<p>The <code>context.Context</code> type exports a <code>Done</code> method that returns a receive-only notification channel: <code>&lt;-chan struct{}</code>. This channel is closed when the work associated with the context should be canceled. For example,</p>\n<ul>\n<li>The Done channel related to a context created with <code>context.WithCancel</code> is closed when the cancel function is called.</li>\n<li>The Done channel related to a context created with <code>context.WithDeadline</code> is closed when the deadline has expired.</li>\n</ul>\n<p>One thing to note is that the internal channel should be closed when a context is canceled or has met a deadline, instead of when it receives a specific value, because the closure of a channel is the only channel action that all the consumer goroutines will receive. This way, all the consumers will be notified once a context is canceled or a deadline is reached.</p>\n<p>In summary, to be a proficient Go developer, we have to understand what a context is and how to use it. In general, a function that users wait for should take a context, as doing so allows upstream callers to decide when calling this function should be aborted. </p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/60-contexts/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h2 id=\"concurrency-practice\">Concurrency: Practice</h2>\n<h3 id=\"propagating-an-inappropriate-context-61\">Propagating an inappropriate context (#61)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Understanding the conditions when a context can be canceled should matter when propagating it: for example, an HTTP handler canceling the context when the response has been sent.</p>\n</details>\n<p>In many situations, it is recommended to propagate Go contexts. However, context propagation can sometimes lead to subtle bugs, preventing subfunctions from being correctly executed.</p>\n<p>Let’s consider the following example. We expose an HTTP handler that performs some tasks and returns a response. But just before returning the response, we also want to send it to a Kafka topic. We don’t want to penalize the HTTP consumer latency-wise, so we want the publish action to be handled asynchronously within a new goroutine. We assume that we have at our disposal a <code>publish</code> function that accepts a context so the action of publishing a message can be interrupted if the context is canceled, for example. Here is a possible implementation:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-36-1\"><a id=\"__codelineno-36-1\" name=\"__codelineno-36-1\" href=\"#__codelineno-36-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">handler</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">ResponseWriter</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Request</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-36-2\"><a id=\"__codelineno-36-2\" name=\"__codelineno-36-2\" href=\"#__codelineno-36-2\"></a><span class=\"w\">    </span><span class=\"nx\">response</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">doSomeTask</span><span class=\"p\">(</span><span class=\"nx\">r</span><span class=\"p\">.</span><span class=\"nx\">Context</span><span class=\"p\">(),</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"p\">)</span>\n</span><span id=\"__span-36-3\"><a id=\"__codelineno-36-3\" name=\"__codelineno-36-3\" href=\"#__codelineno-36-3\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-36-4\"><a id=\"__codelineno-36-4\" name=\"__codelineno-36-4\" href=\"#__codelineno-36-4\"></a><span class=\"w\">        </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Error</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">Error</span><span class=\"p\">(),</span><span class=\"w\"> </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">StatusInternalServerError</span><span class=\"p\">)</span>\n</span><span id=\"__span-36-5\"><a id=\"__codelineno-36-5\" name=\"__codelineno-36-5\" href=\"#__codelineno-36-5\"></a><span class=\"w\">    </span><span class=\"k\">return</span>\n</span><span id=\"__span-36-6\"><a id=\"__codelineno-36-6\" name=\"__codelineno-36-6\" href=\"#__codelineno-36-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-36-7\"><a id=\"__codelineno-36-7\" name=\"__codelineno-36-7\" href=\"#__codelineno-36-7\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-36-8\"><a id=\"__codelineno-36-8\" name=\"__codelineno-36-8\" href=\"#__codelineno-36-8\"></a><span class=\"w\">        </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">publish</span><span class=\"p\">(</span><span class=\"nx\">r</span><span class=\"p\">.</span><span class=\"nx\">Context</span><span class=\"p\">(),</span><span class=\"w\"> </span><span class=\"nx\">response</span><span class=\"p\">)</span>\n</span><span id=\"__span-36-9\"><a id=\"__codelineno-36-9\" name=\"__codelineno-36-9\" href=\"#__codelineno-36-9\"></a><span class=\"w\">        </span><span class=\"c1\">// Do something with err</span>\n</span><span id=\"__span-36-10\"><a id=\"__codelineno-36-10\" name=\"__codelineno-36-10\" href=\"#__codelineno-36-10\"></a><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span><span id=\"__span-36-11\"><a id=\"__codelineno-36-11\" name=\"__codelineno-36-11\" href=\"#__codelineno-36-11\"></a><span class=\"w\">    </span><span class=\"nx\">writeResponse</span><span class=\"p\">(</span><span class=\"nx\">response</span><span class=\"p\">)</span>\n</span><span id=\"__span-36-12\"><a id=\"__codelineno-36-12\" name=\"__codelineno-36-12\" href=\"#__codelineno-36-12\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>What’s wrong with this piece of code? We have to know that the context attached to an HTTP request can cancel in different conditions:</p>\n<ul>\n<li>When the client’s connection closes</li>\n<li>In the case of an HTTP/2 request, when the request is canceled</li>\n<li>When the response has been written back to the client</li>\n</ul>\n<p>In the first two cases, we probably handle things correctly. For example, if we get a response from doSomeTask but the client has closed the connection, it’s probably OK to call publish with a context already canceled so the message isn’t published. But what about the last case?</p>\n<p>When the response has been written to the client, the context associated with the request will be canceled. Therefore, we are facing a race condition:</p>\n<ul>\n<li>If the response is written after the Kafka publication, we both return a response and publish a message successfully</li>\n<li>However, if the response is written before or during the Kafka publication, the message shouldn’t be published.</li>\n</ul>\n<p>In the latter case, calling publish will return an error because we returned the HTTP response quickly.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>From Go 1.21, there is a way to create a new context without cancel. <a href=\"https://pkg.go.dev/context#WithoutCancel\"><code>context.WithoutCancel</code></a> returns a copy of parent that is not canceled when parent is canceled.</p>\n</details>\n<p>In summary, propagating a context should be done cautiously.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/61-inappropriate-context/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"starting-a-goroutine-without-knowing-when-to-stop-it-62\">Starting a goroutine without knowing when to stop it (#62)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Avoiding leaks means being mindful that whenever a goroutine is started, you should have a plan to stop it eventually.</p>\n</details>\n<p>Goroutines are easy and cheap to start—so easy and cheap that we may not necessarily have a plan for when to stop a new goroutine, which can lead to leaks. Not knowing when to stop a goroutine is a design issue and a common concurrency mistake in Go.</p>\n<p>Let’s discuss a concrete example. We will design an application that needs to watch some external configuration (for example, using a database connection). Here’s a first implementation:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-37-1\"><a id=\"__codelineno-37-1\" name=\"__codelineno-37-1\" href=\"#__codelineno-37-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-37-2\"><a id=\"__codelineno-37-2\" name=\"__codelineno-37-2\" href=\"#__codelineno-37-2\"></a><span class=\"w\">    </span><span class=\"nx\">newWatcher</span><span class=\"p\">()</span>\n</span><span id=\"__span-37-3\"><a id=\"__codelineno-37-3\" name=\"__codelineno-37-3\" href=\"#__codelineno-37-3\"></a><span class=\"w\">    </span><span class=\"c1\">// Run the application</span>\n</span><span id=\"__span-37-4\"><a id=\"__codelineno-37-4\" name=\"__codelineno-37-4\" href=\"#__codelineno-37-4\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-37-5\"><a id=\"__codelineno-37-5\" name=\"__codelineno-37-5\" href=\"#__codelineno-37-5\"></a>\n</span><span id=\"__span-37-6\"><a id=\"__codelineno-37-6\" name=\"__codelineno-37-6\" href=\"#__codelineno-37-6\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"cm\">/* Some resources */</span><span class=\"w\"> </span><span class=\"p\">}</span>\n</span><span id=\"__span-37-7\"><a id=\"__codelineno-37-7\" name=\"__codelineno-37-7\" href=\"#__codelineno-37-7\"></a>\n</span><span id=\"__span-37-8\"><a id=\"__codelineno-37-8\" name=\"__codelineno-37-8\" href=\"#__codelineno-37-8\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">newWatcher</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-37-9\"><a id=\"__codelineno-37-9\" name=\"__codelineno-37-9\" href=\"#__codelineno-37-9\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"p\">{}</span>\n</span><span id=\"__span-37-10\"><a id=\"__codelineno-37-10\" name=\"__codelineno-37-10\" href=\"#__codelineno-37-10\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">watch</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// Creates a goroutine that watches some external configuration</span>\n</span><span id=\"__span-37-11\"><a id=\"__codelineno-37-11\" name=\"__codelineno-37-11\" href=\"#__codelineno-37-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>The problem with this code is that when the main goroutine exits (perhaps because of an OS signal or because it has a finite workload), the application is stopped. Hence, the resources created by watcher aren’t closed gracefully. How can we prevent this from happening?</p>\n<p>One option could be to pass to newWatcher a context that will be canceled when main returns:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-38-1\"><a id=\"__codelineno-38-1\" name=\"__codelineno-38-1\" href=\"#__codelineno-38-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-38-2\"><a id=\"__codelineno-38-2\" name=\"__codelineno-38-2\" href=\"#__codelineno-38-2\"></a><span class=\"w\">    </span><span class=\"nx\">ctx</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">cancel</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">context</span><span class=\"p\">.</span><span class=\"nx\">WithCancel</span><span class=\"p\">(</span><span class=\"nx\">context</span><span class=\"p\">.</span><span class=\"nx\">Background</span><span class=\"p\">())</span>\n</span><span id=\"__span-38-3\"><a id=\"__codelineno-38-3\" name=\"__codelineno-38-3\" href=\"#__codelineno-38-3\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">cancel</span><span class=\"p\">()</span>\n</span><span id=\"__span-38-4\"><a id=\"__codelineno-38-4\" name=\"__codelineno-38-4\" href=\"#__codelineno-38-4\"></a><span class=\"w\">    </span><span class=\"nx\">newWatcher</span><span class=\"p\">(</span><span class=\"nx\">ctx</span><span class=\"p\">)</span>\n</span><span id=\"__span-38-5\"><a id=\"__codelineno-38-5\" name=\"__codelineno-38-5\" href=\"#__codelineno-38-5\"></a><span class=\"w\">    </span><span class=\"c1\">// Run the application</span>\n</span><span id=\"__span-38-6\"><a id=\"__codelineno-38-6\" name=\"__codelineno-38-6\" href=\"#__codelineno-38-6\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-38-7\"><a id=\"__codelineno-38-7\" name=\"__codelineno-38-7\" href=\"#__codelineno-38-7\"></a>\n</span><span id=\"__span-38-8\"><a id=\"__codelineno-38-8\" name=\"__codelineno-38-8\" href=\"#__codelineno-38-8\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">newWatcher</span><span class=\"p\">(</span><span class=\"nx\">ctx</span><span class=\"w\"> </span><span class=\"nx\">context</span><span class=\"p\">.</span><span class=\"nx\">Context</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-38-9\"><a id=\"__codelineno-38-9\" name=\"__codelineno-38-9\" href=\"#__codelineno-38-9\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"p\">{}</span>\n</span><span id=\"__span-38-10\"><a id=\"__codelineno-38-10\" name=\"__codelineno-38-10\" href=\"#__codelineno-38-10\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">watch</span><span class=\"p\">(</span><span class=\"nx\">ctx</span><span class=\"p\">)</span>\n</span><span id=\"__span-38-11\"><a id=\"__codelineno-38-11\" name=\"__codelineno-38-11\" href=\"#__codelineno-38-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>We propagate the context created to the watch method. When the context is canceled, the watcher struct should close its resources. However, can we guarantee that watch will have time to do so? Absolutely not—and that’s a design flaw.</p>\n<p>The problem is that we used signaling to convey that a goroutine had to be stopped. We didn’t block the parent goroutine until the resources had been closed.  Let’s make sure we do:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-39-1\"><a id=\"__codelineno-39-1\" name=\"__codelineno-39-1\" href=\"#__codelineno-39-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-39-2\"><a id=\"__codelineno-39-2\" name=\"__codelineno-39-2\" href=\"#__codelineno-39-2\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">newWatcher</span><span class=\"p\">()</span>\n</span><span id=\"__span-39-3\"><a id=\"__codelineno-39-3\" name=\"__codelineno-39-3\" href=\"#__codelineno-39-3\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nb\">close</span><span class=\"p\">()</span>\n</span><span id=\"__span-39-4\"><a id=\"__codelineno-39-4\" name=\"__codelineno-39-4\" href=\"#__codelineno-39-4\"></a><span class=\"w\">    </span><span class=\"c1\">// Run the application</span>\n</span><span id=\"__span-39-5\"><a id=\"__codelineno-39-5\" name=\"__codelineno-39-5\" href=\"#__codelineno-39-5\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-39-6\"><a id=\"__codelineno-39-6\" name=\"__codelineno-39-6\" href=\"#__codelineno-39-6\"></a>\n</span><span id=\"__span-39-7\"><a id=\"__codelineno-39-7\" name=\"__codelineno-39-7\" href=\"#__codelineno-39-7\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">newWatcher</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-39-8\"><a id=\"__codelineno-39-8\" name=\"__codelineno-39-8\" href=\"#__codelineno-39-8\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"p\">{}</span>\n</span><span id=\"__span-39-9\"><a id=\"__codelineno-39-9\" name=\"__codelineno-39-9\" href=\"#__codelineno-39-9\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">watch</span><span class=\"p\">()</span>\n</span><span id=\"__span-39-10\"><a id=\"__codelineno-39-10\" name=\"__codelineno-39-10\" href=\"#__codelineno-39-10\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">w</span>\n</span><span id=\"__span-39-11\"><a id=\"__codelineno-39-11\" name=\"__codelineno-39-11\" href=\"#__codelineno-39-11\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-39-12\"><a id=\"__codelineno-39-12\" name=\"__codelineno-39-12\" href=\"#__codelineno-39-12\"></a>\n</span><span id=\"__span-39-13\"><a id=\"__codelineno-39-13\" name=\"__codelineno-39-13\" href=\"#__codelineno-39-13\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nb\">close</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-39-14\"><a id=\"__codelineno-39-14\" name=\"__codelineno-39-14\" href=\"#__codelineno-39-14\"></a><span class=\"w\">    </span><span class=\"c1\">// Close the resources</span>\n</span><span id=\"__span-39-15\"><a id=\"__codelineno-39-15\" name=\"__codelineno-39-15\" href=\"#__codelineno-39-15\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Instead of signaling <code>watcher</code> that it’s time to close its resources, we now call this <code>close</code> method, using <code>defer</code> to guarantee that the resources are closed before the application exits.</p>\n<p>In summary, let’s be mindful that a goroutine is a resource like any other that must eventually be closed to free memory or other resources. Starting a goroutine without knowing when to stop it is a design issue. Whenever a goroutine is started, we should have a clear plan about when it will stop. Last but not least, if a goroutine creates resources and its lifetime is bound to the lifetime of the application, it’s probably safer to wait for this goroutine to complete before exiting the application. This way, we can ensure that the resources can be freed.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/62-starting-goroutine/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-being-careful-with-goroutines-and-loop-variables-63\"><img alt=\"⚠\" class=\"twemoji\" src=\"https://cdn.jsdelivr.net/gh/jdecked/twemoji@15.1.0/assets/svg/26a0.svg\" title=\":warning:\"> Not being careful with goroutines and loop variables (#63)</h3>\n<details class=\"warning\" open=\"open\">\n<summary>Warning</summary>\n<p>This mistake isn't relevant anymore from Go 1.22 (<a href=\"https://go.dev/blog/loopvar-preview\">details</a>).</p>\n</details>\n<h3 id=\"expecting-a-deterministic-behavior-using-select-and-channels-64\">Expecting a deterministic behavior using select and channels (#64)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Understanding that <code>select</code> with multiple channels chooses the case randomly if multiple options are possible prevents making wrong assumptions that can lead to subtle concurrency bugs.</p>\n</details>\n<p>One common mistake made by Go developers while working with channels is to make wrong assumptions about how select behaves with multiple channels.</p>\n<p>For example, let's consider the following case (<code>disconnectCh</code> is a unbuffered channel):</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-40-1\"><a id=\"__codelineno-40-1\" name=\"__codelineno-40-1\" href=\"#__codelineno-40-1\"></a><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-40-2\"><a id=\"__codelineno-40-2\" name=\"__codelineno-40-2\" href=\"#__codelineno-40-2\"></a><span class=\"w\">  </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">10</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-40-3\"><a id=\"__codelineno-40-3\" name=\"__codelineno-40-3\" href=\"#__codelineno-40-3\"></a><span class=\"w\">      </span><span class=\"nx\">messageCh</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"w\"> </span><span class=\"nx\">i</span>\n</span><span id=\"__span-40-4\"><a id=\"__codelineno-40-4\" name=\"__codelineno-40-4\" href=\"#__codelineno-40-4\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-40-5\"><a id=\"__codelineno-40-5\" name=\"__codelineno-40-5\" href=\"#__codelineno-40-5\"></a><span class=\"w\">    </span><span class=\"nx\">disconnectCh</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"p\">{}{}</span>\n</span><span id=\"__span-40-6\"><a id=\"__codelineno-40-6\" name=\"__codelineno-40-6\" href=\"#__codelineno-40-6\"></a><span class=\"p\">}()</span>\n</span><span id=\"__span-40-7\"><a id=\"__codelineno-40-7\" name=\"__codelineno-40-7\" href=\"#__codelineno-40-7\"></a>\n</span><span id=\"__span-40-8\"><a id=\"__codelineno-40-8\" name=\"__codelineno-40-8\" href=\"#__codelineno-40-8\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-40-9\"><a id=\"__codelineno-40-9\" name=\"__codelineno-40-9\" href=\"#__codelineno-40-9\"></a><span class=\"w\">    </span><span class=\"k\">select</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-40-10\"><a id=\"__codelineno-40-10\" name=\"__codelineno-40-10\" href=\"#__codelineno-40-10\"></a><span class=\"w\">    </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">messageCh</span><span class=\"p\">:</span>\n</span><span id=\"__span-40-11\"><a id=\"__codelineno-40-11\" name=\"__codelineno-40-11\" href=\"#__codelineno-40-11\"></a><span class=\"w\">        </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">v</span><span class=\"p\">)</span>\n</span><span id=\"__span-40-12\"><a id=\"__codelineno-40-12\" name=\"__codelineno-40-12\" href=\"#__codelineno-40-12\"></a><span class=\"w\">    </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">disconnectCh</span><span class=\"p\">:</span>\n</span><span id=\"__span-40-13\"><a id=\"__codelineno-40-13\" name=\"__codelineno-40-13\" href=\"#__codelineno-40-13\"></a><span class=\"w\">        </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"s\">\"disconnection, return\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-40-14\"><a id=\"__codelineno-40-14\" name=\"__codelineno-40-14\" href=\"#__codelineno-40-14\"></a><span class=\"w\">        </span><span class=\"k\">return</span>\n</span><span id=\"__span-40-15\"><a id=\"__codelineno-40-15\" name=\"__codelineno-40-15\" href=\"#__codelineno-40-15\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-40-16\"><a id=\"__codelineno-40-16\" name=\"__codelineno-40-16\" href=\"#__codelineno-40-16\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>If we run this example multiple times, the result will be random:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-41-1\"><a id=\"__codelineno-41-1\" name=\"__codelineno-41-1\" href=\"#__codelineno-41-1\"></a>0\n</span><span id=\"__span-41-2\"><a id=\"__codelineno-41-2\" name=\"__codelineno-41-2\" href=\"#__codelineno-41-2\"></a>1\n</span><span id=\"__span-41-3\"><a id=\"__codelineno-41-3\" name=\"__codelineno-41-3\" href=\"#__codelineno-41-3\"></a>2\n</span><span id=\"__span-41-4\"><a id=\"__codelineno-41-4\" name=\"__codelineno-41-4\" href=\"#__codelineno-41-4\"></a>disconnection, return\n</span><span id=\"__span-41-5\"><a id=\"__codelineno-41-5\" name=\"__codelineno-41-5\" href=\"#__codelineno-41-5\"></a>\n</span><span id=\"__span-41-6\"><a id=\"__codelineno-41-6\" name=\"__codelineno-41-6\" href=\"#__codelineno-41-6\"></a>0\n</span><span id=\"__span-41-7\"><a id=\"__codelineno-41-7\" name=\"__codelineno-41-7\" href=\"#__codelineno-41-7\"></a>disconnection, return\n</span></code></pre></div>\n<p>Instead of consuming the 10 messages, we only received a few of them. What’s the reason? It lies in the specification of the select statement with multiple channels (https:// go.dev/ref/spec):</p>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">Quote</p>\n<p>If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection.</p>\n</div>\n<p>Unlike a switch statement, where the first case with a match wins, the select statement selects randomly if multiple options are possible.</p>\n<p>This behavior might look odd at first, but there’s a good reason for it: to prevent possible starvation. Suppose the first possible communication chosen is based on the source order. In that case, we may fall into a situation where, for example, we only receive from one channel because of a fast sender. To prevent this, the language designers decided to use a random selection.</p>\n<p>When using <code>select</code> with multiple channels, we must remember that if multiple options are possible, the first case in the source order does not automatically win. Instead, Go selects randomly, so there’s no guarantee about which option will be chosen. To overcome this behavior, in the case of a single producer goroutine, we can use either unbuffered channels or a single channel.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/64-select-behavior/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-using-notification-channels-65\">Not using notification channels (#65)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Send notifications using a <code>chan struct{}</code> type.</p>\n</details>\n<p>Channels are a mechanism for communicating across goroutines via signaling. A signal can be either with or without data.</p>\n<p>Let’s look at a concrete example. We will create a channel that will notify us whenever a certain disconnection occurs. One idea is to handle it as a <code>chan bool</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-42-1\"><a id=\"__codelineno-42-1\" name=\"__codelineno-42-1\" href=\"#__codelineno-42-1\"></a><span class=\"nx\">disconnectCh</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">bool</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>Now, let’s say we interact with an API that provides us with such a channel. Because it’s a channel of Booleans, we can receive either <code>true</code> or <code>false</code> messages. It’s probably clear what <code>true</code> conveys. But what does <code>false</code> mean? Does it mean we haven’t been disconnected? And in this case, how frequently will we receive such a signal? Does it mean we have reconnected? Should we even expect to receive <code>false</code>? Perhaps we should only expect to receive <code>true</code> messages.</p>\n<p>If that’s the case, meaning we don’t need a specific value to convey some information, we need a channel <em>without</em> data. The idiomatic way to handle it is a channel of empty structs: <code>chan struct{}</code>.</p>\n<h3 id=\"not-using-nil-channels-66\">Not using nil channels (#66)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Using nil channels should be part of your concurrency toolset because it allows you to <em>remove</em> cases from <code>select</code> statements, for example.</p>\n</details>\n<p>What should this code do?</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-43-1\"><a id=\"__codelineno-43-1\" name=\"__codelineno-43-1\" href=\"#__codelineno-43-1\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span>\n</span><span id=\"__span-43-2\"><a id=\"__codelineno-43-2\" name=\"__codelineno-43-2\" href=\"#__codelineno-43-2\"></a><span class=\"o\">&lt;-</span><span class=\"nx\">ch</span>\n</span></code></pre></div>\n<p><code>ch</code> is a <code>chan int</code> type. The zero value of a channel being nil, <code>ch</code> is <code>nil</code>. The goroutine won’t panic; however, it will block forever.</p>\n<p>The principle is the same if we send a message to a nil channel. This goroutine blocks forever:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-44-1\"><a id=\"__codelineno-44-1\" name=\"__codelineno-44-1\" href=\"#__codelineno-44-1\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span>\n</span><span id=\"__span-44-2\"><a id=\"__codelineno-44-2\" name=\"__codelineno-44-2\" href=\"#__codelineno-44-2\"></a><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"w\"> </span><span class=\"mi\">0</span>\n</span></code></pre></div>\n<p>Then what’s the purpose of Go allowing messages to be received from or sent to a nil channel? For example, we can use nil channels to implement an idiomatic way to merge two channels:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-45-1\"><a id=\"__codelineno-45-1\" name=\"__codelineno-45-1\" href=\"#__codelineno-45-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">merge</span><span class=\"p\">(</span><span class=\"nx\">ch1</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">ch2</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-45-2\"><a id=\"__codelineno-45-2\" name=\"__codelineno-45-2\" href=\"#__codelineno-45-2\"></a><span class=\"w\">    </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-45-3\"><a id=\"__codelineno-45-3\" name=\"__codelineno-45-3\" href=\"#__codelineno-45-3\"></a>\n</span><span id=\"__span-45-4\"><a id=\"__codelineno-45-4\" name=\"__codelineno-45-4\" href=\"#__codelineno-45-4\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-45-5\"><a id=\"__codelineno-45-5\" name=\"__codelineno-45-5\" href=\"#__codelineno-45-5\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">ch1</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"o\">||</span><span class=\"w\"> </span><span class=\"nx\">ch2</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Continue if at least one channel isn’t nil</span>\n</span></span><span id=\"__span-45-6\"><a id=\"__codelineno-45-6\" name=\"__codelineno-45-6\" href=\"#__codelineno-45-6\"></a><span class=\"w\">            </span><span class=\"k\">select</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-45-7\"><a id=\"__codelineno-45-7\" name=\"__codelineno-45-7\" href=\"#__codelineno-45-7\"></a><span class=\"w\">            </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">open</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">ch1</span><span class=\"p\">:</span>\n</span><span id=\"__span-45-8\"><a id=\"__codelineno-45-8\" name=\"__codelineno-45-8\" href=\"#__codelineno-45-8\"></a><span class=\"w\">                </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"p\">!</span><span class=\"nx\">open</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-45-9\"><a id=\"__codelineno-45-9\" name=\"__codelineno-45-9\" href=\"#__codelineno-45-9\"></a><span class=\"hll\"><span class=\"w\">                    </span><span class=\"nx\">ch1</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"c1\">// Assign ch1 to a nil channel once closed</span>\n</span></span><span id=\"__span-45-10\"><a id=\"__codelineno-45-10\" name=\"__codelineno-45-10\" href=\"#__codelineno-45-10\"></a><span class=\"w\">                    </span><span class=\"k\">break</span>\n</span><span id=\"__span-45-11\"><a id=\"__codelineno-45-11\" name=\"__codelineno-45-11\" href=\"#__codelineno-45-11\"></a><span class=\"w\">                </span><span class=\"p\">}</span>\n</span><span id=\"__span-45-12\"><a id=\"__codelineno-45-12\" name=\"__codelineno-45-12\" href=\"#__codelineno-45-12\"></a><span class=\"w\">                </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"w\"> </span><span class=\"nx\">v</span>\n</span><span id=\"__span-45-13\"><a id=\"__codelineno-45-13\" name=\"__codelineno-45-13\" href=\"#__codelineno-45-13\"></a><span class=\"w\">            </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">open</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">ch2</span><span class=\"p\">:</span>\n</span><span id=\"__span-45-14\"><a id=\"__codelineno-45-14\" name=\"__codelineno-45-14\" href=\"#__codelineno-45-14\"></a><span class=\"w\">                </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"p\">!</span><span class=\"nx\">open</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-45-15\"><a id=\"__codelineno-45-15\" name=\"__codelineno-45-15\" href=\"#__codelineno-45-15\"></a><span class=\"hll\"><span class=\"w\">                    </span><span class=\"nx\">ch2</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"c1\">// Assigns ch2 to a nil channel once closed</span>\n</span></span><span id=\"__span-45-16\"><a id=\"__codelineno-45-16\" name=\"__codelineno-45-16\" href=\"#__codelineno-45-16\"></a><span class=\"w\">                    </span><span class=\"k\">break</span>\n</span><span id=\"__span-45-17\"><a id=\"__codelineno-45-17\" name=\"__codelineno-45-17\" href=\"#__codelineno-45-17\"></a><span class=\"w\">                </span><span class=\"p\">}</span>\n</span><span id=\"__span-45-18\"><a id=\"__codelineno-45-18\" name=\"__codelineno-45-18\" href=\"#__codelineno-45-18\"></a><span class=\"w\">                </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"w\"> </span><span class=\"nx\">v</span>\n</span><span id=\"__span-45-19\"><a id=\"__codelineno-45-19\" name=\"__codelineno-45-19\" href=\"#__codelineno-45-19\"></a><span class=\"w\">            </span><span class=\"p\">}</span>\n</span><span id=\"__span-45-20\"><a id=\"__codelineno-45-20\" name=\"__codelineno-45-20\" href=\"#__codelineno-45-20\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-45-21\"><a id=\"__codelineno-45-21\" name=\"__codelineno-45-21\" href=\"#__codelineno-45-21\"></a><span class=\"w\">        </span><span class=\"nb\">close</span><span class=\"p\">(</span><span class=\"nx\">ch</span><span class=\"p\">)</span>\n</span><span id=\"__span-45-22\"><a id=\"__codelineno-45-22\" name=\"__codelineno-45-22\" href=\"#__codelineno-45-22\"></a><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span><span id=\"__span-45-23\"><a id=\"__codelineno-45-23\" name=\"__codelineno-45-23\" href=\"#__codelineno-45-23\"></a>\n</span><span id=\"__span-45-24\"><a id=\"__codelineno-45-24\" name=\"__codelineno-45-24\" href=\"#__codelineno-45-24\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">ch</span>\n</span><span id=\"__span-45-25\"><a id=\"__codelineno-45-25\" name=\"__codelineno-45-25\" href=\"#__codelineno-45-25\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>This elegant solution relies on nil channels to somehow <em>remove</em> one case from the <code>select</code> statement.</p>\n<p>Let’s keep this idea in mind: nil channels are useful in some conditions and should be part of the Go developer’s toolset when dealing with concurrent code.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/66-nil-channels/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"being-puzzled-about-channel-size-67\">Being puzzled about channel size (#67)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Carefully decide on the right channel type to use, given a problem. Only unbuffered channels provide strong synchronization guarantees. For buffered channels, you should have a good reason to specify a channel size other than one.</p>\n</details>\n<p>An unbuffered channel is a channel without any capacity. It can be created by either omitting the size or providing a 0 size:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-46-1\"><a id=\"__codelineno-46-1\" name=\"__codelineno-46-1\" href=\"#__codelineno-46-1\"></a><span class=\"nx\">ch1</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span>\n</span><span id=\"__span-46-2\"><a id=\"__codelineno-46-2\" name=\"__codelineno-46-2\" href=\"#__codelineno-46-2\"></a><span class=\"nx\">ch2</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>With an unbuffered channel (sometimes called a synchronous channel), the sender will block until the receiver receives data from the channel.</p>\n<p>Conversely, a buffered channel has a capacity, and it must be created with a size greater than or equal to 1:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-47-1\"><a id=\"__codelineno-47-1\" name=\"__codelineno-47-1\" href=\"#__codelineno-47-1\"></a><span class=\"nx\">ch3</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>With a buffered channel, a sender can send messages while the channel isn’t full. Once the channel is full, it will block until a receiver goroutine receives a message:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-48-1\"><a id=\"__codelineno-48-1\" name=\"__codelineno-48-1\" href=\"#__codelineno-48-1\"></a><span class=\"nx\">ch3</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-48-2\"><a id=\"__codelineno-48-2\" name=\"__codelineno-48-2\" href=\"#__codelineno-48-2\"></a><span class=\"nx\">ch3</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"mi\">1</span><span class=\"w\"> </span><span class=\"c1\">// Non-blocking</span>\n</span><span id=\"__span-48-3\"><a id=\"__codelineno-48-3\" name=\"__codelineno-48-3\" href=\"#__codelineno-48-3\"></a><span class=\"nx\">ch3</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"mi\">2</span><span class=\"w\"> </span><span class=\"c1\">// Blocking</span>\n</span></code></pre></div>\n<p>The first send isn’t blocking, whereas the second one is, as the channel is full at this stage.</p>\n<p>What's the main difference between unbuffered and buffered channels:</p>\n<ul>\n<li>An unbuffered channel enables synchronization. We have the guarantee that two goroutines will be in a known state: one receiving and another sending a message.</li>\n<li>A buffered channel doesn’t provide any strong synchronization. Indeed, a producer goroutine can send a message and then continue its execution if the channel isn’t full. The only guarantee is that a goroutine won’t receive a message before it is sent. But this is only a guarantee because of causality (you don’t drink your coffee before you prepare it).</li>\n</ul>\n<p>If we need a buffered channel, what size should we provide?</p>\n<p>The default value we should use for buffered channels is its minimum: 1. So, we may approach the problem from this standpoint: is there any good reason not to use a value of 1? Here’s a list of possible cases where we should use another size:</p>\n<ul>\n<li>While using a worker pooling-like pattern, meaning spinning a fixed number of goroutines that need to send data to a shared channel. In that case, we can tie the channel size to the number of goroutines created.</li>\n<li>When using channels for rate-limiting problems. For example, if we need to enforce resource utilization by bounding the number of requests, we should set up the channel size according to the limit.</li>\n</ul>\n<p>If we are outside of these cases, using a different channel size should be done cautiously. Let’s bear in mind that deciding about an accurate queue size isn’t an easy problem:</p>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">Martin Thompson</p>\n<p>Queues are typically always close to full or close to empty due to the differences in pace between consumers and producers. They very rarely operate in a balanced middle ground where the rate of production and consumption is evenly matched.</p>\n</div>\n<h3 id=\"forgetting-about-possible-side-effects-with-string-formatting-68\">Forgetting about possible side effects with string formatting (#68)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Being aware that string formatting may lead to calling existing functions means watching out for possible deadlocks and other data races.</p>\n</details>\n<p>It’s pretty easy to forget the potential side effects of string formatting while working in a concurrent application.</p>\n<h4 id=\"etcd-data-race\"><a href=\"https://github.com/etcd-io/etcd\">etcd</a> data race</h4>\n<p><a href=\"https://github.com/etcd-io/etcd/pull/7816\">github.com/etcd-io/etcd/pull/7816</a> shows an example of an issue where a map's key was formatted based on a mutable values from a context.</p>\n<h4 id=\"deadlock\">Deadlock</h4>\n<p>Can you see what the problem is in this code with a <code>Customer</code> struct exposing an <code>UpdateAge</code> method and implementing the <code>fmt.Stringer</code> interface?</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-49-1\"><a id=\"__codelineno-49-1\" name=\"__codelineno-49-1\" href=\"#__codelineno-49-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Customer</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-49-2\"><a id=\"__codelineno-49-2\" name=\"__codelineno-49-2\" href=\"#__codelineno-49-2\"></a><span class=\"w\">    </span><span class=\"nx\">mutex</span><span class=\"w\"> </span><span class=\"nx\">sync</span><span class=\"p\">.</span><span class=\"nx\">RWMutex</span><span class=\"w\"> </span><span class=\"c1\">// Uses a sync.RWMutex to protect concurrent accesses</span>\n</span><span id=\"__span-49-3\"><a id=\"__codelineno-49-3\" name=\"__codelineno-49-3\" href=\"#__codelineno-49-3\"></a><span class=\"w\">    </span><span class=\"nx\">id</span><span class=\"w\">    </span><span class=\"kt\">string</span>\n</span><span id=\"__span-49-4\"><a id=\"__codelineno-49-4\" name=\"__codelineno-49-4\" href=\"#__codelineno-49-4\"></a><span class=\"w\">    </span><span class=\"nx\">age</span><span class=\"w\">   </span><span class=\"kt\">int</span>\n</span><span id=\"__span-49-5\"><a id=\"__codelineno-49-5\" name=\"__codelineno-49-5\" href=\"#__codelineno-49-5\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-49-6\"><a id=\"__codelineno-49-6\" name=\"__codelineno-49-6\" href=\"#__codelineno-49-6\"></a>\n</span><span id=\"__span-49-7\"><a id=\"__codelineno-49-7\" name=\"__codelineno-49-7\" href=\"#__codelineno-49-7\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Customer</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">UpdateAge</span><span class=\"p\">(</span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-49-8\"><a id=\"__codelineno-49-8\" name=\"__codelineno-49-8\" href=\"#__codelineno-49-8\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">Lock</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// Locks and defers unlock as we update Customer</span>\n</span><span id=\"__span-49-9\"><a id=\"__codelineno-49-9\" name=\"__codelineno-49-9\" href=\"#__codelineno-49-9\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">Unlock</span><span class=\"p\">()</span>\n</span><span id=\"__span-49-10\"><a id=\"__codelineno-49-10\" name=\"__codelineno-49-10\" href=\"#__codelineno-49-10\"></a>\n</span><span id=\"__span-49-11\"><a id=\"__codelineno-49-11\" name=\"__codelineno-49-11\" href=\"#__codelineno-49-11\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Returns an error if age is negative</span>\n</span><span id=\"__span-49-12\"><a id=\"__codelineno-49-12\" name=\"__codelineno-49-12\" href=\"#__codelineno-49-12\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Errorf</span><span class=\"p\">(</span><span class=\"s\">\"age should be positive for customer %v\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">)</span>\n</span><span id=\"__span-49-13\"><a id=\"__codelineno-49-13\" name=\"__codelineno-49-13\" href=\"#__codelineno-49-13\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-49-14\"><a id=\"__codelineno-49-14\" name=\"__codelineno-49-14\" href=\"#__codelineno-49-14\"></a>\n</span><span id=\"__span-49-15\"><a id=\"__codelineno-49-15\" name=\"__codelineno-49-15\" href=\"#__codelineno-49-15\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">age</span>\n</span><span id=\"__span-49-16\"><a id=\"__codelineno-49-16\" name=\"__codelineno-49-16\" href=\"#__codelineno-49-16\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-49-17\"><a id=\"__codelineno-49-17\" name=\"__codelineno-49-17\" href=\"#__codelineno-49-17\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-49-18\"><a id=\"__codelineno-49-18\" name=\"__codelineno-49-18\" href=\"#__codelineno-49-18\"></a>\n</span><span id=\"__span-49-19\"><a id=\"__codelineno-49-19\" name=\"__codelineno-49-19\" href=\"#__codelineno-49-19\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Customer</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">String</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-49-20\"><a id=\"__codelineno-49-20\" name=\"__codelineno-49-20\" href=\"#__codelineno-49-20\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">RLock</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// Locks and defers unlock as we read Customer</span>\n</span><span id=\"__span-49-21\"><a id=\"__codelineno-49-21\" name=\"__codelineno-49-21\" href=\"#__codelineno-49-21\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">RUnlock</span><span class=\"p\">()</span>\n</span><span id=\"__span-49-22\"><a id=\"__codelineno-49-22\" name=\"__codelineno-49-22\" href=\"#__codelineno-49-22\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Sprintf</span><span class=\"p\">(</span><span class=\"s\">\"id %s, age %d\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">age</span><span class=\"p\">)</span>\n</span><span id=\"__span-49-23\"><a id=\"__codelineno-49-23\" name=\"__codelineno-49-23\" href=\"#__codelineno-49-23\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>The problem here may not be straightforward. If the provided age is negative, we return an error. Because the error is formatted, using the <code>%s</code> directive on the receiver, it will call the <code>String</code> method to format <code>Customer</code>. But because <code>UpdateAge</code> already acquires the mutex lock, the <code>String</code> method won’t be able to acquire it. Hence, this leads to a deadlock situation. If all goroutines are also asleep, it leads to a panic.</p>\n<p>One possible solution is to restrict the scope of the mutex lock:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-50-1\"><a id=\"__codelineno-50-1\" name=\"__codelineno-50-1\" href=\"#__codelineno-50-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Customer</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">UpdateAge</span><span class=\"p\">(</span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-50-2\"><a id=\"__codelineno-50-2\" name=\"__codelineno-50-2\" href=\"#__codelineno-50-2\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span></span><span id=\"__span-50-3\"><a id=\"__codelineno-50-3\" name=\"__codelineno-50-3\" href=\"#__codelineno-50-3\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Errorf</span><span class=\"p\">(</span><span class=\"s\">\"age should be positive for customer %v\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-50-4\"><a id=\"__codelineno-50-4\" name=\"__codelineno-50-4\" href=\"#__codelineno-50-4\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"p\">}</span>\n</span></span><span id=\"__span-50-5\"><a id=\"__codelineno-50-5\" name=\"__codelineno-50-5\" href=\"#__codelineno-50-5\"></a>\n</span><span id=\"__span-50-6\"><a id=\"__codelineno-50-6\" name=\"__codelineno-50-6\" href=\"#__codelineno-50-6\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">Lock</span><span class=\"p\">()</span>\n</span><span id=\"__span-50-7\"><a id=\"__codelineno-50-7\" name=\"__codelineno-50-7\" href=\"#__codelineno-50-7\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">Unlock</span><span class=\"p\">()</span>\n</span><span id=\"__span-50-8\"><a id=\"__codelineno-50-8\" name=\"__codelineno-50-8\" href=\"#__codelineno-50-8\"></a>\n</span><span id=\"__span-50-9\"><a id=\"__codelineno-50-9\" name=\"__codelineno-50-9\" href=\"#__codelineno-50-9\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">age</span>\n</span><span id=\"__span-50-10\"><a id=\"__codelineno-50-10\" name=\"__codelineno-50-10\" href=\"#__codelineno-50-10\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-50-11\"><a id=\"__codelineno-50-11\" name=\"__codelineno-50-11\" href=\"#__codelineno-50-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Yet, such an approach isn't always possible. In these conditions, we have to be extremely careful with string formatting.</p>\n<p>Another approach is to access the <code>id</code> field directly:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-51-1\"><a id=\"__codelineno-51-1\" name=\"__codelineno-51-1\" href=\"#__codelineno-51-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Customer</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">UpdateAge</span><span class=\"p\">(</span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-51-2\"><a id=\"__codelineno-51-2\" name=\"__codelineno-51-2\" href=\"#__codelineno-51-2\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">Lock</span><span class=\"p\">()</span>\n</span><span id=\"__span-51-3\"><a id=\"__codelineno-51-3\" name=\"__codelineno-51-3\" href=\"#__codelineno-51-3\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">Unlock</span><span class=\"p\">()</span>\n</span><span id=\"__span-51-4\"><a id=\"__codelineno-51-4\" name=\"__codelineno-51-4\" href=\"#__codelineno-51-4\"></a>\n</span><span id=\"__span-51-5\"><a id=\"__codelineno-51-5\" name=\"__codelineno-51-5\" href=\"#__codelineno-51-5\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-51-6\"><a id=\"__codelineno-51-6\" name=\"__codelineno-51-6\" href=\"#__codelineno-51-6\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Errorf</span><span class=\"p\">(</span><span class=\"s\">\"age should be positive for customer id %s\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-51-7\"><a id=\"__codelineno-51-7\" name=\"__codelineno-51-7\" href=\"#__codelineno-51-7\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-51-8\"><a id=\"__codelineno-51-8\" name=\"__codelineno-51-8\" href=\"#__codelineno-51-8\"></a>\n</span><span id=\"__span-51-9\"><a id=\"__codelineno-51-9\" name=\"__codelineno-51-9\" href=\"#__codelineno-51-9\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">age</span>\n</span><span id=\"__span-51-10\"><a id=\"__codelineno-51-10\" name=\"__codelineno-51-10\" href=\"#__codelineno-51-10\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-51-11\"><a id=\"__codelineno-51-11\" name=\"__codelineno-51-11\" href=\"#__codelineno-51-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>In concurrent applications, we should remain cautious about the possible side effects of string formatting.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/68-string-formatting/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"creating-data-races-with-append-69\">Creating data races with append (#69)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Calling <code>append</code> isn’t always data-race-free; hence, it shouldn’t be used concurrently on a shared slice.</p>\n</details>\n<p>Should adding an element to a slice using <code>append</code> is data-race-free? Spoiler: it depends.</p>\n<p>Do you believe this example has a data race? </p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-52-1\"><a id=\"__codelineno-52-1\" name=\"__codelineno-52-1\" href=\"#__codelineno-52-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">([]</span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-52-2\"><a id=\"__codelineno-52-2\" name=\"__codelineno-52-2\" href=\"#__codelineno-52-2\"></a>\n</span><span id=\"__span-52-3\"><a id=\"__codelineno-52-3\" name=\"__codelineno-52-3\" href=\"#__codelineno-52-3\"></a><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// In a new goroutine, appends a new element on s</span>\n</span><span id=\"__span-52-4\"><a id=\"__codelineno-52-4\" name=\"__codelineno-52-4\" href=\"#__codelineno-52-4\"></a><span class=\"w\">    </span><span class=\"nx\">s1</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-52-5\"><a id=\"__codelineno-52-5\" name=\"__codelineno-52-5\" href=\"#__codelineno-52-5\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">s1</span><span class=\"p\">)</span>\n</span><span id=\"__span-52-6\"><a id=\"__codelineno-52-6\" name=\"__codelineno-52-6\" href=\"#__codelineno-52-6\"></a><span class=\"p\">}()</span>\n</span><span id=\"__span-52-7\"><a id=\"__codelineno-52-7\" name=\"__codelineno-52-7\" href=\"#__codelineno-52-7\"></a>\n</span><span id=\"__span-52-8\"><a id=\"__codelineno-52-8\" name=\"__codelineno-52-8\" href=\"#__codelineno-52-8\"></a><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Same</span>\n</span><span id=\"__span-52-9\"><a id=\"__codelineno-52-9\" name=\"__codelineno-52-9\" href=\"#__codelineno-52-9\"></a><span class=\"w\">    </span><span class=\"nx\">s2</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-52-10\"><a id=\"__codelineno-52-10\" name=\"__codelineno-52-10\" href=\"#__codelineno-52-10\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">s2</span><span class=\"p\">)</span>\n</span><span id=\"__span-52-11\"><a id=\"__codelineno-52-11\" name=\"__codelineno-52-11\" href=\"#__codelineno-52-11\"></a><span class=\"p\">}()</span>\n</span></code></pre></div>\n<p>The answer is no.</p>\n<p>In this example, we create a slice with <code>make([]int, 1)</code>. The code creates a one-length, one-capacity slice. Thus, because the slice is full, using append in each goroutine returns a slice backed by a new array. It doesn’t mutate the existing array; hence, it doesn’t lead to a data race.</p>\n<p>Now, let’s run the same example with a slight change in how we initialize <code>s</code>. Instead of creating a slice with a length of 1, we create it with a length of 0 but a capacity of 1. How about this new example? Does it contain a data race?</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-53-1\"><a id=\"__codelineno-53-1\" name=\"__codelineno-53-1\" href=\"#__codelineno-53-1\"></a><span class=\"hll\"><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">([]</span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-53-2\"><a id=\"__codelineno-53-2\" name=\"__codelineno-53-2\" href=\"#__codelineno-53-2\"></a>\n</span><span id=\"__span-53-3\"><a id=\"__codelineno-53-3\" name=\"__codelineno-53-3\" href=\"#__codelineno-53-3\"></a><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span>\n</span><span id=\"__span-53-4\"><a id=\"__codelineno-53-4\" name=\"__codelineno-53-4\" href=\"#__codelineno-53-4\"></a><span class=\"w\">    </span><span class=\"nx\">s1</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-53-5\"><a id=\"__codelineno-53-5\" name=\"__codelineno-53-5\" href=\"#__codelineno-53-5\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">s1</span><span class=\"p\">)</span>\n</span><span id=\"__span-53-6\"><a id=\"__codelineno-53-6\" name=\"__codelineno-53-6\" href=\"#__codelineno-53-6\"></a><span class=\"p\">}()</span>\n</span><span id=\"__span-53-7\"><a id=\"__codelineno-53-7\" name=\"__codelineno-53-7\" href=\"#__codelineno-53-7\"></a>\n</span><span id=\"__span-53-8\"><a id=\"__codelineno-53-8\" name=\"__codelineno-53-8\" href=\"#__codelineno-53-8\"></a><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-53-9\"><a id=\"__codelineno-53-9\" name=\"__codelineno-53-9\" href=\"#__codelineno-53-9\"></a><span class=\"w\">    </span><span class=\"nx\">s2</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-53-10\"><a id=\"__codelineno-53-10\" name=\"__codelineno-53-10\" href=\"#__codelineno-53-10\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">s2</span><span class=\"p\">)</span>\n</span><span id=\"__span-53-11\"><a id=\"__codelineno-53-11\" name=\"__codelineno-53-11\" href=\"#__codelineno-53-11\"></a><span class=\"p\">}()</span>\n</span></code></pre></div>\n<p>The answer is yes. We create a slice with <code>make([]int, 0, 1)</code>. Therefore, the array isn’t full. Both goroutines attempt to update the same index of the backing array (index 1), which is a data race.</p>\n<p>How can we prevent the data race if we want both goroutines to work on a slice containing the initial elements of <code>s</code> plus an extra element? One solution is to create a copy of <code>s</code>.</p>\n<p>We should remember that using append on a shared slice in concurrent applications can lead to a data race. Hence, it should be avoided.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/69-data-race-append/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"using-mutexes-inaccurately-with-slices-and-maps-70\">Using mutexes inaccurately with slices and maps (#70)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Remembering that slices and maps are pointers can prevent common data races.</p>\n</details>\n<p>Let's implement a <code>Cache</code> struct used to handle caching for customer balances. This struct will contain a map of balances per customer ID and a mutex to protect concurrent accesses:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-54-1\"><a id=\"__codelineno-54-1\" name=\"__codelineno-54-1\" href=\"#__codelineno-54-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Cache</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-54-2\"><a id=\"__codelineno-54-2\" name=\"__codelineno-54-2\" href=\"#__codelineno-54-2\"></a><span class=\"w\">    </span><span class=\"nx\">mu</span><span class=\"w\">       </span><span class=\"nx\">sync</span><span class=\"p\">.</span><span class=\"nx\">RWMutex</span>\n</span><span id=\"__span-54-3\"><a id=\"__codelineno-54-3\" name=\"__codelineno-54-3\" href=\"#__codelineno-54-3\"></a><span class=\"w\">    </span><span class=\"nx\">balances</span><span class=\"w\"> </span><span class=\"kd\">map</span><span class=\"p\">[</span><span class=\"kt\">string</span><span class=\"p\">]</span><span class=\"kt\">float64</span>\n</span><span id=\"__span-54-4\"><a id=\"__codelineno-54-4\" name=\"__codelineno-54-4\" href=\"#__codelineno-54-4\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Next, we add an <code>AddBalance</code> method that mutates the <code>balances</code> map. The mutation is done in a critical section (within a mutex lock and a mutex unlock):</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-55-1\"><a id=\"__codelineno-55-1\" name=\"__codelineno-55-1\" href=\"#__codelineno-55-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Cache</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">AddBalance</span><span class=\"p\">(</span><span class=\"nx\">id</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">balance</span><span class=\"w\"> </span><span class=\"kt\">float64</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-55-2\"><a id=\"__codelineno-55-2\" name=\"__codelineno-55-2\" href=\"#__codelineno-55-2\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">Lock</span><span class=\"p\">()</span>\n</span><span id=\"__span-55-3\"><a id=\"__codelineno-55-3\" name=\"__codelineno-55-3\" href=\"#__codelineno-55-3\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">balances</span><span class=\"p\">[</span><span class=\"nx\">id</span><span class=\"p\">]</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">balance</span>\n</span><span id=\"__span-55-4\"><a id=\"__codelineno-55-4\" name=\"__codelineno-55-4\" href=\"#__codelineno-55-4\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">Unlock</span><span class=\"p\">()</span>\n</span><span id=\"__span-55-5\"><a id=\"__codelineno-55-5\" name=\"__codelineno-55-5\" href=\"#__codelineno-55-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Meanwhile, we have to implement a method to calculate the average balance for all the customers. One idea is to handle a minimal critical section this way:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-56-1\"><a id=\"__codelineno-56-1\" name=\"__codelineno-56-1\" href=\"#__codelineno-56-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Cache</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">AverageBalance</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">float64</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-56-2\"><a id=\"__codelineno-56-2\" name=\"__codelineno-56-2\" href=\"#__codelineno-56-2\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">RLock</span><span class=\"p\">()</span>\n</span><span id=\"__span-56-3\"><a id=\"__codelineno-56-3\" name=\"__codelineno-56-3\" href=\"#__codelineno-56-3\"></a><span class=\"w\">    </span><span class=\"nx\">balances</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">balances</span><span class=\"w\"> </span><span class=\"c1\">// Creates a copy of the balances map</span>\n</span><span id=\"__span-56-4\"><a id=\"__codelineno-56-4\" name=\"__codelineno-56-4\" href=\"#__codelineno-56-4\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">RUnlock</span><span class=\"p\">()</span>\n</span><span id=\"__span-56-5\"><a id=\"__codelineno-56-5\" name=\"__codelineno-56-5\" href=\"#__codelineno-56-5\"></a>\n</span><span id=\"__span-56-6\"><a id=\"__codelineno-56-6\" name=\"__codelineno-56-6\" href=\"#__codelineno-56-6\"></a><span class=\"w\">    </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mf\">0.</span>\n</span><span id=\"__span-56-7\"><a id=\"__codelineno-56-7\" name=\"__codelineno-56-7\" href=\"#__codelineno-56-7\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">balance</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">balances</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Iterates over the copy, outside of the critical section</span>\n</span><span id=\"__span-56-8\"><a id=\"__codelineno-56-8\" name=\"__codelineno-56-8\" href=\"#__codelineno-56-8\"></a><span class=\"w\">        </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"nx\">balance</span>\n</span><span id=\"__span-56-9\"><a id=\"__codelineno-56-9\" name=\"__codelineno-56-9\" href=\"#__codelineno-56-9\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-56-10\"><a id=\"__codelineno-56-10\" name=\"__codelineno-56-10\" href=\"#__codelineno-56-10\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">/</span><span class=\"w\"> </span><span class=\"nb\">float64</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">balances</span><span class=\"p\">))</span>\n</span><span id=\"__span-56-11\"><a id=\"__codelineno-56-11\" name=\"__codelineno-56-11\" href=\"#__codelineno-56-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>What's the problem with this code?</p>\n<p>If we run a test using the <code>-race</code> flag with two concurrent goroutines, one calling <code>AddBalance</code> (hence mutating balances) and another calling <code>AverageBalance</code>, a data race occurs. What’s the problem here?</p>\n<p>Internally, a map is a <code>runtime.hmap</code> struct containing mostly metadata (for example, a counter) and a pointer referencing data buckets. So, <code>balances := c.balances</code> doesn’t copy the actual data. Therefore, the two goroutines perform operations on the same data set, and one mutates it. Hence, it's a data race.</p>\n<p>One possible solution is to protect the whole <code>AverageBalance</code> function:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-57-1\"><a id=\"__codelineno-57-1\" name=\"__codelineno-57-1\" href=\"#__codelineno-57-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Cache</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">AverageBalance</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">float64</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-57-2\"><a id=\"__codelineno-57-2\" name=\"__codelineno-57-2\" href=\"#__codelineno-57-2\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">RLock</span><span class=\"p\">()</span>\n</span></span><span id=\"__span-57-3\"><a id=\"__codelineno-57-3\" name=\"__codelineno-57-3\" href=\"#__codelineno-57-3\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">RUnlock</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// Unlocks when the function returns</span>\n</span></span><span id=\"__span-57-4\"><a id=\"__codelineno-57-4\" name=\"__codelineno-57-4\" href=\"#__codelineno-57-4\"></a>\n</span><span id=\"__span-57-5\"><a id=\"__codelineno-57-5\" name=\"__codelineno-57-5\" href=\"#__codelineno-57-5\"></a><span class=\"w\">    </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mf\">0.</span>\n</span><span id=\"__span-57-6\"><a id=\"__codelineno-57-6\" name=\"__codelineno-57-6\" href=\"#__codelineno-57-6\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">balance</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">balances</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-57-7\"><a id=\"__codelineno-57-7\" name=\"__codelineno-57-7\" href=\"#__codelineno-57-7\"></a><span class=\"w\">        </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"nx\">balance</span>\n</span><span id=\"__span-57-8\"><a id=\"__codelineno-57-8\" name=\"__codelineno-57-8\" href=\"#__codelineno-57-8\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-57-9\"><a id=\"__codelineno-57-9\" name=\"__codelineno-57-9\" href=\"#__codelineno-57-9\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">/</span><span class=\"w\"> </span><span class=\"nb\">float64</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">balances</span><span class=\"p\">))</span>\n</span><span id=\"__span-57-10\"><a id=\"__codelineno-57-10\" name=\"__codelineno-57-10\" href=\"#__codelineno-57-10\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Another option, if the iteration operation isn’t lightweight, is to work on an actual copy of the data and protect only the copy:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-58-1\"><a id=\"__codelineno-58-1\" name=\"__codelineno-58-1\" href=\"#__codelineno-58-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Cache</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">AverageBalance</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">float64</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-58-2\"><a id=\"__codelineno-58-2\" name=\"__codelineno-58-2\" href=\"#__codelineno-58-2\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">RLock</span><span class=\"p\">()</span>\n</span></span><span id=\"__span-58-3\"><a id=\"__codelineno-58-3\" name=\"__codelineno-58-3\" href=\"#__codelineno-58-3\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"nx\">m</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">maps</span><span class=\"p\">.</span><span class=\"nx\">Clone</span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">balances</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-58-4\"><a id=\"__codelineno-58-4\" name=\"__codelineno-58-4\" href=\"#__codelineno-58-4\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">RUnlock</span><span class=\"p\">()</span>\n</span></span><span id=\"__span-58-5\"><a id=\"__codelineno-58-5\" name=\"__codelineno-58-5\" href=\"#__codelineno-58-5\"></a><span class=\"hll\">\n</span></span><span id=\"__span-58-6\"><a id=\"__codelineno-58-6\" name=\"__codelineno-58-6\" href=\"#__codelineno-58-6\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mf\">0.</span>\n</span></span><span id=\"__span-58-7\"><a id=\"__codelineno-58-7\" name=\"__codelineno-58-7\" href=\"#__codelineno-58-7\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">balance</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">m</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span></span><span id=\"__span-58-8\"><a id=\"__codelineno-58-8\" name=\"__codelineno-58-8\" href=\"#__codelineno-58-8\"></a><span class=\"w\">        </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"nx\">balance</span>\n</span><span id=\"__span-58-9\"><a id=\"__codelineno-58-9\" name=\"__codelineno-58-9\" href=\"#__codelineno-58-9\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-58-10\"><a id=\"__codelineno-58-10\" name=\"__codelineno-58-10\" href=\"#__codelineno-58-10\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">/</span><span class=\"w\"> </span><span class=\"nb\">float64</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">m</span><span class=\"p\">))</span>\n</span><span id=\"__span-58-11\"><a id=\"__codelineno-58-11\" name=\"__codelineno-58-11\" href=\"#__codelineno-58-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Once we have made a deep copy, we release the mutex. The iterations are done on the copy outside of the critical section.</p>\n<p>In summary, we have to be careful with the boundaries of a mutex lock. In this section, we have seen why assigning an existing map (or an existing slice) to a map isn’t enough to protect against data races. The new variable, whether a map or a slice, is backed by the same data set. There are two leading solutions to prevent this: protect the whole function, or work on a copy of the actual data. In all cases, let’s be cautious when designing critical sections and make sure the boundaries are accurately defined.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/70-mutex-slices-maps/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"misusing-syncwaitgroup-71\">Misusing <code>sync.WaitGroup</code> (#71)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>To accurately use <code>sync.WaitGroup</code>, call the <code>Add</code> method before spinning up goroutines.</p>\n</details>\n<p>In the following example, we will initialize a wait group, start three goroutines that will update a counter atomically, and then wait for them to complete. We want to wait for these three goroutines to print the value of the counter (which should be 3):</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-59-1\"><a id=\"__codelineno-59-1\" name=\"__codelineno-59-1\" href=\"#__codelineno-59-1\"></a><span class=\"nx\">wg</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">sync</span><span class=\"p\">.</span><span class=\"nx\">WaitGroup</span><span class=\"p\">{}</span>\n</span><span id=\"__span-59-2\"><a id=\"__codelineno-59-2\" name=\"__codelineno-59-2\" href=\"#__codelineno-59-2\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"kt\">uint64</span>\n</span><span id=\"__span-59-3\"><a id=\"__codelineno-59-3\" name=\"__codelineno-59-3\" href=\"#__codelineno-59-3\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">3</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-59-4\"><a id=\"__codelineno-59-4\" name=\"__codelineno-59-4\" href=\"#__codelineno-59-4\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-59-5\"><a id=\"__codelineno-59-5\" name=\"__codelineno-59-5\" href=\"#__codelineno-59-5\"></a><span class=\"w\">        </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Add</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-59-6\"><a id=\"__codelineno-59-6\" name=\"__codelineno-59-6\" href=\"#__codelineno-59-6\"></a><span class=\"w\">        </span><span class=\"nx\">atomic</span><span class=\"p\">.</span><span class=\"nx\">AddUint64</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">v</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-59-7\"><a id=\"__codelineno-59-7\" name=\"__codelineno-59-7\" href=\"#__codelineno-59-7\"></a><span class=\"w\">        </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Done</span><span class=\"p\">()</span>\n</span><span id=\"__span-59-8\"><a id=\"__codelineno-59-8\" name=\"__codelineno-59-8\" href=\"#__codelineno-59-8\"></a><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span><span id=\"__span-59-9\"><a id=\"__codelineno-59-9\" name=\"__codelineno-59-9\" href=\"#__codelineno-59-9\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-59-10\"><a id=\"__codelineno-59-10\" name=\"__codelineno-59-10\" href=\"#__codelineno-59-10\"></a><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Wait</span><span class=\"p\">()</span>\n</span><span id=\"__span-59-11\"><a id=\"__codelineno-59-11\" name=\"__codelineno-59-11\" href=\"#__codelineno-59-11\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">v</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>If we run this example, we get a non-deterministic value: the code can print any value from 0 to 3. Also, if we enable the <code>-race</code> flag, Go will even catch a data race.</p>\n<p>The problem is that <code>wg.Add(1)</code> is called within the newly created goroutine, not in the parent goroutine. Hence, there is no guarantee that we have indicated to the wait group that we want to wait for three goroutines before calling <code>wg.Wait()</code>.</p>\n<p>To fix this issue, we can call <code>wg.Add</code> before the loop:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-60-1\"><a id=\"__codelineno-60-1\" name=\"__codelineno-60-1\" href=\"#__codelineno-60-1\"></a><span class=\"nx\">wg</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">sync</span><span class=\"p\">.</span><span class=\"nx\">WaitGroup</span><span class=\"p\">{}</span>\n</span><span id=\"__span-60-2\"><a id=\"__codelineno-60-2\" name=\"__codelineno-60-2\" href=\"#__codelineno-60-2\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"kt\">uint64</span>\n</span><span id=\"__span-60-3\"><a id=\"__codelineno-60-3\" name=\"__codelineno-60-3\" href=\"#__codelineno-60-3\"></a><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Add</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">)</span>\n</span><span id=\"__span-60-4\"><a id=\"__codelineno-60-4\" name=\"__codelineno-60-4\" href=\"#__codelineno-60-4\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">3</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-60-5\"><a id=\"__codelineno-60-5\" name=\"__codelineno-60-5\" href=\"#__codelineno-60-5\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-60-6\"><a id=\"__codelineno-60-6\" name=\"__codelineno-60-6\" href=\"#__codelineno-60-6\"></a><span class=\"w\">        </span><span class=\"nx\">atomic</span><span class=\"p\">.</span><span class=\"nx\">AddUint64</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">v</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-60-7\"><a id=\"__codelineno-60-7\" name=\"__codelineno-60-7\" href=\"#__codelineno-60-7\"></a><span class=\"w\">        </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Done</span><span class=\"p\">()</span>\n</span><span id=\"__span-60-8\"><a id=\"__codelineno-60-8\" name=\"__codelineno-60-8\" href=\"#__codelineno-60-8\"></a><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span><span id=\"__span-60-9\"><a id=\"__codelineno-60-9\" name=\"__codelineno-60-9\" href=\"#__codelineno-60-9\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-60-10\"><a id=\"__codelineno-60-10\" name=\"__codelineno-60-10\" href=\"#__codelineno-60-10\"></a><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Wait</span><span class=\"p\">()</span>\n</span><span id=\"__span-60-11\"><a id=\"__codelineno-60-11\" name=\"__codelineno-60-11\" href=\"#__codelineno-60-11\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">v</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>Or inside the loop but not in the newly created goroutine:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-61-1\"><a id=\"__codelineno-61-1\" name=\"__codelineno-61-1\" href=\"#__codelineno-61-1\"></a><span class=\"nx\">wg</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">sync</span><span class=\"p\">.</span><span class=\"nx\">WaitGroup</span><span class=\"p\">{}</span>\n</span><span id=\"__span-61-2\"><a id=\"__codelineno-61-2\" name=\"__codelineno-61-2\" href=\"#__codelineno-61-2\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"kt\">uint64</span>\n</span><span id=\"__span-61-3\"><a id=\"__codelineno-61-3\" name=\"__codelineno-61-3\" href=\"#__codelineno-61-3\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">3</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-61-4\"><a id=\"__codelineno-61-4\" name=\"__codelineno-61-4\" href=\"#__codelineno-61-4\"></a><span class=\"w\">    </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Add</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-61-5\"><a id=\"__codelineno-61-5\" name=\"__codelineno-61-5\" href=\"#__codelineno-61-5\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-61-6\"><a id=\"__codelineno-61-6\" name=\"__codelineno-61-6\" href=\"#__codelineno-61-6\"></a><span class=\"w\">        </span><span class=\"nx\">atomic</span><span class=\"p\">.</span><span class=\"nx\">AddUint64</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">v</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-61-7\"><a id=\"__codelineno-61-7\" name=\"__codelineno-61-7\" href=\"#__codelineno-61-7\"></a><span class=\"w\">        </span><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Done</span><span class=\"p\">()</span>\n</span><span id=\"__span-61-8\"><a id=\"__codelineno-61-8\" name=\"__codelineno-61-8\" href=\"#__codelineno-61-8\"></a><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span><span id=\"__span-61-9\"><a id=\"__codelineno-61-9\" name=\"__codelineno-61-9\" href=\"#__codelineno-61-9\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-61-10\"><a id=\"__codelineno-61-10\" name=\"__codelineno-61-10\" href=\"#__codelineno-61-10\"></a><span class=\"nx\">wg</span><span class=\"p\">.</span><span class=\"nx\">Wait</span><span class=\"p\">()</span>\n</span><span id=\"__span-61-11\"><a id=\"__codelineno-61-11\" name=\"__codelineno-61-11\" href=\"#__codelineno-61-11\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">v</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/71-wait-group/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"forgetting-about-synccond-72\">Forgetting about <code>sync.Cond</code> (#72)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>You can send repeated notifications to multiple goroutines with <code>sync.Cond</code>.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/72-cond/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-using-errgroup-73\">Not using <code>errgroup</code> (#73)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>You can synchronize a group of goroutines and handle errors and contexts with the <code>errgroup</code> package.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/73-errgroup/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"copying-a-sync-type-74\">Copying a <code>sync</code> type (#74)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p><code>sync</code> types shouldn’t be copied.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/74-copying-sync/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h2 id=\"standard-library\">Standard Library</h2>\n<h3 id=\"providing-a-wrong-time-duration-75\">Providing a wrong time duration (#75)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Remain cautious with functions accepting a <code>time.Duration</code>. Even though passing an integer is allowed, strive to use the time API to prevent any possible confusion.</p>\n</details>\n<p>Many common functions in the standard library accept a <code>time.Duration</code>, which is an alias for the <code>int64</code> type. However, one <code>time.Duration</code> unit represents one nanosecond, instead of one millisecond, as commonly seen in other programming languages. As a result, passing numeric types instead of using the <code>time.Duration</code> API can lead to unexpected behavior.</p>\n<p>A developer with experience in other languages might assume that the following code creates a new <code>time.Ticker</code> that delivers ticks every second, given the value <code>1000</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-62-1\"><a id=\"__codelineno-62-1\" name=\"__codelineno-62-1\" href=\"#__codelineno-62-1\"></a><span class=\"nx\">ticker</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">NewTicker</span><span class=\"p\">(</span><span class=\"mi\">1000</span><span class=\"p\">)</span>\n</span><span id=\"__span-62-2\"><a id=\"__codelineno-62-2\" name=\"__codelineno-62-2\" href=\"#__codelineno-62-2\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-62-3\"><a id=\"__codelineno-62-3\" name=\"__codelineno-62-3\" href=\"#__codelineno-62-3\"></a><span class=\"w\">    </span><span class=\"k\">select</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-62-4\"><a id=\"__codelineno-62-4\" name=\"__codelineno-62-4\" href=\"#__codelineno-62-4\"></a><span class=\"w\">    </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">ticker</span><span class=\"p\">.</span><span class=\"nx\">C</span><span class=\"p\">:</span>\n</span><span id=\"__span-62-5\"><a id=\"__codelineno-62-5\" name=\"__codelineno-62-5\" href=\"#__codelineno-62-5\"></a><span class=\"w\">        </span><span class=\"c1\">// Do something</span>\n</span><span id=\"__span-62-6\"><a id=\"__codelineno-62-6\" name=\"__codelineno-62-6\" href=\"#__codelineno-62-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-62-7\"><a id=\"__codelineno-62-7\" name=\"__codelineno-62-7\" href=\"#__codelineno-62-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>However, because 1,000 <code>time.Duration</code> units = 1,000 nanoseconds, ticks are delivered every 1,000 nanoseconds = 1 microsecond, not every second as assumed.</p>\n<p>We should always use the <code>time.Duration</code> API to avoid confusion and unexpected behavior:\n</p><div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-63-1\"><a id=\"__codelineno-63-1\" name=\"__codelineno-63-1\" href=\"#__codelineno-63-1\"></a><span class=\"nx\">ticker</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">NewTicker</span><span class=\"p\">(</span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">Microsecond</span><span class=\"p\">)</span>\n</span><span id=\"__span-63-2\"><a id=\"__codelineno-63-2\" name=\"__codelineno-63-2\" href=\"#__codelineno-63-2\"></a><span class=\"c1\">// Or</span>\n</span><span id=\"__span-63-3\"><a id=\"__codelineno-63-3\" name=\"__codelineno-63-3\" href=\"#__codelineno-63-3\"></a><span class=\"nx\">ticker</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">NewTicker</span><span class=\"p\">(</span><span class=\"mi\">1000</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"w\"> </span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">Nanosecond</span><span class=\"p\">)</span>\n</span></code></pre></div><p></p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/75-wrong-time-duration/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"timeafter-and-memory-leaks-76\"><code>time.After</code> and memory leaks (#76)</h3>\n<details class=\"warning\" open=\"open\">\n<summary>Warning</summary>\n<p>This mistake isn't relevant anymore from Go 1.23 (<a href=\"https://go.dev/wiki/Go123Timer\">details</a>).</p>\n</details>\n<h3 id=\"json-handling-common-mistakes-77\">JSON handling common mistakes (#77)</h3>\n<ul>\n<li>Unexpected behavior because of type embedding</li>\n</ul>\n<p>Be careful about using embedded fields in Go structs. Doing so may lead to sneaky bugs like an embedded time.Time field implementing the <code>json.Marshaler</code> interface, hence overriding the default marshaling behavior.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/type-embedding/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<ul>\n<li>JSON and the monotonic clock</li>\n</ul>\n<p>When comparing two <code>time.Time</code> structs, recall that <code>time.Time</code> contains both a wall clock and a monotonic clock, and the comparison using the == operator is done on both clocks.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/monotonic-clock/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<ul>\n<li>Map of <code>any</code></li>\n</ul>\n<p>To avoid wrong assumptions when you provide a map while unmarshaling JSON data, remember that numerics are converted to <code>float64</code> by default.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/map-any/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"common-sql-mistakes-78\">Common SQL mistakes (#78)</h3>\n<ul>\n<li>Forgetting that <code>sql.Open</code> doesn't necessarily establish connections to a database</li>\n</ul>\n<p>Call the <code>Ping</code> or <code>PingContext</code> method if you need to test your configuration and make sure a database is reachable.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/sql-open\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<ul>\n<li>Forgetting about connections pooling</li>\n</ul>\n<p>Configure the database connection parameters for production-grade applications.</p>\n<ul>\n<li>Not using prepared statements</li>\n</ul>\n<p>Using SQL prepared statements makes queries more efficient and more secure.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/prepared-statements\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<ul>\n<li>Mishandling null values</li>\n</ul>\n<p>Deal with nullable columns in tables using pointers or <code>sql.NullXXX</code> types.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/null-values/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<ul>\n<li>Not handling rows iteration errors</li>\n</ul>\n<p>Call the <code>Err</code> method of <code>sql.Rows</code> after row iterations to ensure that you haven’t missed an error while preparing the next row.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/rows-iterations-errors\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-closing-transient-resources-http-body-sqlrows-and-osfile-79\">Not closing transient resources (HTTP body, <code>sql.Rows</code>, and <code>os.File</code>) (#79)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Eventually close all structs implementing <code>io.Closer</code> to avoid possible leaks.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/79-closing-resources/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"forgetting-the-return-statement-after-replying-to-an-http-request-80\">Forgetting the return statement after replying to an HTTP request (#80)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>To avoid unexpected behaviors in HTTP handler implementations, make sure you don’t miss the <code>return</code> statement if you want a handler to stop after <code>http.Error</code>.</p>\n</details>\n<p>Consider the following HTTP handler that handles an error from <code>foo</code> using <code>http.Error</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-64-1\"><a id=\"__codelineno-64-1\" name=\"__codelineno-64-1\" href=\"#__codelineno-64-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">handler</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">ResponseWriter</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">req</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Request</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-64-2\"><a id=\"__codelineno-64-2\" name=\"__codelineno-64-2\" href=\"#__codelineno-64-2\"></a><span class=\"w\">    </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">foo</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">)</span>\n</span><span id=\"__span-64-3\"><a id=\"__codelineno-64-3\" name=\"__codelineno-64-3\" href=\"#__codelineno-64-3\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-64-4\"><a id=\"__codelineno-64-4\" name=\"__codelineno-64-4\" href=\"#__codelineno-64-4\"></a><span class=\"w\">        </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Error</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s\">\"foo\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">StatusInternalServerError</span><span class=\"p\">)</span>\n</span><span id=\"__span-64-5\"><a id=\"__codelineno-64-5\" name=\"__codelineno-64-5\" href=\"#__codelineno-64-5\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-64-6\"><a id=\"__codelineno-64-6\" name=\"__codelineno-64-6\" href=\"#__codelineno-64-6\"></a>\n</span><span id=\"__span-64-7\"><a id=\"__codelineno-64-7\" name=\"__codelineno-64-7\" href=\"#__codelineno-64-7\"></a><span class=\"w\">    </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">Write</span><span class=\"p\">([]</span><span class=\"nb\">byte</span><span class=\"p\">(</span><span class=\"s\">\"all good\"</span><span class=\"p\">))</span>\n</span><span id=\"__span-64-8\"><a id=\"__codelineno-64-8\" name=\"__codelineno-64-8\" href=\"#__codelineno-64-8\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">WriteHeader</span><span class=\"p\">(</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">StatusCreated</span><span class=\"p\">)</span>\n</span><span id=\"__span-64-9\"><a id=\"__codelineno-64-9\" name=\"__codelineno-64-9\" href=\"#__codelineno-64-9\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>If we run this code and <code>err != nil</code>, the HTTP response would be:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-65-1\"><a id=\"__codelineno-65-1\" name=\"__codelineno-65-1\" href=\"#__codelineno-65-1\"></a>foo\n</span><span id=\"__span-65-2\"><a id=\"__codelineno-65-2\" name=\"__codelineno-65-2\" href=\"#__codelineno-65-2\"></a>all good\n</span></code></pre></div>\n<p>The response contains both the error and success messages, and also the first HTTP status code, 500. There would also be a warning log indicating that we attempted to write the status code multiple times:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-66-1\"><a id=\"__codelineno-66-1\" name=\"__codelineno-66-1\" href=\"#__codelineno-66-1\"></a>2023/10/10 16:45:33 http: superfluous response.WriteHeader call from main.handler (main.go:20)\n</span></code></pre></div>\n<p>The mistake in this code is that <code>http.Error</code> does not stop the handler's execution, which means the success message and status code get written in addition to the error. Beyond an incorrect response, failing to return after writing an error can lead to the unwanted execution of code and unexpected side-effects. The following code adds the <code>return</code> statement following the <code>http.Error</code> and exhibits the desired behavior when ran:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-67-1\"><a id=\"__codelineno-67-1\" name=\"__codelineno-67-1\" href=\"#__codelineno-67-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">handler</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">ResponseWriter</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">req</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Request</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-67-2\"><a id=\"__codelineno-67-2\" name=\"__codelineno-67-2\" href=\"#__codelineno-67-2\"></a><span class=\"w\">    </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">foo</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">)</span>\n</span><span id=\"__span-67-3\"><a id=\"__codelineno-67-3\" name=\"__codelineno-67-3\" href=\"#__codelineno-67-3\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-67-4\"><a id=\"__codelineno-67-4\" name=\"__codelineno-67-4\" href=\"#__codelineno-67-4\"></a><span class=\"w\">        </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Error</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s\">\"foo\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">StatusInternalServerError</span><span class=\"p\">)</span>\n</span><span id=\"__span-67-5\"><a id=\"__codelineno-67-5\" name=\"__codelineno-67-5\" href=\"#__codelineno-67-5\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"c1\">// Adds the return statement</span>\n</span><span id=\"__span-67-6\"><a id=\"__codelineno-67-6\" name=\"__codelineno-67-6\" href=\"#__codelineno-67-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-67-7\"><a id=\"__codelineno-67-7\" name=\"__codelineno-67-7\" href=\"#__codelineno-67-7\"></a>\n</span><span id=\"__span-67-8\"><a id=\"__codelineno-67-8\" name=\"__codelineno-67-8\" href=\"#__codelineno-67-8\"></a><span class=\"w\">    </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">Write</span><span class=\"p\">([]</span><span class=\"nb\">byte</span><span class=\"p\">(</span><span class=\"s\">\"all good\"</span><span class=\"p\">))</span>\n</span><span id=\"__span-67-9\"><a id=\"__codelineno-67-9\" name=\"__codelineno-67-9\" href=\"#__codelineno-67-9\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">WriteHeader</span><span class=\"p\">(</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">StatusCreated</span><span class=\"p\">)</span>\n</span><span id=\"__span-67-10\"><a id=\"__codelineno-67-10\" name=\"__codelineno-67-10\" href=\"#__codelineno-67-10\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/80-http-return/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"using-the-default-http-client-and-server-81\">Using the default HTTP client and server (#81)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>For production-grade applications, don’t use the default HTTP client and server implementations. These implementations are missing timeouts and behaviors that should be mandatory in production.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/81-default-http-client-server/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h2 id=\"testing\">Testing</h2>\n<h3 id=\"not-categorizing-tests-build-tags-environment-variables-and-short-mode-82\">Not categorizing tests (build tags, environment variables, and short mode) (#82)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Categorizing tests using build flags, environment variables, or short mode makes the testing process more efficient. You can create test categories using build flags or environment variables (for example, unit versus integration tests) and differentiate short from long-running tests to decide which kinds of tests to execute.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/82-categorizing-tests/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-enabling-the-race-flag-83\">Not enabling the race flag (#83)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Enabling the <code>-race</code> flag is highly recommended when writing concurrent applications. Doing so allows you to catch potential data races that can lead to software bugs.</p>\n</details>\n<p>In Go, the race detector isn’t a static analysis tool used during compilation; instead, it’s a tool to find data races that occur at runtime. To enable it, we have to enable the -race flag while compiling or running a test. For example:</p>\n<div class=\"language-bash highlight\"><pre><span></span><code><span id=\"__span-68-1\"><a id=\"__codelineno-68-1\" name=\"__codelineno-68-1\" href=\"#__codelineno-68-1\"></a>go<span class=\"w\"> </span><span class=\"nb\">test</span><span class=\"w\"> </span>-race<span class=\"w\"> </span>./...\n</span></code></pre></div>\n<p>Once the race detector is enabled, the compiler instruments the code to detect data races. Instrumentation refers to a compiler adding extra instructions: here, tracking all memory accesses and recording when and how they occur.</p>\n<p>Enabling the race detector adds an overhead in terms of memory and execution time; hence, it's generally recommended to enable it only during local testing or continuous integration, not production.</p>\n<p>If a race is detected, Go raises a warning. For example:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-69-1\"><a id=\"__codelineno-69-1\" name=\"__codelineno-69-1\" href=\"#__codelineno-69-1\"></a><span class=\"kn\">package</span><span class=\"w\"> </span><span class=\"nx\">main</span>\n</span><span id=\"__span-69-2\"><a id=\"__codelineno-69-2\" name=\"__codelineno-69-2\" href=\"#__codelineno-69-2\"></a>\n</span><span id=\"__span-69-3\"><a id=\"__codelineno-69-3\" name=\"__codelineno-69-3\" href=\"#__codelineno-69-3\"></a><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"p\">(</span>\n</span><span id=\"__span-69-4\"><a id=\"__codelineno-69-4\" name=\"__codelineno-69-4\" href=\"#__codelineno-69-4\"></a><span class=\"w\">    </span><span class=\"s\">\"fmt\"</span>\n</span><span id=\"__span-69-5\"><a id=\"__codelineno-69-5\" name=\"__codelineno-69-5\" href=\"#__codelineno-69-5\"></a><span class=\"p\">)</span>\n</span><span id=\"__span-69-6\"><a id=\"__codelineno-69-6\" name=\"__codelineno-69-6\" href=\"#__codelineno-69-6\"></a>\n</span><span id=\"__span-69-7\"><a id=\"__codelineno-69-7\" name=\"__codelineno-69-7\" href=\"#__codelineno-69-7\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-69-8\"><a id=\"__codelineno-69-8\" name=\"__codelineno-69-8\" href=\"#__codelineno-69-8\"></a><span class=\"w\">    </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span>\n</span><span id=\"__span-69-9\"><a id=\"__codelineno-69-9\" name=\"__codelineno-69-9\" href=\"#__codelineno-69-9\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">}()</span>\n</span><span id=\"__span-69-10\"><a id=\"__codelineno-69-10\" name=\"__codelineno-69-10\" href=\"#__codelineno-69-10\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">i</span><span class=\"p\">)</span>\n</span><span id=\"__span-69-11\"><a id=\"__codelineno-69-11\" name=\"__codelineno-69-11\" href=\"#__codelineno-69-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Running this code with the <code>-race</code> logs the following warning:</p>\n<div class=\"language-bash highlight\"><pre><span></span><code><span id=\"__span-70-1\"><a id=\"__codelineno-70-1\" name=\"__codelineno-70-1\" href=\"#__codelineno-70-1\"></a><span class=\"o\">==================</span>\n</span><span id=\"__span-70-2\"><a id=\"__codelineno-70-2\" name=\"__codelineno-70-2\" href=\"#__codelineno-70-2\"></a>WARNING:<span class=\"w\"> </span>DATA<span class=\"w\"> </span>RACE\n</span><span id=\"__span-70-3\"><a id=\"__codelineno-70-3\" name=\"__codelineno-70-3\" href=\"#__codelineno-70-3\"></a><span class=\"hll\">Write<span class=\"w\"> </span>at<span class=\"w\"> </span>0x00c000026078<span class=\"w\"> </span>by<span class=\"w\"> </span>goroutine<span class=\"w\"> </span><span class=\"m\">7</span>:<span class=\"w\"> </span><span class=\"c1\"># (1)</span>\n</span></span><span id=\"__span-70-4\"><a id=\"__codelineno-70-4\" name=\"__codelineno-70-4\" href=\"#__codelineno-70-4\"></a><span class=\"w\">  </span>main.main.func1<span class=\"o\">()</span>\n</span><span id=\"__span-70-5\"><a id=\"__codelineno-70-5\" name=\"__codelineno-70-5\" href=\"#__codelineno-70-5\"></a><span class=\"w\">      </span>/tmp/app/main.go:9<span class=\"w\"> </span>+0x4e\n</span><span id=\"__span-70-6\"><a id=\"__codelineno-70-6\" name=\"__codelineno-70-6\" href=\"#__codelineno-70-6\"></a>\n</span><span id=\"__span-70-7\"><a id=\"__codelineno-70-7\" name=\"__codelineno-70-7\" href=\"#__codelineno-70-7\"></a><span class=\"hll\">Previous<span class=\"w\"> </span><span class=\"nb\">read</span><span class=\"w\"> </span>at<span class=\"w\"> </span>0x00c000026078<span class=\"w\"> </span>by<span class=\"w\"> </span>main<span class=\"w\"> </span>goroutine:<span class=\"w\"> </span><span class=\"c1\"># (2)</span>\n</span></span><span id=\"__span-70-8\"><a id=\"__codelineno-70-8\" name=\"__codelineno-70-8\" href=\"#__codelineno-70-8\"></a><span class=\"w\">  </span>main.main<span class=\"o\">()</span>\n</span><span id=\"__span-70-9\"><a id=\"__codelineno-70-9\" name=\"__codelineno-70-9\" href=\"#__codelineno-70-9\"></a><span class=\"w\">      </span>/tmp/app/main.go:10<span class=\"w\"> </span>+0x88\n</span><span id=\"__span-70-10\"><a id=\"__codelineno-70-10\" name=\"__codelineno-70-10\" href=\"#__codelineno-70-10\"></a>\n</span><span id=\"__span-70-11\"><a id=\"__codelineno-70-11\" name=\"__codelineno-70-11\" href=\"#__codelineno-70-11\"></a><span class=\"hll\">Goroutine<span class=\"w\"> </span><span class=\"m\">7</span><span class=\"w\"> </span><span class=\"o\">(</span>running<span class=\"o\">)</span><span class=\"w\"> </span>created<span class=\"w\"> </span>at:<span class=\"w\"> </span><span class=\"c1\"># (3)</span>\n</span></span><span id=\"__span-70-12\"><a id=\"__codelineno-70-12\" name=\"__codelineno-70-12\" href=\"#__codelineno-70-12\"></a><span class=\"w\">  </span>main.main<span class=\"o\">()</span>\n</span><span id=\"__span-70-13\"><a id=\"__codelineno-70-13\" name=\"__codelineno-70-13\" href=\"#__codelineno-70-13\"></a><span class=\"w\">      </span>/tmp/app/main.go:9<span class=\"w\"> </span>+0x7a\n</span><span id=\"__span-70-14\"><a id=\"__codelineno-70-14\" name=\"__codelineno-70-14\" href=\"#__codelineno-70-14\"></a><span class=\"o\">==================</span>\n</span></code></pre></div>\n<ol>\n<li>Indicates that goroutine 7 was writing</li>\n<li>Indicates that the main goroutine was reading</li>\n<li>Indicates when the goroutine 7 was created</li>\n</ol>\n<p>Let’s make sure we are comfortable reading these messages. Go always logs the following:</p>\n<ul>\n<li>The concurrent goroutines that are incriminated: here, the main goroutine and goroutine 7.</li>\n<li>Where accesses occur in the code: in this case, lines 9 and 10.</li>\n<li>When these goroutines were created: goroutine 7 was created in main().</li>\n</ul>\n<p>In addition, if a specific file contains tests that lead to data races, we can exclude it <span class=\"twemoji\" title=\"temporarily! 😉\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M11 9h2V7h-2m1 13c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8m0-18A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m-1 15h2v-6h-2z\"></path></svg></span> from race detection using the <code>!race</code> build tag:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-71-1\"><a id=\"__codelineno-71-1\" name=\"__codelineno-71-1\" href=\"#__codelineno-71-1\"></a><span class=\"c1\">//go:build !race</span>\n</span><span id=\"__span-71-2\"><a id=\"__codelineno-71-2\" name=\"__codelineno-71-2\" href=\"#__codelineno-71-2\"></a>\n</span><span id=\"__span-71-3\"><a id=\"__codelineno-71-3\" name=\"__codelineno-71-3\" href=\"#__codelineno-71-3\"></a><span class=\"kn\">package</span><span class=\"w\"> </span><span class=\"nx\">main</span>\n</span><span id=\"__span-71-4\"><a id=\"__codelineno-71-4\" name=\"__codelineno-71-4\" href=\"#__codelineno-71-4\"></a>\n</span><span id=\"__span-71-5\"><a id=\"__codelineno-71-5\" name=\"__codelineno-71-5\" href=\"#__codelineno-71-5\"></a><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"p\">(</span>\n</span><span id=\"__span-71-6\"><a id=\"__codelineno-71-6\" name=\"__codelineno-71-6\" href=\"#__codelineno-71-6\"></a><span class=\"w\">    </span><span class=\"s\">\"testing\"</span>\n</span><span id=\"__span-71-7\"><a id=\"__codelineno-71-7\" name=\"__codelineno-71-7\" href=\"#__codelineno-71-7\"></a><span class=\"p\">)</span>\n</span><span id=\"__span-71-8\"><a id=\"__codelineno-71-8\" name=\"__codelineno-71-8\" href=\"#__codelineno-71-8\"></a>\n</span><span id=\"__span-71-9\"><a id=\"__codelineno-71-9\" name=\"__codelineno-71-9\" href=\"#__codelineno-71-9\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">TestFoo</span><span class=\"p\">(</span><span class=\"nx\">t</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">T</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-71-10\"><a id=\"__codelineno-71-10\" name=\"__codelineno-71-10\" href=\"#__codelineno-71-10\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-71-11\"><a id=\"__codelineno-71-11\" name=\"__codelineno-71-11\" href=\"#__codelineno-71-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<h3 id=\"not-using-test-execution-modes-parallel-and-shuffle-84\">Not using test execution modes (parallel and shuffle) (#84)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Using the <code>-parallel</code> flag is an efficient way to speed up tests, especially long-running ones. Use the <code>-shuffle</code> flag to help ensure that a test suite doesn’t rely on wrong assumptions that could hide bugs.</p>\n</details>\n<h3 id=\"not-using-table-driven-tests-85\">Not using table-driven tests (#85)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Table-driven tests are an efficient way to group a set of similar tests to prevent code duplication and make future updates easier to handle.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/85-table-driven-tests/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"sleeping-in-unit-tests-86\">Sleeping in unit tests (#86)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Avoid sleeps using synchronization to make a test less flaky and more robust. If synchronization isn’t possible, consider a retry approach.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/86-sleeping/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-dealing-with-the-time-api-efficiently-87\">Not dealing with the time API efficiently (#87)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Understanding how to deal with functions using the time API is another way to make a test less flaky. You can use standard techniques such as handling the time as part of a hidden dependency or asking clients to provide it.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/87-time-api/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-using-testing-utility-packages-httptest-and-iotest-88\">Not using testing utility packages (<code>httptest</code> and <code>iotest</code>) (#88)</h3>\n<ul>\n<li>The <code>httptest</code> package is helpful for dealing with HTTP applications. It provides a set of utilities to test both clients and servers.</li>\n</ul>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/88-utility-package/httptest/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<ul>\n<li>The <code>iotest</code> package helps write io.Reader and test that an application is tolerant to errors.</li>\n</ul>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/88-utility-package/iotest/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"writing-inaccurate-benchmarks-89\">Writing inaccurate benchmarks (#89)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Regarding benchmarks:</p>\n<ul>\n<li>Use time methods to preserve the accuracy of a benchmark.</li>\n<li>Increasing benchtime or using tools such as benchstat can be helpful when dealing with micro-benchmarks.</li>\n<li>Be careful with the results of a micro-benchmark if the system that ends up running the application is different from the one running the micro-benchmark.</li>\n<li>Make sure the function under test leads to a side effect, to prevent compiler optimizations from fooling you about the benchmark results.</li>\n<li>To prevent the observer effect, force a benchmark to re-create the data used by a CPU-bound function.</li>\n</ul>\n</details>\n<p>Read the full section <a href=\"89-benchmarks/\">here</a>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/89-benchmark/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-exploring-all-the-go-testing-features-90\">Not exploring all the Go testing features (#90)</h3>\n<ul>\n<li>Code coverage</li>\n</ul>\n<p>Use code coverage with the <code>-coverprofile</code> flag to quickly see which part of the code needs more attention.</p>\n<ul>\n<li>Testing from a different package</li>\n</ul>\n<p>Place unit tests in a different package to enforce writing tests that focus on an exposed behavior, not internals.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/different-package/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<ul>\n<li>Utility functions</li>\n</ul>\n<p>Handling errors using the <code>*testing.T</code> variable instead of the classic <code>if err != nil</code> makes code shorter and easier to read.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/utility-function/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<ul>\n<li>Setup and teardown</li>\n</ul>\n<p>You can use setup and teardown functions to configure a complex environment, such as in the case of integration tests.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/setup-teardown/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-using-fuzzing-community-mistake\">Not using fuzzing (community mistake)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Fuzzing is an efficient strategy to detect random, unexpected, or malformed inputs to complex functions and methods in order to discover vulnerabilities, bugs, or even potential crashes.</p>\n</details>\n<p>Credits: <a href=\"https://github.com/jeromedoucet\">@jeromedoucet</a></p>\n<h2 id=\"optimizations\">Optimizations</h2>\n<h3 id=\"not-understanding-cpu-caches-91\">Not understanding CPU caches (#91)</h3>\n<ul>\n<li>CPU architecture</li>\n</ul>\n<p>Understanding how to use CPU caches is important for optimizing CPU-bound applications because the L1 cache is about 50 to 100 times faster than the main memory.</p>\n<ul>\n<li>Cache line</li>\n</ul>\n<p>Being conscious of the cache line concept is critical to understanding how to organize data in data-intensive applications. A CPU doesn’t fetch memory word by word; instead, it usually copies a memory block to a 64-byte cache line. To get the most out of each individual cache line, enforce spatial locality.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/cache-line/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<ul>\n<li>Slice of structs vs. struct of slices</li>\n</ul>\n<!-- TODO -->\n\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/slice-structs/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<ul>\n<li>Predictability</li>\n</ul>\n<p>Making code predictable for the CPU can also be an efficient way to optimize certain functions. For example, a unit or constant stride is predictable for the CPU, but a non-unit stride (for example, a linked list) isn’t predictable.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/predictability/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<ul>\n<li>Cache placement policy</li>\n</ul>\n<p>To avoid a critical stride, hence utilizing only a tiny portion of the cache, be aware that caches are partitioned.</p>\n<h3 id=\"writing-concurrent-code-that-leads-to-false-sharing-92\">Writing concurrent code that leads to false sharing (#92)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Knowing that lower levels of CPU caches aren’t shared across all the cores helps avoid performance-degrading patterns such as false sharing while writing concurrency code. Sharing memory is an illusion.</p>\n</details>\n<p>Read the full section <a href=\"92-false-sharing/\">here</a>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/92-false-sharing/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-taking-into-account-instruction-level-parallelism-93\">Not taking into account instruction-level parallelism (#93)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Use <abbr title=\"Instruction-Level Parallelism\">ILP</abbr> to optimize specific parts of your code to allow a CPU to execute as many parallel instructions as possible. Identifying data hazards is one of the main steps.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/93-instruction-level-parallelism/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-being-aware-of-data-alignment-94\">Not being aware of data alignment (#94)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>You can avoid common mistakes by remembering that in Go, basic types are aligned with their own size. For example, keep in mind that reorganizing the fields of a struct by size in descending order can lead to more compact structs (less memory allocation and potentially a better spatial locality).</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/94-data-alignment/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-understanding-stack-vs-heap-95\">Not understanding stack vs. heap (#95)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Understanding the fundamental differences between heap and stack should also be part of your core knowledge when optimizing a Go application. Stack allocations are almost free, whereas heap allocations are slower and rely on the <abbr title=\"Garbage Collector\">GC</abbr> to clean the memory.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/95-stack-heap/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-knowing-how-to-reduce-allocations-api-change-compiler-optimizations-and-syncpool-96\">Not knowing how to reduce allocations (API change, compiler optimizations, and <code>sync.Pool</code>) (#96)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Reducing allocations is also an essential aspect of optimizing a Go application. This can be done in different ways, such as designing the API carefully to prevent sharing up, understanding the common Go compiler optimizations, and using <code>sync.Pool</code>.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/96-reduce-allocations/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Source code</a></p>\n<h3 id=\"not-relying-on-inlining-97\">Not relying on inlining (#97)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Use the fast-path inlining technique to efficiently reduce the amortized time to call a function.</p>\n</details>\n<h3 id=\"not-using-go-diagnostics-tooling-98\">Not using Go diagnostics tooling (#98)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Rely on profiling and the execution tracer to understand how an application performs and the parts to optimize.</p>\n</details>\n<p>Read the full section <a href=\"98-profiling-execution-tracing/\">here</a>.</p>\n<h3 id=\"not-understanding-how-the-gc-works-99\">Not understanding how the <abbr title=\"Garbage Collector\">GC</abbr> works (#99)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Understanding how to tune the <abbr title=\"Garbage Collector\">GC</abbr> can lead to multiple benefits such as handling sudden load increases more efficiently.</p>\n</details>\n<h3 id=\"not-understanding-the-impacts-of-running-go-in-docker-and-kubernetes-100\"><img alt=\"⚠\" class=\"twemoji\" src=\"https://cdn.jsdelivr.net/gh/jdecked/twemoji@15.1.0/assets/svg/26a0.svg\" title=\":warning:\"> Not understanding the impacts of running Go in Docker and Kubernetes (#100)</h3>\n<details class=\"warning\" open=\"open\">\n<summary>Warning</summary>\n<p>This mistake isn't relevant anymore from Go 1.25 (<a href=\"https://go.dev/blog/container-aware-gomaxprocs\">details</a>).</p>\n</details>\n<h2 id=\"community\">Community</h2>\n<p>Thanks to all the contributors:</p>\n<p><a href=\"https://contrib.rocks/image?repo=teivah/100-go-mistakes\">\n    <img src=\"https://contrib.rocks/image?repo=teivah/100-go-mistakes\" alt=\"Description of the image\">\n</a></p>\n<h2 id=\"powered-by\">Powered by</h2>\n<p><a href=\"https://jb.gg/OpenSource\"><img alt=\"JetBrains logo.\" src=\"https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.svg\"></a></p>\n\n\n\n\n\n\n\n  \n  \n\n\n\n  \n\n\n\n\n<h2 id=\"__comments\">Comments</h2>\n<!-- Insert generated snippet here -->\n<script src=\"https://giscus.app/client.js\" data-repo=\"teivah/100-go-mistakes\" data-repo-id=\"MDEwOlJlcG9zaXRvcnkzMjA4MTg5NjI=\" data-category=\"Discussions\" data-category-id=\"DIC_kwDOEx9PEs4CZQUm\" data-mapping=\"pathname\" data-strict=\"0\" data-reactions-enabled=\"1\" data-emit-metadata=\"0\" data-input-position=\"bottom\" data-theme=\"preferred_color_scheme\" data-lang=\"en\" crossorigin=\"anonymous\" async>\n</script>\n<!-- Synchronize Giscus theme with palette -->\n<script>\n  var giscus = document.querySelector(\"script[src*=giscus]\")\n\n  // Set palette on initial load\n  var palette = __md_get(\"__palette\")\n  if (palette && typeof palette.color === \"object\") {\n    var theme = palette.color.scheme === \"slate\"\n        ? \"transparent_dark\"\n        : \"light\"\n\n    // Instruct Giscus to set theme\n    giscus.setAttribute(\"data-theme\", theme)\n  }\n\n  // Register event handlers after documented loaded\n  document.addEventListener(\"DOMContentLoaded\", function() {\n    var ref = document.querySelector(\"[data-md-component=palette]\")\n    ref.addEventListener(\"change\", function() {\n      var palette = __md_get(\"__palette\")\n      if (palette && typeof palette.color === \"object\") {\n        var theme = palette.color.scheme === \"slate\"\n            ? \"transparent_dark\"\n            : \"light\"\n\n        // Instruct Giscus to change theme\n        var frame = document.querySelector(\".giscus-frame\")\n        frame.contentWindow.postMessage(\n            { giscus: { setConfig: { theme } } },\n            \"https://giscus.app\"\n        )\n      }\n    })\n  })\n</script>\n\n                \n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright © 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"></path></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \".\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  \n<script id=\"init-glightbox\">const lightbox = GLightbox({\"touchNavigation\": true, \"loop\": false, \"zoomable\": true, \"draggable\": true, \"openEffect\": \"zoom\", \"closeEffect\": \"zoom\", \"slideEffect\": \"slide\"});\ndocument$.subscribe(()=>{ lightbox.reload(); });\n</script></body></html>"
  },
  {
    "path": "site/ja/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\" class=\"no-js\"><head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n      \n      \n        <link rel=\"canonical\" href=\"https://100go.co/ja/\">\n      \n      \n        <link rel=\"prev\" href=\"../zh/\">\n      \n      \n        <link rel=\"next\" href=\"../pt-br/\">\n      \n      \n      <link rel=\"icon\" href=\"../img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>Japanese Version - 100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"../assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\"..\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n      \n        <meta property=\"og:type\" content=\"website\">\n      \n        <meta property=\"og:title\" content=\"Japanese Version - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta property=\"og:description\" content=\"None\">\n      \n        <meta property=\"og:image\" content=\"https://100go.co/assets/images/social/ja.png\">\n      \n        <meta property=\"og:image:type\" content=\"image/png\">\n      \n        <meta property=\"og:image:width\" content=\"1200\">\n      \n        <meta property=\"og:image:height\" content=\"630\">\n      \n        <meta property=\"og:url\" content=\"https://100go.co/ja/\">\n      \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n      \n        <meta name=\"twitter:title\" content=\"Japanese Version - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta name=\"twitter:description\" content=\"None\">\n      \n        <meta name=\"twitter:image\" content=\"https://100go.co/assets/images/social/ja.png\">\n      \n    \n    \n  <link href=\"../assets/stylesheets/glightbox.min.css\" rel=\"stylesheet\"><script src=\"../assets/javascripts/glightbox.min.js\"></script><style id=\"glightbox-style\">\n            html.glightbox-open { overflow: initial; height: 100%; }\n            .gslide-title { margin-top: 0px; user-select: text; }\n            .gslide-desc { color: #666; user-select: text; }\n            .gslide-image img { background: white; }\n            .gscrollbar-fixer { padding-right: 15px; }\n            .gdesc-inner { font-size: 0.75rem; }\n            body[data-md-color-scheme=\"slate\"] .gdesc-inner { background: var(--md-default-bg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-title { color: var(--md-default-fg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-desc { color: var(--md-default-fg-color); }\n        </style></head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n        \n        <a href=\"#go\" class=\"md-skip\">\n          Skip to content\n        </a>\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"></path></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              Japanese Version\n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"></path></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"></path></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"></path></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n    \n  \n  \n    \n    \n      <li class=\"md-tabs__item md-tabs__item--active\">\n        <a href=\"..\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"../book/\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n        \n        \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"..\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../5-interface-pollution/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../9-generics/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../20-slice/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../28-maps-memory-leaks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../56-concurrency-faster/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../89-benchmarks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../92-false-sharing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../98-profiling-execution-tracing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1_3\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../zh/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    <li class=\"md-nav__item md-nav__item--active\">\n      \n      <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n      \n      \n        \n      \n      \n        <label class=\"md-nav__link md-nav__link--active\" for=\"__toc\">\n          \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n          <span class=\"md-nav__icon md-icon\"></span>\n        </label>\n      \n      <a href=\"./\" class=\"md-nav__link md-nav__link--active\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n      \n        \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      コードとプロジェクト構成\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"コードとプロジェクト構成\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      意図的でない変数のシャドーイング (#1)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#2\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不必要にネストされたコード (#2)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#init-3\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      init関数の誤用 (#3)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#4\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ゲッターとセッターの乱用 (#4)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#5\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      インタフェース汚染 (#5)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#6\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      生産者側のインタフェース (#6)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#7\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      インタフェースを返す (#7)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#any-8\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      any は何も言わない (#8)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#9\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ジェネリックスをいつ使用するべきか理解していない (#9)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#10\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      型の埋め込みで起こりうる問題を把握していない (#10)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#functional-options-11\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Functional Options パターンを使用していない (#11)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#12\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      誤ったプロジェクト構成 (プロジェクト構造とパッケージ構成) (#12)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#13\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ユーティリティパッケージの作成 (#13)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#14\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      パッケージ名の衝突を無視する (#14)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#15\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      コードの文章化が行われていない (#15)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#16\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      リンターを使用してない (#16)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_2\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      データ型\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"データ型\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#8-17\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      8 進数リテラルで混乱を招いてしまう (#17)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#18\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      整数オーバーフローを無視している (#18)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#19\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      浮動小数点を理解していない (#19)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#20\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      スライスの長さと容量を理解していない (#20)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#21\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      非効率なスライスの初期化 (#21)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nil-22\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      nil と空のスライスを混同している (#22)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#23\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      スライスが空かどうかを適切に確認しない (#23)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#24\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      スライスのコピーを正しく作成していない (#24)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#append-25\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      append の使用による予想外の副作用 (#25)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#26\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      スライスとメモリリーク (#26)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"スライスとメモリリーク (#26)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#_3\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      容量漏れ\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#_4\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      スライスとポインタ\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#27\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      非効率なマップの初期化 (#27)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#28\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      マップとメモリリーク (#28)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#29\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      誤った方法による値の比較 (#29)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_5\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      制御構造\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"制御構造\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#range-30\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      要素が range ループ内でコピーされることを知らない (#30)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#range-31\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      range ループ（チャネルと配列）での引数の評価方法を知らない (#31)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#range-32\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      range ループ内におけるポインタ要素の使用が及ぼす影響を分かっていない (#32)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#33\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      マップの反復処理中に誤った仮定をする（反復処理中の順序付けとマップの挿入） (#33)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#break-34\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      break 文がどのように機能するかを分かっていない (#34)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#defer-35\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ループ内で defer を使用する (#35)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_6\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      文字列\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"文字列\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#36\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ルーンを理解していない (#36)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#37\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      文字列に対する不正な反復処理 (#37)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#trim-38\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      trim 関数の誤用 (#38)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#39\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      最適化が不十分な文字列の連結 (#39)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#40\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      無駄な文字列変換 (#40)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#41\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      部分文字列とメモリリーク (#41)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_7\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      関数とメソッド\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"関数とメソッド\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#42\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      どの型のレシーバーを使用すればよいかわかっていない (#42)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#43\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      名前付き結果パラメータをまったく使用していない (#43)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#44\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      名前付き結果パラメータによる予想外の副作用 (#44)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nil-45\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      nil レシーバーを返す (#45)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#46\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      関数入力にファイル名を使用している (#46)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#defer-47\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      defer 引数とレシーバーがどのように評価されるかを知らない（引数の評価、ポインター、および値レシーバー） (#47)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_8\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      エラー処理\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"エラー処理\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#48\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      パニック (#48)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#49\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      エラーをラップすべきときを知らない (#49)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#50\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      エラー型の不正な比較 (#50)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#51\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      エラー値の不正な比較 (#51)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#2-52\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      エラーの 2 回処理 (#52)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#53\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      エラー処理をしない (#53)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#defer-54\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      defer エラーを処理しない (#54)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_9\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      並行処理：基礎\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"並行処理：基礎\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#55\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      並行処理と並列処理の混同 (#55)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#56\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      並行処理のほうが常に早いと考えている (#56)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#57\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      チャネルまたはミューテックスをいつ使用するべきかについて戸惑っている (#57)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-58\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      競合問題を理解していない（データ競合と競合状態、そしてGo言語のメモリモデル） (#58)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"競合問題を理解していない（データ競合と競合状態、そしてGo言語のメモリモデル） (#58)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#_10\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      データ競合\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#_11\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      競合状態\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#59\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ワークロードタイプごとの並行処理の影響を理解していない (#59)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-context-60\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Go Context に対する誤解 (#60)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Go Context に対する誤解 (#60)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#_12\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      デッドライン\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#_13\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      キャンセルシグナル\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#context-value\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Context Value\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#context\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Context のキャンセルをキャッチする\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_14\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      並行処理：実践\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"並行処理：実践\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#context-61\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不適切な Context を広めてしまう (#61)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#62\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      停止すべきときを知らずにゴルーチンを開始してしまう (#62)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#63\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ゴルーチンとループ変数に注意しない (#63)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#select-64\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      select とチャネルを使用して決定的動作を期待する (#64)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#65\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      通知チャネルを使用していない (#65)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nil-66\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      nil チャネルを使用していない (#66)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#67\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      チャネルの容量について困惑している (#67)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#etcd-68\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      文字列フォーマットで起こり得る副作用を忘れてしまう（ etcd データ競合の例とデッドロック） (#68)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#append-69\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      append でデータ競合を起こしてしまう (#69)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#70\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      スライスとマップでミューテックスを正しく使用していない (#70)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#syncwaitgroup-71\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      sync.WaitGroup を正しく使用していない (#71)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#synccond-72\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      sync.Cond について忘れてしまう (#72)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#errgroup-73\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      errgroup を使用していない (#73)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#sync-74\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      sync 型のコピー (#74)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_15\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      標準ライブラリ\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"標準ライブラリ\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#75\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      間違った時間を指定する (#75)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#timeafter-76\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      time.After とメモリリーク (#76)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#json-77\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      JSON 処理でありがちな間違い (#77)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#sql-78\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      SQL でありがちな間違い (#78)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#http-bodysqlrows-osfile-79\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      一時的なリソース（ HTTP body、sql.Rows、および os.File ）を閉じていない (#79)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#http-return-80\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      HTTP リクエストに応答した後の return 文を忘れてしまう (#80)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#http-81\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      標準の HTTP クライアントとサーバーを使用している (#81)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_16\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      テスト\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"テスト\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#82\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      テストを分類していない（ビルドタグ、環境変数、ショートモード） (#82)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#-race-83\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      -race フラグを有効にしていない (#83)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#-parallel-shuffle-84\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      テスト実行モード（ -parallel および -shuffle ）を使用していない (#84)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#85\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      テーブル駆動テストを使用しない (#85)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#86\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      単体テストでのスリープ (#86)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#time-api-87\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      time API を効率的に処理できていない (#87)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#httptest-iotest-88\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      テストに関するユーティリティパッケージ（ httptest および iotest ）を使用していない (#88)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#89\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不正確なベンチマークの作成 (#89)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-90\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Go言語のテスト機能をすべて試していない (#90)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#community-mistake\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ファジングを使用していない（community mistake）\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_17\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      最適化\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"最適化\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#cpu-91\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      CPU キャッシュを理解していない (#91)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#92\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      誤った共有を引き起こす並行処理(#92)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#93\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      命令レベルの並列性を考慮しない (#93)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#94\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      データの配置を意識していない (#94)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#95\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ヒープとスタックの違いを理解していない (#95)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#api-syncpool-96\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      割り当てを減らす方法がわかっていない（ API の変更、コンパイラの最適化、および sync.Pool） (#96)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#97\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      インライン展開をしていない (#97)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-98\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Go言語の診断ツールを利用していない (#98)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#gc-99\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      GC の仕組みを理解していない (#99)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#docker-kubernetes-go-100\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Docker と Kubernetes 上でGo言語を実行することの影響を理解していない (#100)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../pt-br/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../book/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../chapter-1/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../external/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      コードとプロジェクト構成\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"コードとプロジェクト構成\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      意図的でない変数のシャドーイング (#1)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#2\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不必要にネストされたコード (#2)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#init-3\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      init関数の誤用 (#3)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#4\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ゲッターとセッターの乱用 (#4)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#5\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      インタフェース汚染 (#5)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#6\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      生産者側のインタフェース (#6)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#7\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      インタフェースを返す (#7)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#any-8\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      any は何も言わない (#8)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#9\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ジェネリックスをいつ使用するべきか理解していない (#9)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#10\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      型の埋め込みで起こりうる問題を把握していない (#10)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#functional-options-11\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Functional Options パターンを使用していない (#11)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#12\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      誤ったプロジェクト構成 (プロジェクト構造とパッケージ構成) (#12)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#13\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ユーティリティパッケージの作成 (#13)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#14\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      パッケージ名の衝突を無視する (#14)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#15\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      コードの文章化が行われていない (#15)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#16\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      リンターを使用してない (#16)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_2\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      データ型\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"データ型\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#8-17\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      8 進数リテラルで混乱を招いてしまう (#17)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#18\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      整数オーバーフローを無視している (#18)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#19\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      浮動小数点を理解していない (#19)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#20\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      スライスの長さと容量を理解していない (#20)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#21\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      非効率なスライスの初期化 (#21)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nil-22\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      nil と空のスライスを混同している (#22)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#23\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      スライスが空かどうかを適切に確認しない (#23)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#24\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      スライスのコピーを正しく作成していない (#24)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#append-25\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      append の使用による予想外の副作用 (#25)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#26\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      スライスとメモリリーク (#26)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"スライスとメモリリーク (#26)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#_3\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      容量漏れ\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#_4\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      スライスとポインタ\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#27\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      非効率なマップの初期化 (#27)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#28\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      マップとメモリリーク (#28)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#29\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      誤った方法による値の比較 (#29)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_5\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      制御構造\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"制御構造\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#range-30\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      要素が range ループ内でコピーされることを知らない (#30)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#range-31\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      range ループ（チャネルと配列）での引数の評価方法を知らない (#31)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#range-32\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      range ループ内におけるポインタ要素の使用が及ぼす影響を分かっていない (#32)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#33\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      マップの反復処理中に誤った仮定をする（反復処理中の順序付けとマップの挿入） (#33)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#break-34\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      break 文がどのように機能するかを分かっていない (#34)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#defer-35\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ループ内で defer を使用する (#35)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_6\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      文字列\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"文字列\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#36\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ルーンを理解していない (#36)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#37\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      文字列に対する不正な反復処理 (#37)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#trim-38\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      trim 関数の誤用 (#38)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#39\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      最適化が不十分な文字列の連結 (#39)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#40\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      無駄な文字列変換 (#40)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#41\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      部分文字列とメモリリーク (#41)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_7\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      関数とメソッド\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"関数とメソッド\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#42\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      どの型のレシーバーを使用すればよいかわかっていない (#42)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#43\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      名前付き結果パラメータをまったく使用していない (#43)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#44\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      名前付き結果パラメータによる予想外の副作用 (#44)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nil-45\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      nil レシーバーを返す (#45)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#46\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      関数入力にファイル名を使用している (#46)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#defer-47\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      defer 引数とレシーバーがどのように評価されるかを知らない（引数の評価、ポインター、および値レシーバー） (#47)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_8\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      エラー処理\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"エラー処理\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#48\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      パニック (#48)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#49\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      エラーをラップすべきときを知らない (#49)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#50\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      エラー型の不正な比較 (#50)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#51\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      エラー値の不正な比較 (#51)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#2-52\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      エラーの 2 回処理 (#52)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#53\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      エラー処理をしない (#53)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#defer-54\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      defer エラーを処理しない (#54)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_9\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      並行処理：基礎\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"並行処理：基礎\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#55\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      並行処理と並列処理の混同 (#55)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#56\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      並行処理のほうが常に早いと考えている (#56)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#57\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      チャネルまたはミューテックスをいつ使用するべきかについて戸惑っている (#57)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-58\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      競合問題を理解していない（データ競合と競合状態、そしてGo言語のメモリモデル） (#58)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"競合問題を理解していない（データ競合と競合状態、そしてGo言語のメモリモデル） (#58)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#_10\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      データ競合\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#_11\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      競合状態\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#59\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ワークロードタイプごとの並行処理の影響を理解していない (#59)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-context-60\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Go Context に対する誤解 (#60)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Go Context に対する誤解 (#60)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#_12\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      デッドライン\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#_13\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      キャンセルシグナル\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#context-value\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Context Value\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#context\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Context のキャンセルをキャッチする\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_14\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      並行処理：実践\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"並行処理：実践\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#context-61\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不適切な Context を広めてしまう (#61)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#62\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      停止すべきときを知らずにゴルーチンを開始してしまう (#62)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#63\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ゴルーチンとループ変数に注意しない (#63)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#select-64\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      select とチャネルを使用して決定的動作を期待する (#64)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#65\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      通知チャネルを使用していない (#65)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nil-66\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      nil チャネルを使用していない (#66)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#67\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      チャネルの容量について困惑している (#67)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#etcd-68\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      文字列フォーマットで起こり得る副作用を忘れてしまう（ etcd データ競合の例とデッドロック） (#68)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#append-69\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      append でデータ競合を起こしてしまう (#69)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#70\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      スライスとマップでミューテックスを正しく使用していない (#70)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#syncwaitgroup-71\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      sync.WaitGroup を正しく使用していない (#71)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#synccond-72\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      sync.Cond について忘れてしまう (#72)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#errgroup-73\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      errgroup を使用していない (#73)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#sync-74\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      sync 型のコピー (#74)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_15\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      標準ライブラリ\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"標準ライブラリ\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#75\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      間違った時間を指定する (#75)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#timeafter-76\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      time.After とメモリリーク (#76)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#json-77\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      JSON 処理でありがちな間違い (#77)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#sql-78\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      SQL でありがちな間違い (#78)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#http-bodysqlrows-osfile-79\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      一時的なリソース（ HTTP body、sql.Rows、および os.File ）を閉じていない (#79)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#http-return-80\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      HTTP リクエストに応答した後の return 文を忘れてしまう (#80)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#http-81\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      標準の HTTP クライアントとサーバーを使用している (#81)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_16\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      テスト\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"テスト\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#82\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      テストを分類していない（ビルドタグ、環境変数、ショートモード） (#82)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#-race-83\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      -race フラグを有効にしていない (#83)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#-parallel-shuffle-84\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      テスト実行モード（ -parallel および -shuffle ）を使用していない (#84)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#85\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      テーブル駆動テストを使用しない (#85)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#86\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      単体テストでのスリープ (#86)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#time-api-87\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      time API を効率的に処理できていない (#87)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#httptest-iotest-88\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      テストに関するユーティリティパッケージ（ httptest および iotest ）を使用していない (#88)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#89\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不正確なベンチマークの作成 (#89)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-90\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Go言語のテスト機能をすべて試していない (#90)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#community-mistake\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ファジングを使用していない（community mistake）\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_17\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      最適化\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"最適化\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#cpu-91\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      CPU キャッシュを理解していない (#91)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#92\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      誤った共有を引き起こす並行処理(#92)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#93\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      命令レベルの並列性を考慮しない (#93)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#94\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      データの配置を意識していない (#94)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#95\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      ヒープとスタックの違いを理解していない (#95)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#api-syncpool-96\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      割り当てを減らす方法がわかっていない（ API の変更、コンパイラの最適化、および sync.Pool） (#96)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#97\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      インライン展開をしていない (#97)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-98\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Go言語の診断ツールを利用していない (#98)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#gc-99\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      GC の仕組みを理解していない (#99)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#docker-kubernetes-go-100\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Docker と Kubernetes 上でGo言語を実行することの影響を理解していない (#100)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n                  \n\n\n  \n  \n\n\n<h1 id=\"go\">Go言語でありがちな間違い</h1>\n<details class=\"tip\" open=\"open\">\n<summary>The Coder Cafe</summary>\n<p>もし私の本を楽しんでいただけたなら、私の最新プロジェクトにもご興味があるかもしれません。<a href=\"https://thecoder.cafe?rd=100go.co/ja\">The Coder Cafe</a>は、コーダー向けの日刊ニュースレターです。</p>\n<blockquote>\n<p>Feeling overwhelmed by the endless stream of tech content? At The Coder Cafe, we serve one essential concept for coders. Written by a senior software engineer at Google, it's perfectly brewed for your morning coffee, helping you grow your skills deeply.</p>\n</blockquote>\n<p></p><center><a href=\"https://thecoder.cafe?rd=100go.co/ja\"><img src=\"../img/thecodercafe.png\" alt=\"\" style=\"width:480px;height:240px;\"></a></center><p></p>\n</details>\n<p>このページは『100 Go Mistakes』の内容をまとめたものです。一方で、コミュニティに開かれたページでもあります。「ありがちな間違い」が新たに追加されるべきだとお考えでしたら <a href=\"https://github.com/teivah/100-go-mistakes/issues/new?assignees=&amp;labels=community+mistake&amp;template=community_mistake.md&amp;title=\">community mistake issue</a> を作成してください。</p>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/inside-cover.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/inside-cover.png\"></a></p>\n<details class=\"warning\" open=\"open\">\n<summary>注意</summary>\n<p>現在、大幅に多くのコンテンツを追加して強化している新しいバージョンを閲覧しています。このバージョンはまだ開発中です。問題を見つけた場合はどうぞ気軽にPRを作成してください。</p>\n</details>\n<h2 id=\"_1\">コードとプロジェクト構成</h2>\n<h3 id=\"1\">意図的でない変数のシャドーイング (#1)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>変数のシャドーイングを避けることは、誤った変数の参照や読み手の混乱を防ぎます。</p>\n</details>\n<p>変数のシャドーイングは、変数名がブロック内で再宣言されることで生じますが、これは間違いを引き起こしやすくします。変数のシャドーイングを禁止するかどうかは個人の好みによります。たとえば、エラーに対して <code>err</code> のような既存の変数名を再利用すると便利な場合があります。とはいえ、コードはコンパイルされたものの、値を受け取った変数が予期したものではないというシナリオに直面する可能性があるため、原則として引き続き注意を払う必要があります。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/1-variable-shadowing/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"2\">不必要にネストされたコード (#2)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>ネストが深くならないようにし、ハッピーパスを左側に揃えることでメンタルコードモデルを構築することが容易になります。</p>\n</details>\n<p>一般的に、関数がより深いネストを要求するほど、読んで理解することがより複雑になります。私たちのコードの可読性を最適化するために、このルールの適用方法を見ていきましょう。</p>\n<ul>\n<li><code>if</code> ブロックが返されるとき、すべての場合において <code>else</code> ブロックを省略する必要があります。 たとえば、次のように書くべきではありません。</li>\n</ul>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-0-1\"><a id=\"__codelineno-0-1\" name=\"__codelineno-0-1\" href=\"#__codelineno-0-1\"></a><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">foo</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-0-2\"><a id=\"__codelineno-0-2\" name=\"__codelineno-0-2\" href=\"#__codelineno-0-2\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-0-3\"><a id=\"__codelineno-0-3\" name=\"__codelineno-0-3\" href=\"#__codelineno-0-3\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">true</span>\n</span><span id=\"__span-0-4\"><a id=\"__codelineno-0-4\" name=\"__codelineno-0-4\" href=\"#__codelineno-0-4\"></a><span class=\"p\">}</span><span class=\"w\"> </span><span class=\"k\">else</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-0-5\"><a id=\"__codelineno-0-5\" name=\"__codelineno-0-5\" href=\"#__codelineno-0-5\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-0-6\"><a id=\"__codelineno-0-6\" name=\"__codelineno-0-6\" href=\"#__codelineno-0-6\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>代わりに、次のように <code>else</code> ブロックを省略します。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-1-1\"><a id=\"__codelineno-1-1\" name=\"__codelineno-1-1\" href=\"#__codelineno-1-1\"></a><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">foo</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-2\"><a id=\"__codelineno-1-2\" name=\"__codelineno-1-2\" href=\"#__codelineno-1-2\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-1-3\"><a id=\"__codelineno-1-3\" name=\"__codelineno-1-3\" href=\"#__codelineno-1-3\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">true</span>\n</span><span id=\"__span-1-4\"><a id=\"__codelineno-1-4\" name=\"__codelineno-1-4\" href=\"#__codelineno-1-4\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-1-5\"><a id=\"__codelineno-1-5\" name=\"__codelineno-1-5\" href=\"#__codelineno-1-5\"></a><span class=\"c1\">// ...</span>\n</span></code></pre></div>\n<ul>\n<li>ノンハッピーパスでもこのロジックに従うことが可能です。</li>\n</ul>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-2-1\"><a id=\"__codelineno-2-1\" name=\"__codelineno-2-1\" href=\"#__codelineno-2-1\"></a><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"s\">\"\"</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-2-2\"><a id=\"__codelineno-2-2\" name=\"__codelineno-2-2\" href=\"#__codelineno-2-2\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-2-3\"><a id=\"__codelineno-2-3\" name=\"__codelineno-2-3\" href=\"#__codelineno-2-3\"></a><span class=\"p\">}</span><span class=\"w\"> </span><span class=\"k\">else</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-2-4\"><a id=\"__codelineno-2-4\" name=\"__codelineno-2-4\" href=\"#__codelineno-2-4\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">errors</span><span class=\"p\">.</span><span class=\"nx\">New</span><span class=\"p\">(</span><span class=\"s\">\"empty string\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-2-5\"><a id=\"__codelineno-2-5\" name=\"__codelineno-2-5\" href=\"#__codelineno-2-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>ここでは、空の <code>s</code> がノンハッピーパスを表します。したがって、次のように条件をひっくり返す必要があります。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-3-1\"><a id=\"__codelineno-3-1\" name=\"__codelineno-3-1\" href=\"#__codelineno-3-1\"></a><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">==</span><span class=\"w\"> </span><span class=\"s\">\"\"</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-3-2\"><a id=\"__codelineno-3-2\" name=\"__codelineno-3-2\" href=\"#__codelineno-3-2\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">errors</span><span class=\"p\">.</span><span class=\"nx\">New</span><span class=\"p\">(</span><span class=\"s\">\"empty string\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-3-3\"><a id=\"__codelineno-3-3\" name=\"__codelineno-3-3\" href=\"#__codelineno-3-3\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-3-4\"><a id=\"__codelineno-3-4\" name=\"__codelineno-3-4\" href=\"#__codelineno-3-4\"></a><span class=\"c1\">// ...</span>\n</span></code></pre></div>\n<p>読みやすいコードを書くことは、すべての開発者にとって重要な課題です。ネストされたブロックの数を減らすよう努め、ハッピーパスを左側に揃え、できるだけ早く戻ることが、コードの可読性を向上させる具体的な手段です。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/2-nested-code/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"init-3\">init関数の誤用 (#3)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>変数を初期化するときは、init関数のエラー処理が制限されており、ステートの処理とテストがより複雑になることに注意してください。ほとんどの場合、初期化は特定の関数として処理されるべきです。</p>\n</details>\n<p>init関数は、アプリケーションのステートを初期化するために使用される関数です。引数を取らず、結果も返しません（ <code>func()</code> 関数）。パッケージが初期化されると、パッケージ内のすべての定数および変数の宣言が評価されます。次に、init関数が実行されます。</p>\n<p>init関数はいくつかの問題を引き起こす可能性があります。</p>\n<ul>\n<li>エラー処理が制限される可能性があります。</li>\n<li>テストの実装方法が複雑になる可能性があります（たとえば、外部依存関係を設定する必要がありますが、単体テストの範囲では必要ない可能性があります）。</li>\n<li>初期化でステートを設定する必要がある場合は、グローバル変数を使用して行う必要があります。</li>\n</ul>\n<p>init関数には注意が必要です。ただし、静的構成の定義など、状況によっては役立つ場合があります。それ以外のほとんどの場合、初期化処理は特定の関数を通じて行われるべきです。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/3-init-functions/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"4\">ゲッターとセッターの乱用 (#4)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>Go言語では、慣用的にゲッターとセッターの使用を強制することはありません。実利を重視し、効率性と特定の慣習に従うこととの間の適切なバランスを見つけることが、進むべき道であるはずです。</p>\n</details>\n<p>データのカプセル化とは、オブジェクトの値または状態を隠すことを指します。ゲッターとセッターは、エクスポートされていないオブジェクトフィールドの上にエクスポートされたメソッドを提供することでカプセル化を可能にする手段です。</p>\n<p>Go言語では、一部の言語で見られるようなゲッターとセッターの自動サポートはありません。また、ゲッターとセッターを使用して構造体フィールドにアクセスすることは必須でも慣用的でもありません。値をもたらさない構造体のゲッターとセッターでコードを埋めるべきではありません。実利を重視し、他のプログラミングパラダイムで時には議論の余地がないと考えられている慣習に従うことと、効率性との間の適切なバランスを見つけるよう努めるべきです。</p>\n<p>Go言語は、シンプルさを含む多くの特性を考慮して設計された独自の言語であることを忘れないでください。ただし、ゲッターとセッターの必要性が見つかった場合、または前述のように、前方互換性を保証しながら将来の必要性が予測される場合は、それらを使用することに問題はありません。</p>\n<h3 id=\"5\">インタフェース汚染 (#5)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>抽象化は作成されるべきものではなく、発見されるべきものです。不必要な複雑さを避けるために、インタフェースは、必要になると予測したときではなく、必要になったときに作成するか、少なくとも抽象化が有効であることを証明できる場合に作成してください。</p>\n</details>\n<p>インタフェースは、オブジェクトの動作を指定する方法を提供します。複数のオブジェクトが実装できる共通項を抽出するために、インタフェースは使用されます。Go言語のインタフェースが大きく異なるのは、暗黙的に満たされることです。オブジェクト <code>X</code> がインタフェース <code>Y</code> を実装していることを示す <code>implements</code> のような明示的なキーワードはありません。</p>\n<p>一般に、インタフェースが価値をもたらすと考えられる主要な使用例は３つあります。それは、共通の動作を除外する、何らかの分離を作成する、および型を特定の動作に制限するというものです。ただし、このリストはすべてを網羅しているわけではなく、直面する状況によっても異なります。</p>\n<p>多くの場合、インタフェースは抽象化するために作成されます。そして、プログラミングで抽象化するときの主な注意点は、抽象化は作成されるべきではなく、発見されるべきであるということを覚えておくことです。すなわち、そうする直接の理由がない限り、コード内で抽象化すべきではないということです。インタフェースを使って設計するのではなく、具体的なニーズを待つべきです。別の言い方をすれば、インタフェースは必要になると予測したときではなく、必要になったときに作成する必要があります。\nインタフェースの過度な使用をした場合の主な問題は何でしょうか。答えは、コードフローがより複雑になることです。役に立たない間接参照を追加しても何の価値もありません。それは価値のない抽象化をすることで、コードを読み、理解し、推論することをさらに困難にします。インタフェースを追加する明確な理由がなく、インタフェースによってコードがどのように改善されるかが不明瞭な場合は、そのインタフェースの目的に異議を唱える必要があります。実装を直接呼び出すのも一つの手です。</p>\n<p>コード内で抽象化するときは注意が必要です（抽象化は作成するのではなく、発見する必要があります）。後で必要になる可能性があるものを考慮し、完璧な抽象化レベルを推測して、私たちソフトウェア開発者はコードをオーバーエンジニアリングすることがよくあります。ほとんどの場合、コードが不必要な抽象化で汚染され、読みにくくなるため、このプロセスは避けるべきです。</p>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">ロブ・パイク</p>\n<p>インタフェースでデザインするな。インタフェースを見つけ出せ。</p>\n</div>\n<p>抽象的に問題を解決しようとするのではなく、今解決すべきことを解決しましょう。最後に重要なことですが、インタフェースによってコードがどのように改善されるかが不明瞭な場合は、コードを簡素化するためにインタフェースを削除することを検討する必要があるでしょう。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/5-interface-pollution/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"6\">生産者側のインタフェース (#6)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>インタフェースをクライアント側で保持することで不必要な抽象化を回避できます。</p>\n</details>\n<p>Go言語ではインタフェースが暗黙的に満たされます。これは、明示的な実装を持つ言語と比較して大きな変化をもたらす傾向があります。ほとんどの場合、従うべきアプローチは前のセクションで説明したもの――<em>抽象化は作成するのではなく、発見する必要がある</em>――に似ています。これは、すべてのクライアントに対して特定の抽象化を強制するのは生産者の役割ではないことを意味します。代わりに、何らかの形式の抽象化が必要かどうかを判断し、そのニーズに最適な抽象化レベルを決定するのはクライアントの責任です。</p>\n<p>ほとんどの場合、インタフェースは消費者側に存在する必要があります。ただし、特定の状況（たとえば、抽象化が消費者にとって役立つことがわかっている――予測はしていない――場合）では、それを生産者側で使用したい場合があります。そうした場合、可能な限り最小限に抑え、再利用可能性を高め、より簡単に構成できるように努めるべきです。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/6-interface-producer/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"7\">インタフェースを返す (#7)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>柔軟性に問題がないようにするために、関数はほとんどの場合、インタフェースではなく具体的​​な実装を返す必要があります。逆に、関数は可能な限りインタフェースを受け入れる必要があります。</p>\n</details>\n<p>ほとんどの場合、インタフェースではなく具体的な実装を返す必要があります。そうでないとパッケージの依存関係により設計がいっそう複雑になり、すべてのクライアントが同じ抽象化に依存する必要があるため、柔軟性に欠ける可能性があります。結論は前のセクションと似ています。抽象化がクライアントにとって役立つことが（予測されるではなく）わかっている場合は、インタフェースを返すことを検討してもよいでしょう。それ以外の場合は、抽象化を強制すべきではありません。それらはクライアントによって発見される必要があります。何らかの理由でクライアントが実装を抽象化する必要がある場合でも、クライアント側でそれを行うことができます。</p>\n<h3 id=\"any-8\"><code>any</code> は何も言わない (#8)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>json.Marshal</code> など考えうるすべての型を受け入れるか返す必要がある場合にのみ <code>any</code> を使用してください。それ以外の場合、<code>any</code> は意味のある情報を提供せず、呼び出し元が任意のデータ型のメソッドを呼び出すことを許可するため、コンパイル時に問題が発生する可能性があります。</p>\n</details>\n<p><code>any</code> 型は、考えうるすべての型を受け入れるか返す必要がある場合（たとえば、マーシャリングやフォーマットの場合）に役立ちます。原則としてコードを過度に一般化することは何としても避けるべきです。コードの表現力などの他の側面が向上する場合は、コードを少し重複させたほうが良いこともあります。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/8-any/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"9\">ジェネリックスをいつ使用するべきか理解していない (#9)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>ジェネリックスと型パラメーターを利用することで、要素や動作を除外するためのボイラープレートコードを避けることができます。ただし、型パラメータは時期尚早に使用せず、具体的な必要性がわかった場合にのみ使用してください。そうでなければ、不必要な抽象化と複雑さが生じます。</p>\n</details>\n<p>セクション全文は<a href=\"../9-generics/\">こちら</a>。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/9-generics/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"10\">型の埋め込みで起こりうる問題を把握していない (#10)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>型埋め込みを使用すると、ボイラープレートコードを回避することもできます。ただし、そうすることで、一部のフィールドを非表示にしておく必要がある場合に問題が発生しないようにしてください。</p>\n</details>\n<p>構造体を作成するとき、Go言語は型を埋め込むオプションを提供します。ただし、型埋め込みの意味をすべて理解していないと、予想外の動作が発生する可能性があります。このセクションでは、型を埋め込む方法、それがもたらすもの、および考えられる問題について見ていきます。</p>\n<p>Go言語では、名前なしで宣言された構造体フィールドは、埋め込みと呼ばれます。たとえば、次のようなものです。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-4-1\"><a id=\"__codelineno-4-1\" name=\"__codelineno-4-1\" href=\"#__codelineno-4-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Foo</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-4-2\"><a id=\"__codelineno-4-2\" name=\"__codelineno-4-2\" href=\"#__codelineno-4-2\"></a><span class=\"w\">    </span><span class=\"nx\">Bar</span><span class=\"w\"> </span><span class=\"c1\">// 埋め込みフィールド</span>\n</span><span id=\"__span-4-3\"><a id=\"__codelineno-4-3\" name=\"__codelineno-4-3\" href=\"#__codelineno-4-3\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-4-4\"><a id=\"__codelineno-4-4\" name=\"__codelineno-4-4\" href=\"#__codelineno-4-4\"></a>\n</span><span id=\"__span-4-5\"><a id=\"__codelineno-4-5\" name=\"__codelineno-4-5\" href=\"#__codelineno-4-5\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Bar</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-4-6\"><a id=\"__codelineno-4-6\" name=\"__codelineno-4-6\" href=\"#__codelineno-4-6\"></a><span class=\"w\">    </span><span class=\"nx\">Baz</span><span class=\"w\"> </span><span class=\"kt\">int</span>\n</span><span id=\"__span-4-7\"><a id=\"__codelineno-4-7\" name=\"__codelineno-4-7\" href=\"#__codelineno-4-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p><code>Foo</code> 構造体では、<code>Bar</code> 型が関連付けられた名前なしで宣言されています。したがって、これは埋め込みフィールドです。</p>\n<p>埋め込みを使用することで、埋め込み型のフィールドとメソッドは昇格します。Bar には Baz フィールドが含まれているため、このフィールドは <code>Foo</code> に昇格します。したがって、Foo から Baz を利用できるようになります。</p>\n<p>型の埋め込みについて何が言えるでしょうか。まず、これが必要になることはほとんどなく、ユースケースが何であれ、おそらく型埋め込みなしでも同様に解決できることを意味します。型の埋め込みは主に利便性を目的として使用されます。ほとんどの場合、それは動作を昇格するために使用されます。</p>\n<p>型埋め込みを使用する場合は、次の 2 つの主な制約を念頭に置く必要があります。</p>\n<ul>\n<li>フィールドへのアクセスを簡素化するための糖衣構文としてのみ使用しないでください（ <code>Foo.Bar.Baz()</code> の代わりに <code>Foo.Baz()</code> など）。 これが唯一の根拠である場合は、内部型を埋め込まず、代わりにフィールドを使いましょう。</li>\n<li>外部から隠したいデータ（フィールド）や動作（メソッド）を昇格してはなりません。たとえば、構造体に対してプライベートなままにしておく必要があるロック動作にクライアントがアクセスできるようにする場合などです。</li>\n</ul>\n<p>これらの制約を念頭に置いて型埋め込みを意識的に使用すると、追加の転送メソッドによるボイラープレートコードを回避するのに役立ちます。ただし、見た目だけを目的としたり、隠すべき要素を昇格したりしないように注意しましょう。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/10-type-embedding/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"functional-options-11\">Functional Options パターンを使用していない (#11)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>API に適した方法でオプションを便利に処理するには、Functional Options パターンを使用しましょう。</p>\n</details>\n<p>さまざまな実装方法が存在し、多少の違いはありますが、主な考え方は次のとおりです。</p>\n<ul>\n<li>未エクスポートの構造体はオプション設定を保持します。</li>\n<li>各オプションは同じ型、<code>type Option func(options *options)</code> エラーを返す関数です。たとえば、<code>WithPort</code> はポートを表す <code>int</code> 引数を受け取り、<code>options</code> 構造体の更新方法を表す <code>Option</code> 型を返します。</li>\n</ul>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/options.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/options.png\"></a></p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-5-1\"><a id=\"__codelineno-5-1\" name=\"__codelineno-5-1\" href=\"#__codelineno-5-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">options</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-2\"><a id=\"__codelineno-5-2\" name=\"__codelineno-5-2\" href=\"#__codelineno-5-2\"></a><span class=\"w\">  </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"kt\">int</span>\n</span><span id=\"__span-5-3\"><a id=\"__codelineno-5-3\" name=\"__codelineno-5-3\" href=\"#__codelineno-5-3\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-5-4\"><a id=\"__codelineno-5-4\" name=\"__codelineno-5-4\" href=\"#__codelineno-5-4\"></a>\n</span><span id=\"__span-5-5\"><a id=\"__codelineno-5-5\" name=\"__codelineno-5-5\" href=\"#__codelineno-5-5\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Option</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">(</span><span class=\"nx\">options</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">options</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span>\n</span><span id=\"__span-5-6\"><a id=\"__codelineno-5-6\" name=\"__codelineno-5-6\" href=\"#__codelineno-5-6\"></a>\n</span><span id=\"__span-5-7\"><a id=\"__codelineno-5-7\" name=\"__codelineno-5-7\" href=\"#__codelineno-5-7\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">WithPort</span><span class=\"p\">(</span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">Option</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-8\"><a id=\"__codelineno-5-8\" name=\"__codelineno-5-8\" href=\"#__codelineno-5-8\"></a><span class=\"w\">  </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">(</span><span class=\"nx\">options</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">options</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-9\"><a id=\"__codelineno-5-9\" name=\"__codelineno-5-9\" href=\"#__codelineno-5-9\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-10\"><a id=\"__codelineno-5-10\" name=\"__codelineno-5-10\" href=\"#__codelineno-5-10\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">errors</span><span class=\"p\">.</span><span class=\"nx\">New</span><span class=\"p\">(</span><span class=\"s\">\"port should be positive\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-5-11\"><a id=\"__codelineno-5-11\" name=\"__codelineno-5-11\" href=\"#__codelineno-5-11\"></a><span class=\"w\">  </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-12\"><a id=\"__codelineno-5-12\" name=\"__codelineno-5-12\" href=\"#__codelineno-5-12\"></a><span class=\"w\">  </span><span class=\"nx\">options</span><span class=\"p\">.</span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"o\">&amp;</span><span class=\"nx\">port</span>\n</span><span id=\"__span-5-13\"><a id=\"__codelineno-5-13\" name=\"__codelineno-5-13\" href=\"#__codelineno-5-13\"></a><span class=\"w\">  </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-5-14\"><a id=\"__codelineno-5-14\" name=\"__codelineno-5-14\" href=\"#__codelineno-5-14\"></a><span class=\"w\">  </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-15\"><a id=\"__codelineno-5-15\" name=\"__codelineno-5-15\" href=\"#__codelineno-5-15\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-5-16\"><a id=\"__codelineno-5-16\" name=\"__codelineno-5-16\" href=\"#__codelineno-5-16\"></a>\n</span><span id=\"__span-5-17\"><a id=\"__codelineno-5-17\" name=\"__codelineno-5-17\" href=\"#__codelineno-5-17\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">NewServer</span><span class=\"p\">(</span><span class=\"nx\">addr</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">opts</span><span class=\"w\"> </span><span class=\"o\">...</span><span class=\"nx\">Option</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Server</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-18\"><a id=\"__codelineno-5-18\" name=\"__codelineno-5-18\" href=\"#__codelineno-5-18\"></a><span class=\"w\">  </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">options</span><span class=\"w\"> </span><span class=\"nx\">options</span>\n</span><span id=\"__span-5-19\"><a id=\"__codelineno-5-19\" name=\"__codelineno-5-19\" href=\"#__codelineno-5-19\"></a><span class=\"w\">  </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">opt</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">opts</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span>\n</span><span id=\"__span-5-20\"><a id=\"__codelineno-5-20\" name=\"__codelineno-5-20\" href=\"#__codelineno-5-20\"></a><span class=\"w\">    </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">opt</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">options</span><span class=\"p\">)</span><span class=\"w\"> </span>\n</span><span id=\"__span-5-21\"><a id=\"__codelineno-5-21\" name=\"__codelineno-5-21\" href=\"#__codelineno-5-21\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-22\"><a id=\"__codelineno-5-22\" name=\"__codelineno-5-22\" href=\"#__codelineno-5-22\"></a><span class=\"w\">      </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-5-23\"><a id=\"__codelineno-5-23\" name=\"__codelineno-5-23\" href=\"#__codelineno-5-23\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-24\"><a id=\"__codelineno-5-24\" name=\"__codelineno-5-24\" href=\"#__codelineno-5-24\"></a><span class=\"w\">  </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-25\"><a id=\"__codelineno-5-25\" name=\"__codelineno-5-25\" href=\"#__codelineno-5-25\"></a>\n</span><span id=\"__span-5-26\"><a id=\"__codelineno-5-26\" name=\"__codelineno-5-26\" href=\"#__codelineno-5-26\"></a><span class=\"c1\">// この段階で、options 構造体が構築され、構成が含まれます。</span>\n</span><span id=\"__span-5-27\"><a id=\"__codelineno-5-27\" name=\"__codelineno-5-27\" href=\"#__codelineno-5-27\"></a><span class=\"c1\">// したがって、ポート設定に関連するロジックを実装できます。</span>\n</span><span id=\"__span-5-28\"><a id=\"__codelineno-5-28\" name=\"__codelineno-5-28\" href=\"#__codelineno-5-28\"></a><span class=\"w\">  </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"kt\">int</span>\n</span><span id=\"__span-5-29\"><a id=\"__codelineno-5-29\" name=\"__codelineno-5-29\" href=\"#__codelineno-5-29\"></a><span class=\"w\">  </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">options</span><span class=\"p\">.</span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"o\">==</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-30\"><a id=\"__codelineno-5-30\" name=\"__codelineno-5-30\" href=\"#__codelineno-5-30\"></a><span class=\"w\">    </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">defaultHTTPPort</span>\n</span><span id=\"__span-5-31\"><a id=\"__codelineno-5-31\" name=\"__codelineno-5-31\" href=\"#__codelineno-5-31\"></a><span class=\"w\">  </span><span class=\"p\">}</span><span class=\"w\"> </span><span class=\"k\">else</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-32\"><a id=\"__codelineno-5-32\" name=\"__codelineno-5-32\" href=\"#__codelineno-5-32\"></a><span class=\"w\">      </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">options</span><span class=\"p\">.</span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"o\">==</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-33\"><a id=\"__codelineno-5-33\" name=\"__codelineno-5-33\" href=\"#__codelineno-5-33\"></a><span class=\"w\">      </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">randomPort</span><span class=\"p\">()</span>\n</span><span id=\"__span-5-34\"><a id=\"__codelineno-5-34\" name=\"__codelineno-5-34\" href=\"#__codelineno-5-34\"></a><span class=\"w\">    </span><span class=\"p\">}</span><span class=\"w\"> </span><span class=\"k\">else</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-35\"><a id=\"__codelineno-5-35\" name=\"__codelineno-5-35\" href=\"#__codelineno-5-35\"></a><span class=\"w\">      </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">options</span><span class=\"p\">.</span><span class=\"nx\">port</span>\n</span><span id=\"__span-5-36\"><a id=\"__codelineno-5-36\" name=\"__codelineno-5-36\" href=\"#__codelineno-5-36\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-37\"><a id=\"__codelineno-5-37\" name=\"__codelineno-5-37\" href=\"#__codelineno-5-37\"></a><span class=\"w\">  </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-38\"><a id=\"__codelineno-5-38\" name=\"__codelineno-5-38\" href=\"#__codelineno-5-38\"></a>\n</span><span id=\"__span-5-39\"><a id=\"__codelineno-5-39\" name=\"__codelineno-5-39\" href=\"#__codelineno-5-39\"></a><span class=\"w\">  </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-5-40\"><a id=\"__codelineno-5-40\" name=\"__codelineno-5-40\" href=\"#__codelineno-5-40\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Functional Options パターンは、オプションを処理するための手軽で API フレンドリーな方法を提供します。 Builder パターンは有効なオプションですが、いくつかの小さな欠点（空の可能性がある構成構造体を渡さなければならない、またはエラーを処理する方法があまり便利ではない）があり、この種の問題において Functional Options パターンがGo言語における慣用的な対処方法になる傾向があります。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/11-functional-options/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"12\">誤ったプロジェクト構成 (プロジェクト構造とパッケージ構成) (#12)</h3>\n<p>全体的な構成に関しては、さまざまな考え方があります。たとえば、アプリケーションをコンテキストごとに整理すべきか、それともレイヤーごとに整理すべきか、それは好みによって異なります。コンテキスト（顧客コンテキスト、契約コンテキストなど）ごとにコードをグループ化することを選ぶ場合もあれば、六角形のアーキテクチャ原則に従うことと、技術層ごとにグループ化することを選ぶ場合もあります。私たちが行う決定が一貫している限り、それがユースケースに適合するなら、それが間違っていることはありません。</p>\n<p>パッケージに関しては、従うべきベストプラクティスが複数あります。まず、プロジェクトが過度に複雑になる可能性があるため、時期尚早なパッケージ化は避けるべきです。場合によっては、完璧な構造を最初から無理に作ろうとするよりも、単純な構成を使用し、その内容を理解した上でプロジェクトを発展させるほうが良い場合があります。\n粒度も考慮すべき重要な点です。 1 つまたは 2 つのファイルだけを含む数十のナノパッケージを作成することは避けるべきです。その場合、おそらくこれらのパッケージ間の論理的な接続の一部が抜け落ち、読み手にとってプロジェクトが理解しにくくなるからです。逆に、パッケージ名の意味を薄めるような巨大なパッケージも避けるべきです。</p>\n<p>パッケージの名前付けも注意して行う必要があります。（開発者なら）誰もが知っているように、名前を付けるのは難しいです。クライアントが Go プロジェクトを理解しやすいように、パッケージに含まれるものではなく、提供するものに基づいてパッケージに名前を付ける必要があります。また、ネーミングには意味のあるものを付ける必要があります。したがって、パッケージ名は短く、簡潔で、表現力豊かで、慣例により単一の小文字にする必要があります。</p>\n<p>何をエクスポートするかについてのルールは非常に簡単です。パッケージ間の結合を減らし、エクスポートされる不要な要素を非表示にするために、エクスポートする必要があるものをできる限り最小限に抑える必要があります。要素をエクスポートするかどうか不明な場合は、デフォルトでエクスポートしないようにする必要があります。後でエクスポートする必要があることが判明した場合は、コードを調整できます。また、構造体を encoding/json でアンマーシャリングできるようにフィールドをエクスポートするなど、いくつかの例外にも留意してください。</p>\n<p>プロジェクトを構成するのは簡単ではありませんが、これらのルールに従うことで維持が容易になります。ただし、保守性を容易にするためには一貫性も重要であることに注意してください。したがって、コードベース内で可能な限り一貫性を保つようにしましょう。</p>\n<details class=\"note\" open=\"open\">\n<summary>補足</summary>\n<p>Go チームは Go プロジェクトの組織化/構造化に関する公式ガイドラインを 2023 年に発行しました： <a href=\"https://go.dev/doc/modules/layout\">go.dev/doc/modules/layout</a></p>\n</details>\n<h3 id=\"13\">ユーティリティパッケージの作成 (#13)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>名前付けはアプリケーション設計の重要な部分です。<code>common</code> 、<code>util</code> 、<code>shared</code> のようなパッケージを作成しても、読み手にそれほどの価値をもたらしません。このようなパッケージを意味のある具体的なパッケージ名にリファクタリングしましょう。</p>\n</details>\n<p>また、パッケージに含まれるものではなく、パッケージが提供するものに基づいてパッケージに名前を付けると、その表現力を高める効率的な方法になることにも留意してください。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/13-utility-packages/stringset.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"14\">パッケージ名の衝突を無視する (#14)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>混乱、さらにはバグにつながりかねない、変数とパッケージ間の名前の衝突を回避するために、それぞれに一意の名前を使用しましょう。これが不可能な場合は、インポートエイリアスを使用して修飾子を変更してパッケージ名と変数名を区別するか、より良い名前を考えてください。</p>\n</details>\n<p>パッケージの衝突は、変数名が既存のパッケージ名と衝突する場合に発生し、パッケージの再利用が妨げられます。曖昧さを避けるために、変数名の衝突を防ぐ必要があります。衝突が発生した場合は、別の意味のある名前を見つけるか、インポートエイリアスを使用する必要があります。</p>\n<h3 id=\"15\">コードの文章化が行われていない (#15)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>クライアントとメンテナがコードの意図を理解できるように、エクスポートされた要素を文章化しましょう。</p>\n</details>\n<p>文章化はコーディングの重要な側面です。これにより、クライアントが API をより簡単に使用することができますが、プロジェクトの維持にも役立ちます。Go言語では、コードを慣用的なものにするために、いくつかのルールに従う必要があります。</p>\n<p>まず、エクスポートされたすべての要素を文章化する必要があります。構造、インタフェース、関数など、エクスポートする場合は文章化する必要があります。慣例として、エクスポートされた要素の名前から始まるコメントを追加します。</p>\n<p>慣例として、各コメントは句読点で終わる完全な文である必要があります。また、関数（またはメソッド）を文章化するときは、関数がどのように実行するかではなく、その関数が何を実行するつもりであるかを強調する必要があることにも留意してください。これはドキュメントではなく、関数とコメントについてです。ドキュメントは理想的には、利用者がエクスポートされた要素の使用方法を理解するためにコードを見る必要がないほど十分な情報を提供する必要があります。</p>\n<p>変数または定数を文章化する場合、その目的と内容という 2 つの側面を伝えることが重要かもしれません。前者は、外部クライアントにとって役立つように、コードドキュメントとして存在する必要があります。ただし、後者は必ずしも公開されるべきではありません。</p>\n<p>クライアントとメンテナがパッケージの目的を理解できるように、各パッケージをドキュメントする必要もあります。慣例として、コメントは <code>//Package</code> で始まり、その後にパッケージ名が続きます。パッケージコメントの最初の行は、パッケージに表示されるため簡潔にする必要があります。そして、次の行に必要な情報をすべて入力します。</p>\n<p>コードを文章化することが制約になるべきではありません。クライアントやメンテナがコードの意図を理解するのに役立つ必要があります。</p>\n<h3 id=\"16\">リンターを使用してない (#16)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>コードの品質と一貫性を向上させるには、リンターとフォーマッターを使用しましょう</p>\n</details>\n<p>リンターは、コードを分析してエラーを検出する自動ツールです。このセクションの目的は、既存のリンターの完全なリストを提供することではありません。そうした場合、すぐに使い物にならなくなってしまうからです。ただし、ほとんどの Go プロジェクトにリンターが不可欠であるということは理解し、覚えておきましょう。</p>\n<ul>\n<li><a href=\"https://golang.org/cmd/vet\">https://golang.org/cmd/vet</a>――Go言語の標準コードアナライザー</li>\n<li><a href=\"https://github.com/kisielk/errcheck\">https://github.com/kisielk/errcheck</a>――エラーチェッカー</li>\n<li><a href=\"https://github.com/fzipp/gocyclo\">https://github.com/fzipp/gocyclo</a>――循環的複雑度アナライザー</li>\n<li><a href=\"https://github.com/jgautheron/goconst\">https://github.com/jgautheron/goconst</a>――複数回使用文字列アナライザー</li>\n</ul>\n<p>リンターのほかに、コードスタイルを修正するためにコードフォーマッターも使用しましょう。以下に、いくつかのコードフォーマッターを示します。</p>\n<ul>\n<li><a href=\"https://golang.org/cmd/gofmt\">https://golang.org/cmd/gofmt</a>――Go言語の標準コードフォーマッター</li>\n<li><a href=\"https://godoc.org/golang.org/x/tools/cmd/goimports\">https://godoc.org/golang.org/x/tools/cmd/goimports</a>――Go言語の標準インポートフォーマッター</li>\n</ul>\n<p>ほかに golangci-lint (<a href=\"https://github.com/golangci/golangci-lint\">https://github.com/golangci/golangci-lint</a>) というものがあります。これは、多くの便利なリンターやフォーマッターの上にファサードを提供するリンティングツールです。また、リンターを並列実行して分析速度を向上させることができ、非常に便利です。</p>\n<p>リンターとフォーマッターは、コードベースの品質と一貫性を向上させる強力な方法です。時間をかけてどれを使用すべきかを理解し、それらの実行（ CI や Git プリコミットフックなど）を自動化しましょう。</p>\n<h2 id=\"_2\">データ型</h2>\n<h3 id=\"8-17\">8 進数リテラルで混乱を招いてしまう (#17)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>既存のコードを読むときは、 <code>0</code> で始まる整数リテラルが 8 進数であることに留意してください。また、接頭辞 <code>0o</code> を付けることで8進数であることを明確にし、読みやすさを向上させましょう。</p>\n</details>\n<p>8 進数は 0 で始まります（たとえば、<code>010</code> は 10 進数の 8 に相当します）。可読性を向上させ、将来のコードリーダーの潜在的な間違いを回避するには、 <code>0o</code> 接頭辞を使用して 8 進数であることを明らかにしましょう（例: <code>0o10</code> ）。</p>\n<p>他の整数リテラル表現にも注意してください。 </p>\n<ul>\n<li><em>バイナリ</em> - 接頭辞 <code>0b</code> あるいは <code>0B</code> を使用します（たとえば、 <code>0b</code> は 10 進数の 4 に相当します）</li>\n<li><em>16進数</em> - 接頭辞 <code>0x</code> あるいは <code>0X</code> を使用します（たとえば、 <code>0xF</code> は 10 進数の 15 に相当します）。 </li>\n<li><em>虚数</em> - 接尾辞 <code>i</code> を使用します（たとえば、 <code>3i</code> ）</li>\n</ul>\n<p>読みやすくするために、区切り文字としてアンダースコア（ _ ）を使用することもできます。たとえば、 10 億は <code>1_000_000_000</code> のように書くことができます。アンダースコアは <code>0b)00_00_01</code> のように他の表現と併用することもできます。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/17-octal-literals/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"18\">整数オーバーフローを無視している (#18)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>Go言語では整数のオーバーフローとアンダーフローが裏側で処理されるため、それらをキャッチする独自の関数を実装できます。</p>\n</details>\n<p>Go言語では、コンパイル時に検出できる整数オーバーフローによってコンパイルエラーが生成されます。たとえば、次のようになります。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-6-1\"><a id=\"__codelineno-6-1\" name=\"__codelineno-6-1\" href=\"#__codelineno-6-1\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">counter</span><span class=\"w\"> </span><span class=\"kt\">int32</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">math</span><span class=\"p\">.</span><span class=\"nx\">MaxInt32</span><span class=\"w\"> </span><span class=\"o\">+</span><span class=\"w\"> </span><span class=\"mi\">1</span>\n</span></code></pre></div>\n<div class=\"language-shell highlight\"><pre><span></span><code><span id=\"__span-7-1\"><a id=\"__codelineno-7-1\" name=\"__codelineno-7-1\" href=\"#__codelineno-7-1\"></a>constant<span class=\"w\"> </span><span class=\"m\">2147483648</span><span class=\"w\"> </span>overflows<span class=\"w\"> </span>int32\n</span></code></pre></div>\n<p>ただし、実行時には、整数のオーバーフローまたはアンダーフローは発生しません。これによってアプリケーションのパニックが発生することはありません。この動作はやっかいなバグ（たとえば、負の結果につながる整数の増分や正の整数の加算など）につながる可能性があるため、頭に入れておくことが重要です。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/18-integer-overflows\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"19\">浮動小数点を理解していない (#19)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>特定のデルタ内で浮動小数点比較を行うと、コードの移植性を確保できます。加算または減算を実行するときは、精度を向上させるために、同程度の大きさの演算をグループ化してください。また、乗算と除算は加算と減算の前に実行してください。</p>\n</details>\n<p>Go言語には、（虚数を除いた場合） <code>float32</code> と <code>float64</code> という 2 つの浮動小数点型があります。浮動小数点の概念は、小数値を表現できないという整数の大きな問題を解決するために発明されました。予想外の事態を避けるために、浮動小数点演算は実際の演算の近似であることを知っておく必要があります。 </p>\n<p>そのために、乗算の例を見てみましょう。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-8-1\"><a id=\"__codelineno-8-1\" name=\"__codelineno-8-1\" href=\"#__codelineno-8-1\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">n</span><span class=\"w\"> </span><span class=\"kt\">float32</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"mf\">1.0001</span>\n</span><span id=\"__span-8-2\"><a id=\"__codelineno-8-2\" name=\"__codelineno-8-2\" href=\"#__codelineno-8-2\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">n</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"w\"> </span><span class=\"nx\">n</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>このコードにおいては 1.0001 * 1.0001 = 1.00020001 という結果が出力されることを期待すると思います。しかしながら、ほとんどの x86 プロセッサでは、代わりに 1.0002 が出力されます。 </p>\n<p>Go言語の <code>float32</code> および <code>float64</code> 型は近似値であるため、いくつかのルールを念頭に置く必要があります。</p>\n<ul>\n<li>2 つの浮動小数点数を比較する場合は、その差が許容範囲内であることを確認する。</li>\n<li>加算または減算を実行する場合、精度を高めるために、同じ桁数の演算をグループ化する。</li>\n<li>精度を高めるため、一連の演算で加算、減算、乗算、除算が必要な場合は、乗算と除算を最初に実行する。</li>\n</ul>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/19-floating-points/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"20\">スライスの長さと容量を理解していない (#20)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>Go 開発者ならば、スライスの長さと容量の違いを理解するべきです。スライスの長さはスライス内の使用可能な要素の数であり、スライスの容量はバッキング配列内の要素の数です。</p>\n</details>\n<p>セクション全文は<a href=\"../20-slice/\">こちら</a>。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/20-slice-length-cap/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"21\">非効率なスライスの初期化 (#21)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>スライスを作成するとき、長さがすでにわかっている場合は、指定された長さまたは容量でスライスを初期化しましょう。これにより、割り当ての数が減り、パフォーマンスが向上します。</p>\n</details>\n<p><code>make</code> を使用してスライスを初期化するときに、長さとオプションの容量を指定できます。これらのパラメータの両方に適切な値を渡すことが適当であるにもかかわらず、それを忘れるのはよくある間違いです。実際、複数のコピーが必要になり、一時的なバッキング配列をクリーンアップするために <abbr title=\"Garbage Collector\">GC</abbr> に追加の労力がかかる可能性があります。パフォーマンスの観点から言えば、Go ランタイムに手を差し伸べない理由はありません。 </p>\n<p>オプションは、指定された容量または指定された長さのスライスを割り当てることです。 これら 2 つの解決策のうち、2 番目の解決策の方がわずかに高速である傾向があることがわかりました。ただし、特定の容量と追加を使用すると、場合によっては実装と読み取りが容易になることがあります。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/21-slice-init/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"nil-22\">nil と空のスライスを混同している (#22)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>encoding/json</code> や <code>reflect</code> パッケージなどを使用するときによくある混乱を避けるためには、nil スライスと空のスライスの違いを理解する必要があります。どちらも長さゼロ、容量ゼロのスライスですが、割り当てを必要としないのは nil スライスだけです。</p>\n</details>\n<p>Go言語では、nil と空のスライスは区別されます。nil スライスは <code>nil</code> に等しいのに対し、空のスライスの長さはゼロです。nil スライスは空ですが、空のスライスは必ずしも<code>nil</code> であるとは限りません。一方、nil スライスには割り当ては必要ありません。このセクション全体を通して、以下の方法を使用することによって、状況に応じてスライスを初期化することを見てきました。</p>\n<ul>\n<li>最終的な長さが不明でスライスが空の場合は <code>var s []string</code> </li>\n<li>nil と空のスライスを作成する糖衣構文としての <code>[]string(nil)</code> </li>\n<li>将来の長さがわかっている場合は <code>make([]string, length)</code> </li>\n</ul>\n<p>要素なしでスライスを初期化する場合、最後のオプション <code>[]string{}</code> は避けるべきです。最後に、予想外の動作を防ぐために、使用するライブラリが nil と空のスライスを区別しているかどうかを確認してみましょう。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/22-nil-empty-slice/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"23\">スライスが空かどうかを適切に確認しない (#23)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>スライスに要素が含まれていないことを確認するには、その長さを確認しましょう。これは、スライスが <code>nil</code> であるか空であるかに関係なく機能します。マップについても同様です。明確な API を設計するには、nil スライスと空のスライスを区別しないでください。</p>\n</details>\n<p>スライスに要素があるかどうかを判断するには、スライスが nil かどうか、またはその長さが 0 に等しいかどうかを確認することで判断できます。スライスが空である場合とスライスが nil である場合の両方をカバーできるため、長さを確かめることが最良の方法です。</p>\n<p>一方、インタフェースを設計するときは、軽微なプログラミングエラーを起こさないよう nil スライスと空のスライスを区別しないようにする必要があります。スライスを返すときに、nil または空のスライスを返すかどうかは、意味的にも技術的にも違いはありません。コーラーにとってはどちらも同じことを意味するはずです。この原理はマップでも同じです。マップが空かどうかを確認するには、それが nil かどうかではなく、その長さを確認しましょう。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/23-checking-slice-empty/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"24\">スライスのコピーを正しく作成していない (#24)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>組み込み関数 <code>copy</code> を使用してあるスライスを別のスライスにコピーするには、コピーされる要素の数が 2 つのスライスの長さの間の最小値に相当することに注意してください。</p>\n</details>\n<p>要素をあるスライスから別のスライスにコピーする操作は、かなり頻繁に行われます。コピーを使用する場合、コピー先にコピーされる要素の数は 2 つのスライスの長さの間の最小値に相当することに注意する必要があります。また、スライスをコピーするための他の代替手段が存在することにも留意してください。そのため、コードベースでそれらを見つけても驚くことはありません。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/24-slice-copy/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"append-25\"><code>append</code> の使用による予想外の副作用 (#25)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>2つの異なる関数が同じ配列に基づくスライスを使用する場合に、copy または完全スライス式を使用することで <code>append</code> による衝突を防ぐことができます。ただし、大きなスライスを縮小する場合、メモリリークを防ぐことができるのはスライスのコピーだけです。</p>\n</details>\n<p>スライスを使用するときは、予想外の副作用につながる状況に直面する可能性があることを覚えておく必要があります。結果のスライスの長さがその容量より小さい場合、追加によって元のスライスが変更される可能性があります。起こり得る副作用の範囲を制限したい場合は、スライスのコピーまたは完全スライス式を使用できます。これにより、コピーを実行できなくなります。</p>\n<details class=\"note\" open=\"open\">\n<summary>補足</summary>\n<p><code>s[low:high:max]</code>（完全スライス式）――この命令文は、容量が <code>max - low</code> に等しいことを除けば、<code>s[low:high]</code> で作成されたスライスと同様のスライスを作成します。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/25-slice-append/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"26\">スライスとメモリリーク (#26)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>ポインタのスライスまたはポインタフィールドを持つ構造体を操作する場合、スライス操作によって除外された要素を nil とすることでメモリリークを回避できます。</p>\n</details>\n<h4 id=\"_3\">容量漏れ</h4>\n<p>大きなスライスまたは配列をスライスすると、メモリ消費が高くなる可能性があることに注意してください。残りのスペースは <abbr title=\"Garbage Collector\">GC</abbr> によって再利用されず、少数の要素しか使用しないにもかかわらず、大きなバッキング配列が保持されます。スライスのコピーをすることで、このような事態を防ぐことができます。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/26-slice-memory-leak/capacity-leak\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h4 id=\"_4\">スライスとポインタ</h4>\n<p>ポインタまたはポインタフィールドを含む構造体を使用してスライス操作をする場合、<abbr title=\"Garbage Collector\">GC</abbr> がこれらの要素を再利用しないことを知っておく必要があります。その場合の選択肢は、コピーを実行するか、残りの要素またはそのフィールドを明示的に <code>nil</code> とすることです。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/26-slice-memory-leak/slice-pointers\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"27\">非効率なマップの初期化 (#27)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>マップを作成するとき、その長さがすでにわかっている場合は、指定された長さで初期化します。これにより、割り当ての数が減り、パフォーマンスが向上します。</p>\n</details>\n<p>マップは、キー・値ペアの順序なしコレクションを提供します。なお、それぞれのペアは固有のキーを持ちます。Go言語では、マップはハッシュテーブルデータ構造に基づいています。内部的には、ハッシュテーブルはバケットの配列であり、各バケットはキー・値ペアの配列へのポインタです。 </p>\n<p>マップに含まれる要素の数が事前にわかっている場合は、その初期サイズを指定して作成する必要があります。マップの増大は、十分なスペースを再割り当てし、すべての要素のバランスを再調整する必要があるため、計算量が非常に多くなりますが、これによりそれを回避することができます。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/27-map-init/main_test.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"28\">マップとメモリリーク (#28)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>マップはメモリ内で常に増大する可能性がありますが、縮小することはありません。したがって、メモリの問題が発生する場合は、マップを強制的に再生成したり、ポインタを使用したりするなど、さまざまな手段を試すことができます。</p>\n</details>\n<p>セクション全文は<a href=\"../28-maps-memory-leaks/\">こちら</a>。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/28-map-memory-leak/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"29\">誤った方法による値の比較 (#29)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>Go言語で型を比較す​​るには、2 つの型が比較可能ならば、== 演算子と != 演算子を使用できます。真偽値、数値、文字列、ポインタ、チャネル、および構造体が完全に比較可能な型で構成されています。それ以外は、 <code>reflect.DeepEqual</code> を使用してリフレクションの代償を支払うか、独自の実装とライブラリを使用することができます。</p>\n</details>\n<p>効果的に比較するには、 <code>==</code> と <code>!=</code> の使用方法を理解することが不可欠です。これらの演算子は、比較可能な被演算子で使用できます。 </p>\n<ul>\n<li><em>真偽値</em> - 2 つの真偽値が等しいかどうかを比較します。 </li>\n<li><em>数値 (int、float、および complex 型)</em> - 2 つの数値が等しいかどうかを比較します。 </li>\n<li><em>文字列</em> - 2 つの文字列が等しいかどうかを比較します。 </li>\n<li><em>チャネル</em> - 2 つのチャネルが同じ make 呼び出しによって作成されたか、または両方が nil であるかを比較します。 </li>\n<li><em>インタフェース</em> - 2 つのインタフェースが同じ動的タイプと等しい動的値を持つかどうか、または両方が nil であるかどうかを比較します。 </li>\n<li><em>ポインタ</em> - 2 つのポインタがメモリ内の同じ値を指しているか、または両方とも nil であるかを比較します。 </li>\n<li><em>構造体と配列</em> - 類似した型で構成されているかどうかを比較します。</li>\n</ul>\n<details class=\"note\" open=\"open\">\n<summary>補足</summary>\n<p><code>?</code> 、 <code>&gt;=</code> 、 <code>&lt;</code> 、および <code>&gt;</code> 演算子を数値型で使用して値を比較したり、文字列で字句順序を比較したりすることもできます。</p>\n</details>\n<p>被演算子が比較できない場合（スライスとマップなど）、リフレクションなどの他の方法を利用する必要があります。リフレクションはメタプログラミングの一種であり、アプリケーションがその構造と動作を内省して変更する機能を指します。たとえば、Go言語では <code>reflect.DeepEqual</code> を使用できます。この関数は、2つの値を再帰的に調べることによって、2つの要素が完全に等しいかどうかを報告します。受け入れられる要素は、基本型に加えて、配列、構造体、スライス、マップ、ポインタ、インタフェース、関数です。しかし、最大の落とし穴はパフォーマンス上のペナルティです。 </p>\n<p>実行時のパフォーマンスが重要な場合は、独自のメソッドを実装することが最善となる可能性があります。</p>\n<p>追記：標準ライブラリには既に比較メソッドがいくつかあることを覚えておく必要があります。たとえば、最適化された <code>bytes.Compare</code> 関数を使用して、2つのバイトスライスを比較できます。独自のメソッドを実装する前に、車輪の再発明をしないようにしましょう。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/29-comparing-values/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h2 id=\"_5\">制御構造</h2>\n<h3 id=\"range-30\">要素が <code>range</code> ループ内でコピーされることを知らない  (#30)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>range</code> ループ内の value 要素はコピーです。したがって、たとえば構造体を変更するには、そのインデックスを介してアクセスするか、従来の <code>for</code> ループを介してアクセスしましょう（変更する要素またはフィールドがポインタである場合を除く）。</p>\n</details>\n<p>range ループを使用すると、さまざまなデータ構造に反復処理を行うことができます。 </p>\n<ul>\n<li>文字列</li>\n<li>配列</li>\n<li>配列へのポインタ</li>\n<li>スライス</li>\n<li>マップ</li>\n<li>受信チャネル </li>\n</ul>\n<p>古典的な <code>for</code> ループと比較すると、<code>range</code> ループはその簡潔な構文のおかげで、これらのデータ構造のすべての要素に反復処理をするのに便利です。</p>\n<p>ただし、range ループ内の値要素はコピーであることを覚えておく必要があります。したがって、値を変更する必要がある構造体の場合、変更する値またはフィールドがポインタでない限り、要素自体ではなくコピーのみを更新します。range ループまたは従来の for ループを使用してインデックス経由で要素にアクセスすることが推奨されます。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/30-range-loop-element-copied/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"range-31\"><code>range</code> ループ（チャネルと配列）での引数の評価方法を知らない (#31)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>range</code> 演算子に渡される式はループの開始前に 1 回だけ評価されることを理解すると、チャネルまたはスライスの反復処理における非効率な割り当てなどのありがちな間違いを回避できます。</p>\n</details>\n<p>range ループは、（タイプに関係なく）コピーを実行することにより、ループの開始前に、指定された式を 1 回だけ評価します。たとえば、誤った要素にアクセスしてしまう、というようなありがちな間違いを避けるために、この動作を覚えておく必要があります。たとえば</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-9-1\"><a id=\"__codelineno-9-1\" name=\"__codelineno-9-1\" href=\"#__codelineno-9-1\"></a><span class=\"nx\">a</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">]</span><span class=\"kt\">int</span><span class=\"p\">{</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"p\">}</span>\n</span><span id=\"__span-9-2\"><a id=\"__codelineno-9-2\" name=\"__codelineno-9-2\" href=\"#__codelineno-9-2\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">a</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-9-3\"><a id=\"__codelineno-9-3\" name=\"__codelineno-9-3\" href=\"#__codelineno-9-3\"></a><span class=\"w\">    </span><span class=\"nx\">a</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">]</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"mi\">10</span>\n</span><span id=\"__span-9-4\"><a id=\"__codelineno-9-4\" name=\"__codelineno-9-4\" href=\"#__codelineno-9-4\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">==</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-9-5\"><a id=\"__codelineno-9-5\" name=\"__codelineno-9-5\" href=\"#__codelineno-9-5\"></a><span class=\"w\">        </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">v</span><span class=\"p\">)</span>\n</span><span id=\"__span-9-6\"><a id=\"__codelineno-9-6\" name=\"__codelineno-9-6\" href=\"#__codelineno-9-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-9-7\"><a id=\"__codelineno-9-7\" name=\"__codelineno-9-7\" href=\"#__codelineno-9-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>このコードは、最後のインデックスを 10 に更新します。しかし、このコードを実行すると、10 は出力されません。 2 が出力されます。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/31-range-loop-arg-evaluation/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"range-32\"><code>range</code> ループ内におけるポインタ要素の使用が及ぼす影響を分かっていない (#32)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>ローカル変数を使用するか、インデックスを使用して要素にアクセスすると、ループ内でポインタをコピーする際の間違いを防ぐことができます。</p>\n</details>\n<p><code>range</code> ループを使用してデータ構造に反復処理を施す場合、すべての値が単一の一意のアドレスを持つ一意の変数に割り当てられることを思い出してください。ゆえに、各反復処理中にこの変数を参照するポインタを保存すると、同じ要素、つまり最新の要素を参照する同じポインタを保存することになります。この問題は、ループのスコープ内にローカル変数を強制的に作成するか、インデックスを介してスライス要素を参照するポインタを作成することで解決できます。どちらの解決策でも問題ありません。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/32-range-loop-pointers/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"33\">マップの反復処理中に誤った仮定をする（反復処理中の順序付けとマップの挿入） (#33)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>マップを使用するときに予測可能な出力を保証するには、マップのデータ構造が次のとおりであることに注意してください。 </p>\n</details>\n<ul>\n<li>データをキーで並べ替えません </li>\n<li>挿入順序は保持されません </li>\n<li>反復処理順序は決まっていません</li>\n<li>ある反復処理中に追加された要素がその処理中に生成されることを保証しません</li>\n</ul>\n<!-- TODO -->\n\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/33-map-iteration/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"break-34\"><code>break</code> 文がどのように機能するかを分かっていない (#34)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>ラベルと <code>break</code> または <code>continue</code> の併用は、特定の命令文を強制的に中断します。これは、ループ内の <code>switch</code> または <code>select</code> 文で役立ちます。 </p>\n</details>\n<p>通常、break 文はループの実行を終了するために使用されます。ループが switch または select と組み合わせて使用​​される場合、目的の命令文ではないのに中断させてしまう、というミスをすることが開発者にはよくあります。たとえば</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-10-1\"><a id=\"__codelineno-10-1\" name=\"__codelineno-10-1\" href=\"#__codelineno-10-1\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">5</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-10-2\"><a id=\"__codelineno-10-2\" name=\"__codelineno-10-2\" href=\"#__codelineno-10-2\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"%d \"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">)</span>\n</span><span id=\"__span-10-3\"><a id=\"__codelineno-10-3\" name=\"__codelineno-10-3\" href=\"#__codelineno-10-3\"></a>\n</span><span id=\"__span-10-4\"><a id=\"__codelineno-10-4\" name=\"__codelineno-10-4\" href=\"#__codelineno-10-4\"></a><span class=\"w\">    </span><span class=\"k\">switch</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-10-5\"><a id=\"__codelineno-10-5\" name=\"__codelineno-10-5\" href=\"#__codelineno-10-5\"></a><span class=\"w\">    </span><span class=\"k\">default</span><span class=\"p\">:</span>\n</span><span id=\"__span-10-6\"><a id=\"__codelineno-10-6\" name=\"__codelineno-10-6\" href=\"#__codelineno-10-6\"></a><span class=\"w\">    </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"p\">:</span>\n</span><span id=\"__span-10-7\"><a id=\"__codelineno-10-7\" name=\"__codelineno-10-7\" href=\"#__codelineno-10-7\"></a><span class=\"w\">        </span><span class=\"k\">break</span>\n</span><span id=\"__span-10-8\"><a id=\"__codelineno-10-8\" name=\"__codelineno-10-8\" href=\"#__codelineno-10-8\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-10-9\"><a id=\"__codelineno-10-9\" name=\"__codelineno-10-9\" href=\"#__codelineno-10-9\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>break 文は <code>for</code> ループを終了させるのではなく、代わりに <code>switch</code> 文を終了させます。したがって、このコードは 0 から 2 までを反復する代わりに、0 から 4 までを反復します（<code>0 1 2 3 4</code>）。</p>\n<p>覚えておくべき重要なルールの1つは、 <code>break</code> 文は最も内側の <code>for</code> 、<code>switch</code> 、または <code>select</code> 文の実行を終了するということです。前の例では、<code>switch</code> 文を終了します。 </p>\n<p><code>switch</code> 文の代わりにループを中断する最も慣用的な方法はラベルを使用することです。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-11-1\"><a id=\"__codelineno-11-1\" name=\"__codelineno-11-1\" href=\"#__codelineno-11-1\"></a><span class=\"hll\"><span class=\"nx\">loop</span><span class=\"p\">:</span>\n</span></span><span id=\"__span-11-2\"><a id=\"__codelineno-11-2\" name=\"__codelineno-11-2\" href=\"#__codelineno-11-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">5</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-11-3\"><a id=\"__codelineno-11-3\" name=\"__codelineno-11-3\" href=\"#__codelineno-11-3\"></a><span class=\"w\">        </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"%d \"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">)</span>\n</span><span id=\"__span-11-4\"><a id=\"__codelineno-11-4\" name=\"__codelineno-11-4\" href=\"#__codelineno-11-4\"></a>\n</span><span id=\"__span-11-5\"><a id=\"__codelineno-11-5\" name=\"__codelineno-11-5\" href=\"#__codelineno-11-5\"></a><span class=\"w\">        </span><span class=\"k\">switch</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-11-6\"><a id=\"__codelineno-11-6\" name=\"__codelineno-11-6\" href=\"#__codelineno-11-6\"></a><span class=\"w\">        </span><span class=\"k\">default</span><span class=\"p\">:</span>\n</span><span id=\"__span-11-7\"><a id=\"__codelineno-11-7\" name=\"__codelineno-11-7\" href=\"#__codelineno-11-7\"></a><span class=\"w\">        </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"p\">:</span>\n</span><span id=\"__span-11-8\"><a id=\"__codelineno-11-8\" name=\"__codelineno-11-8\" href=\"#__codelineno-11-8\"></a><span class=\"hll\"><span class=\"w\">            </span><span class=\"k\">break</span><span class=\"w\"> </span><span class=\"nx\">loop</span>\n</span></span><span id=\"__span-11-9\"><a id=\"__codelineno-11-9\" name=\"__codelineno-11-9\" href=\"#__codelineno-11-9\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-11-10\"><a id=\"__codelineno-11-10\" name=\"__codelineno-11-10\" href=\"#__codelineno-11-10\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>ここでは、<code>loop</code> ラベルを <code>for</code> ループに関連付けます。 次に、<code>break</code> 文に <code>loop</code> ラベルを指定するので、switch ではなく loop が中断されます。よって、この新しいバージョンは予想どおり <code>0 1 2</code> を出力します。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/34-break/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"defer-35\">ループ内で <code>defer</code> を使用する (#35)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>関数内のループロジックの抽出は、各反復の最後での <code>defer</code> 文の実行につながります。</p>\n</details>\n<p><code>defer</code> 文は、上位ブロックの関数が戻るまで呼び出しの実行を遅らせます。これは主に定型コードを削減するために使用されます。たとえば、リソースを最終的に閉じる必要がある場合は、<code>defer</code> を使用して、<code>return</code> を実行する前にクロージャ呼び出しを繰り返すことを避けることができます。 </p>\n<p><code>defer</code> でよくあるミスの1つは、<em>上位ブロック</em> の関数が戻ったときに関数呼び出しがスケジュールされることを忘れることです。たとえば</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-12-1\"><a id=\"__codelineno-12-1\" name=\"__codelineno-12-1\" href=\"#__codelineno-12-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">readFiles</span><span class=\"p\">(</span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-12-2\"><a id=\"__codelineno-12-2\" name=\"__codelineno-12-2\" href=\"#__codelineno-12-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">path</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-12-3\"><a id=\"__codelineno-12-3\" name=\"__codelineno-12-3\" href=\"#__codelineno-12-3\"></a><span class=\"w\">        </span><span class=\"nx\">file</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">os</span><span class=\"p\">.</span><span class=\"nx\">Open</span><span class=\"p\">(</span><span class=\"nx\">path</span><span class=\"p\">)</span>\n</span><span id=\"__span-12-4\"><a id=\"__codelineno-12-4\" name=\"__codelineno-12-4\" href=\"#__codelineno-12-4\"></a><span class=\"w\">        </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-12-5\"><a id=\"__codelineno-12-5\" name=\"__codelineno-12-5\" href=\"#__codelineno-12-5\"></a><span class=\"w\">            </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-12-6\"><a id=\"__codelineno-12-6\" name=\"__codelineno-12-6\" href=\"#__codelineno-12-6\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-12-7\"><a id=\"__codelineno-12-7\" name=\"__codelineno-12-7\" href=\"#__codelineno-12-7\"></a>\n</span><span id=\"__span-12-8\"><a id=\"__codelineno-12-8\" name=\"__codelineno-12-8\" href=\"#__codelineno-12-8\"></a><span class=\"w\">        </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">file</span><span class=\"p\">.</span><span class=\"nx\">Close</span><span class=\"p\">()</span>\n</span><span id=\"__span-12-9\"><a id=\"__codelineno-12-9\" name=\"__codelineno-12-9\" href=\"#__codelineno-12-9\"></a>\n</span><span id=\"__span-12-10\"><a id=\"__codelineno-12-10\" name=\"__codelineno-12-10\" href=\"#__codelineno-12-10\"></a><span class=\"w\">        </span><span class=\"c1\">// ファイルの処理をする</span>\n</span><span id=\"__span-12-11\"><a id=\"__codelineno-12-11\" name=\"__codelineno-12-11\" href=\"#__codelineno-12-11\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-12-12\"><a id=\"__codelineno-12-12\" name=\"__codelineno-12-12\" href=\"#__codelineno-12-12\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-12-13\"><a id=\"__codelineno-12-13\" name=\"__codelineno-12-13\" href=\"#__codelineno-12-13\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p><code>defer</code> 呼び出しは、各ループ反復中ではなく、<code>readFiles</code> 関数が返されたときに実行されます。 <code>readFiles</code> が返らない場合、ファイル記述子は永久に開いたままになり、リークが発生します。 </p>\n<p>この問題を解決するための一般的な手段の1つは、 <code>defer</code> の後に、各反復中に呼び出される上位ブロックの関数を作成することです。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-13-1\"><a id=\"__codelineno-13-1\" name=\"__codelineno-13-1\" href=\"#__codelineno-13-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">readFiles</span><span class=\"p\">(</span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-2\"><a id=\"__codelineno-13-2\" name=\"__codelineno-13-2\" href=\"#__codelineno-13-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">path</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-3\"><a id=\"__codelineno-13-3\" name=\"__codelineno-13-3\" href=\"#__codelineno-13-3\"></a><span class=\"w\">        </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">readFile</span><span class=\"p\">(</span><span class=\"nx\">path</span><span class=\"p\">);</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-4\"><a id=\"__codelineno-13-4\" name=\"__codelineno-13-4\" href=\"#__codelineno-13-4\"></a><span class=\"w\">            </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-13-5\"><a id=\"__codelineno-13-5\" name=\"__codelineno-13-5\" href=\"#__codelineno-13-5\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-13-6\"><a id=\"__codelineno-13-6\" name=\"__codelineno-13-6\" href=\"#__codelineno-13-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-13-7\"><a id=\"__codelineno-13-7\" name=\"__codelineno-13-7\" href=\"#__codelineno-13-7\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-13-8\"><a id=\"__codelineno-13-8\" name=\"__codelineno-13-8\" href=\"#__codelineno-13-8\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-13-9\"><a id=\"__codelineno-13-9\" name=\"__codelineno-13-9\" href=\"#__codelineno-13-9\"></a>\n</span><span id=\"__span-13-10\"><a id=\"__codelineno-13-10\" name=\"__codelineno-13-10\" href=\"#__codelineno-13-10\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">readFile</span><span class=\"p\">(</span><span class=\"nx\">path</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-11\"><a id=\"__codelineno-13-11\" name=\"__codelineno-13-11\" href=\"#__codelineno-13-11\"></a><span class=\"w\">    </span><span class=\"nx\">file</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">os</span><span class=\"p\">.</span><span class=\"nx\">Open</span><span class=\"p\">(</span><span class=\"nx\">path</span><span class=\"p\">)</span>\n</span><span id=\"__span-13-12\"><a id=\"__codelineno-13-12\" name=\"__codelineno-13-12\" href=\"#__codelineno-13-12\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-13\"><a id=\"__codelineno-13-13\" name=\"__codelineno-13-13\" href=\"#__codelineno-13-13\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-13-14\"><a id=\"__codelineno-13-14\" name=\"__codelineno-13-14\" href=\"#__codelineno-13-14\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-13-15\"><a id=\"__codelineno-13-15\" name=\"__codelineno-13-15\" href=\"#__codelineno-13-15\"></a>\n</span><span id=\"__span-13-16\"><a id=\"__codelineno-13-16\" name=\"__codelineno-13-16\" href=\"#__codelineno-13-16\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">file</span><span class=\"p\">.</span><span class=\"nx\">Close</span><span class=\"p\">()</span>\n</span><span id=\"__span-13-17\"><a id=\"__codelineno-13-17\" name=\"__codelineno-13-17\" href=\"#__codelineno-13-17\"></a>\n</span><span id=\"__span-13-18\"><a id=\"__codelineno-13-18\" name=\"__codelineno-13-18\" href=\"#__codelineno-13-18\"></a><span class=\"w\">    </span><span class=\"c1\">// ファイルの処理をする</span>\n</span><span id=\"__span-13-19\"><a id=\"__codelineno-13-19\" name=\"__codelineno-13-19\" href=\"#__codelineno-13-19\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-13-20\"><a id=\"__codelineno-13-20\" name=\"__codelineno-13-20\" href=\"#__codelineno-13-20\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>別の解決策は、<code>readFile</code> 関数をクロージャにすることですが、本質的には同じです。別の上位ブロックの関数を追加して、各反復中に <code>defer</code> 呼び出しを実行します。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/35-defer-loop/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h2 id=\"_6\">文字列</h2>\n<h3 id=\"36\">ルーンを理解していない (#36)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>ルーンが Unicode コードポイントの概念に対応し、複数のバイトで構成される可能性があることを理解することは、 Go 開発者が文字列を正確に操作するために不可欠です。</p>\n</details>\n<p>Go言語ではルーンがあらゆる場所に使用されるため、次の点を理解することが重要です。 </p>\n<ul>\n<li>文字セットは文字の集合ですが、エンコーディングは文字セットをバイナリに変換する方法を記述します。</li>\n<li>Go言語では、文字列は任意のバイトの不変スライスを参照します。</li>\n<li>Go言語のソースコードは UTF-8 でエンコードされています。したがって、すべの文字列リテラルは UTF-8 文字列です。ただし、文字列には任意のバイトが含まれる可能性があるため、文字列が（ソースコードではない）他の場所から取得された場合、その文字列が UTF-8 エンコーディングに基づいている保証はありません。</li>\n<li><code>rune</code> は Unicode コードポイントの概念に対応し、単一の値で表されるアイテムを意味します。</li>\n<li>UTF-8 を使用すると、Unicode コードポイントを 1 ～ 4 バイトにエンコードできます。</li>\n<li>Go言語で文字列に対して <code>len()</code> を使用すると、ルーン数ではなくバイト数が返されます。</li>\n</ul>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/36-rune/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"37\">文字列に対する不正な反復処理 (#37)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>range</code> 演算子を使用して文字列を反復処理すると、ルーンのバイトシーケンスの開始インデックスに対応するインデックスを使用してルーンが反復処理されます。特定のルーンインデックス（ 3 番目のルーンなど）にアクセスするには、文字列を <code>[]rune</code> に変換します。 </p>\n</details>\n<p>文字列の反復処理は、開発者にとって一般的な操作です。おそらく、文字列内の各ルーンに対して操作を実行するか、特定の部分文字列を検索する独自の関数を実装する必要があるでしょう。どちらの場合も、文字列の異なるルーンを反復処理する必要があります。しかし、反復処理がどのように機能するかについては困惑しやすいです。 </p>\n<p>次の例を考えてみましょう。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-14-1\"><a id=\"__codelineno-14-1\" name=\"__codelineno-14-1\" href=\"#__codelineno-14-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"s\">\"hêllo\"</span>\n</span><span id=\"__span-14-2\"><a id=\"__codelineno-14-2\" name=\"__codelineno-14-2\" href=\"#__codelineno-14-2\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-14-3\"><a id=\"__codelineno-14-3\" name=\"__codelineno-14-3\" href=\"#__codelineno-14-3\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"position %d: %c\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"p\">[</span><span class=\"nx\">i</span><span class=\"p\">])</span>\n</span><span id=\"__span-14-4\"><a id=\"__codelineno-14-4\" name=\"__codelineno-14-4\" href=\"#__codelineno-14-4\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-14-5\"><a id=\"__codelineno-14-5\" name=\"__codelineno-14-5\" href=\"#__codelineno-14-5\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"len=%d\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">))</span>\n</span></code></pre></div>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-15-1\"><a id=\"__codelineno-15-1\" name=\"__codelineno-15-1\" href=\"#__codelineno-15-1\"></a>position 0: h\n</span><span id=\"__span-15-2\"><a id=\"__codelineno-15-2\" name=\"__codelineno-15-2\" href=\"#__codelineno-15-2\"></a>position 1: Ã\n</span><span id=\"__span-15-3\"><a id=\"__codelineno-15-3\" name=\"__codelineno-15-3\" href=\"#__codelineno-15-3\"></a>position 3: l\n</span><span id=\"__span-15-4\"><a id=\"__codelineno-15-4\" name=\"__codelineno-15-4\" href=\"#__codelineno-15-4\"></a>position 4: l\n</span><span id=\"__span-15-5\"><a id=\"__codelineno-15-5\" name=\"__codelineno-15-5\" href=\"#__codelineno-15-5\"></a>position 5: o\n</span><span id=\"__span-15-6\"><a id=\"__codelineno-15-6\" name=\"__codelineno-15-6\" href=\"#__codelineno-15-6\"></a>len=6\n</span></code></pre></div>\n<p>混乱を招く可能性のある 3 点を取り上げましょう。 </p>\n<ul>\n<li>2 番目のルーンは、出力では ê ではなく Ã になります。 </li>\n<li>position 1 から position 3 にジャンプしました。 position 2 には何があるのでしょうか。</li>\n<li>len は 6 を返しますが、s には 5 つのルーンしか含まれていません。 </li>\n</ul>\n<p>結果の最後から見ていきましょう。len はルーン数ではなく、文字列内のバイト数を返すことはすでに述べました。文字列リテラルを <code>s</code> に割り当てているため、<code>s</code> は UTF-8 文字列です。一方、特殊文字「ê」は 1 バイトでエンコードされません。 2 バイト必要です。したがって、<code>len(s)</code> を呼び出すと 6 が返されます。 </p>\n<p>前の例では、各ルーンを反復処理していないことを理解する必要があります。代わりに、ルーンの各開始インデックスを反復処理します。 </p>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/rune.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/rune.png\"></a> </p>\n<p><code>s[i]</code> を出力しても i 番目のルーンは出力されません。インデックス <code>i</code> のバイトの UTF-8 表現を出力します。したがって、 <code>hêllo</code> の代わりに <code>hÃllo</code> を出力がされます。 </p>\n<p>さまざまなルーン文字をすべて出力したい場合は、 <code>range</code> 演算子の value 要素を使用することができます。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-16-1\"><a id=\"__codelineno-16-1\" name=\"__codelineno-16-1\" href=\"#__codelineno-16-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"s\">\"hêllo\"</span>\n</span><span id=\"__span-16-2\"><a id=\"__codelineno-16-2\" name=\"__codelineno-16-2\" href=\"#__codelineno-16-2\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-16-3\"><a id=\"__codelineno-16-3\" name=\"__codelineno-16-3\" href=\"#__codelineno-16-3\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"position %d: %c\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"p\">)</span>\n</span><span id=\"__span-16-4\"><a id=\"__codelineno-16-4\" name=\"__codelineno-16-4\" href=\"#__codelineno-16-4\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>または、文字列をルーンのスライスに変換し、それを反復処理することもできます。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-17-1\"><a id=\"__codelineno-17-1\" name=\"__codelineno-17-1\" href=\"#__codelineno-17-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"s\">\"hêllo\"</span>\n</span><span id=\"__span-17-2\"><a id=\"__codelineno-17-2\" name=\"__codelineno-17-2\" href=\"#__codelineno-17-2\"></a><span class=\"hll\"><span class=\"nx\">runes</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"nb\">rune</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-17-3\"><a id=\"__codelineno-17-3\" name=\"__codelineno-17-3\" href=\"#__codelineno-17-3\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">runes</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-17-4\"><a id=\"__codelineno-17-4\" name=\"__codelineno-17-4\" href=\"#__codelineno-17-4\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"position %d: %c\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"p\">)</span>\n</span><span id=\"__span-17-5\"><a id=\"__codelineno-17-5\" name=\"__codelineno-17-5\" href=\"#__codelineno-17-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>この解決策では、以前の解決策と比較して実行時のオーバーヘッドが発生することに注意してください。実際、文字列をルーンのスライスに変換するには、追加のスライスを割り当て、バイトをルーンに変換する必要があります。文字列のバイト数を n とすると、時間計算量は O(n) になります。したがって、すべてのルーンを反復処理する場合は、最初の解決策を使用するべきです。 </p>\n<p>ただし、最初の方法を使用して文字列の i 番目のルーンにアクセスしたい場合は、ルーンインデックスにアクセスできません。代わりに、バイトシーケンス内のルーンの開始インデックスがわかります。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-18-1\"><a id=\"__codelineno-18-1\" name=\"__codelineno-18-1\" href=\"#__codelineno-18-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"s\">\"hêllo\"</span>\n</span><span id=\"__span-18-2\"><a id=\"__codelineno-18-2\" name=\"__codelineno-18-2\" href=\"#__codelineno-18-2\"></a><span class=\"nx\">r</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"nb\">rune</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)[</span><span class=\"mi\">4</span><span class=\"p\">]</span>\n</span><span id=\"__span-18-3\"><a id=\"__codelineno-18-3\" name=\"__codelineno-18-3\" href=\"#__codelineno-18-3\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"%c\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// o</span>\n</span></code></pre></div>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/37-string-iteration/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"trim-38\">trim 関数の誤用 (#38)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>strings.TrimRight</code> ・ <code>strings.TrimLeft</code> は、指定されたセットに含まれるすべての末尾・先頭のルーンを削除しますが、 <code>strings.TrimSuffix</code> ・ <code>strings.TrimPrefix</code> は、指定された接尾辞・接頭辞のない文字列を返します。</p>\n</details>\n<p>たとえば</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-19-1\"><a id=\"__codelineno-19-1\" name=\"__codelineno-19-1\" href=\"#__codelineno-19-1\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">strings</span><span class=\"p\">.</span><span class=\"nx\">TrimRight</span><span class=\"p\">(</span><span class=\"s\">\"123oxo\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s\">\"xo\"</span><span class=\"p\">))</span>\n</span></code></pre></div>\n<p>は 123 を出力します</p>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/trim.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/trim.png\"></a></p>\n<p>逆に、 <code>strings.TrimLeft</code> は、セットに含まれる先頭のルーンをすべて削除します。 </p>\n<p>一方、<code>strings.TrimSuffix</code> ・ <code>strings.TrimPrefix</code> は、指定された末尾の接尾辞・接頭辞を除いた文字列を返します。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/38-trim/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"39\">最適化が不十分な文字列の連結 (#39)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>文字列のリストの連結は、反復ごとに新しい文字列が割り当てられないように、<code>strings.Builder</code> を使用して行う必要があります。</p>\n</details>\n<p><code>+=</code> 演算子を用いてスライスのすべての文字列要素を連結する <code>concat</code> 関数を考えてみましょう。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-20-1\"><a id=\"__codelineno-20-1\" name=\"__codelineno-20-1\" href=\"#__codelineno-20-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">concat</span><span class=\"p\">(</span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-20-2\"><a id=\"__codelineno-20-2\" name=\"__codelineno-20-2\" href=\"#__codelineno-20-2\"></a><span class=\"w\">    </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"s\">\"\"</span>\n</span><span id=\"__span-20-3\"><a id=\"__codelineno-20-3\" name=\"__codelineno-20-3\" href=\"#__codelineno-20-3\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">value</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-20-4\"><a id=\"__codelineno-20-4\" name=\"__codelineno-20-4\" href=\"#__codelineno-20-4\"></a><span class=\"w\">        </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"nx\">value</span>\n</span><span id=\"__span-20-5\"><a id=\"__codelineno-20-5\" name=\"__codelineno-20-5\" href=\"#__codelineno-20-5\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-20-6\"><a id=\"__codelineno-20-6\" name=\"__codelineno-20-6\" href=\"#__codelineno-20-6\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">s</span>\n</span><span id=\"__span-20-7\"><a id=\"__codelineno-20-7\" name=\"__codelineno-20-7\" href=\"#__codelineno-20-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>各反復中に、 <code>+=</code> 演算子は <code>s</code> と value 文字列を連結します。一見すると、この関数は間違っていないように見えるかもしれません。しかし、この実装は、文字列の核となる特性の1つである不変性を忘れています。したがって、各反復では <code>s</code> は更新されません。メモリ内に新しい文字列を再割り当てするため、この関数のパフォーマンスに大きな影響を与えます。 </p>\n<p>幸いなことに、 <code>strings.Builder</code> を用いることで、この問題に対処する解決策があります。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-21-1\"><a id=\"__codelineno-21-1\" name=\"__codelineno-21-1\" href=\"#__codelineno-21-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">concat</span><span class=\"p\">(</span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-21-2\"><a id=\"__codelineno-21-2\" name=\"__codelineno-21-2\" href=\"#__codelineno-21-2\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"nx\">sb</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">strings</span><span class=\"p\">.</span><span class=\"nx\">Builder</span><span class=\"p\">{}</span>\n</span></span><span id=\"__span-21-3\"><a id=\"__codelineno-21-3\" name=\"__codelineno-21-3\" href=\"#__codelineno-21-3\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">value</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-21-4\"><a id=\"__codelineno-21-4\" name=\"__codelineno-21-4\" href=\"#__codelineno-21-4\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">sb</span><span class=\"p\">.</span><span class=\"nx\">WriteString</span><span class=\"p\">(</span><span class=\"nx\">value</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-21-5\"><a id=\"__codelineno-21-5\" name=\"__codelineno-21-5\" href=\"#__codelineno-21-5\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-21-6\"><a id=\"__codelineno-21-6\" name=\"__codelineno-21-6\" href=\"#__codelineno-21-6\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">sb</span><span class=\"p\">.</span><span class=\"nx\">String</span><span class=\"p\">()</span>\n</span><span id=\"__span-21-7\"><a id=\"__codelineno-21-7\" name=\"__codelineno-21-7\" href=\"#__codelineno-21-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>各反復中に、value の内容を内部バッファに追加する <code>WriteString</code> メソッドを呼び出して結果の文字列を構築し、メモリのコピーを最小限に抑えることができました。</p>\n<details class=\"note\" open=\"open\">\n<summary>補足</summary>\n<p><code>WriteString</code> は 2 番目の出力としてエラーを返しますが、意図的に無視しましょう。実際、このメソッドは nil エラー以外を返すことはありません。では、このメソッドがシグネチャの一部としてエラーを返す目的は何でしょうか。<code>strings.Builder</code> は <code>io.StringWriter</code> インタフェースを実装しており、これには <code>WriteString(s string) (n int, err error)</code> という1つのメソッドが含まれています。したがって、このインタフェースに準拠するには、<code>WriteString</code> はエラーを返さなければならないのです。</p>\n</details>\n<p>内部的には、<code>strings.Builder</code> はバイトスライスを保持します。 <code>WriteString</code> を呼び出すたびに、このスライスに追加する呼び出しが行われます。これには2つの影響があります。まず、 <code>append</code> の呼び出しが衝突状態を引き起こす可能性があるため、この構造体は同時に使用されるべきではありません。2番目の影響は、 <a href=\"#21\">非効率なスライスの初期化 (#21)</a> で見たものです。スライスの将来の長さがすでにわかっている場合は、それを事前に割り当てる必要があります。そのために、<code>strings.Builder</code> は別の <code>n</code> バイトのためのスペースを保証するメソッド <code>Grow(n int)</code> を持っています。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-22-1\"><a id=\"__codelineno-22-1\" name=\"__codelineno-22-1\" href=\"#__codelineno-22-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">concat</span><span class=\"p\">(</span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-22-2\"><a id=\"__codelineno-22-2\" name=\"__codelineno-22-2\" href=\"#__codelineno-22-2\"></a><span class=\"w\">    </span><span class=\"nx\">total</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span>\n</span><span id=\"__span-22-3\"><a id=\"__codelineno-22-3\" name=\"__codelineno-22-3\" href=\"#__codelineno-22-3\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">values</span><span class=\"p\">);</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-22-4\"><a id=\"__codelineno-22-4\" name=\"__codelineno-22-4\" href=\"#__codelineno-22-4\"></a><span class=\"w\">        </span><span class=\"nx\">total</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">values</span><span class=\"p\">[</span><span class=\"nx\">i</span><span class=\"p\">])</span>\n</span><span id=\"__span-22-5\"><a id=\"__codelineno-22-5\" name=\"__codelineno-22-5\" href=\"#__codelineno-22-5\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-22-6\"><a id=\"__codelineno-22-6\" name=\"__codelineno-22-6\" href=\"#__codelineno-22-6\"></a>\n</span><span id=\"__span-22-7\"><a id=\"__codelineno-22-7\" name=\"__codelineno-22-7\" href=\"#__codelineno-22-7\"></a><span class=\"w\">    </span><span class=\"nx\">sb</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">strings</span><span class=\"p\">.</span><span class=\"nx\">Builder</span><span class=\"p\">{}</span>\n</span><span id=\"__span-22-8\"><a id=\"__codelineno-22-8\" name=\"__codelineno-22-8\" href=\"#__codelineno-22-8\"></a><span class=\"w\">    </span><span class=\"nx\">sb</span><span class=\"p\">.</span><span class=\"nx\">Grow</span><span class=\"p\">(</span><span class=\"nx\">total</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n</span><span id=\"__span-22-9\"><a id=\"__codelineno-22-9\" name=\"__codelineno-22-9\" href=\"#__codelineno-22-9\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">value</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-22-10\"><a id=\"__codelineno-22-10\" name=\"__codelineno-22-10\" href=\"#__codelineno-22-10\"></a><span class=\"w\">        </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">sb</span><span class=\"p\">.</span><span class=\"nx\">WriteString</span><span class=\"p\">(</span><span class=\"nx\">value</span><span class=\"p\">)</span>\n</span><span id=\"__span-22-11\"><a id=\"__codelineno-22-11\" name=\"__codelineno-22-11\" href=\"#__codelineno-22-11\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-22-12\"><a id=\"__codelineno-22-12\" name=\"__codelineno-22-12\" href=\"#__codelineno-22-12\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">sb</span><span class=\"p\">.</span><span class=\"nx\">String</span><span class=\"p\">()</span>\n</span><span id=\"__span-22-13\"><a id=\"__codelineno-22-13\" name=\"__codelineno-22-13\" href=\"#__codelineno-22-13\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>ベンチマークを実行して 3 つのバージョン（ <code>+=</code> を使用した V1 、事前割り当てなしで <code>strings.Builder{}</code> を使用した V2 、事前割り当てありの <code>strings.Builder{}</code> を使用した V3 ）を比較してみましょう。入力スライスには 1,000 個の文字列が含まれており、各文字列には 1,000 バイトが含まれています。</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-23-1\"><a id=\"__codelineno-23-1\" name=\"__codelineno-23-1\" href=\"#__codelineno-23-1\"></a>BenchmarkConcatV1-4             16      72291485 ns/op\n</span><span id=\"__span-23-2\"><a id=\"__codelineno-23-2\" name=\"__codelineno-23-2\" href=\"#__codelineno-23-2\"></a>BenchmarkConcatV2-4           1188        878962 ns/op\n</span><span id=\"__span-23-3\"><a id=\"__codelineno-23-3\" name=\"__codelineno-23-3\" href=\"#__codelineno-23-3\"></a>BenchmarkConcatV3-4           5922        190340 ns/op\n</span></code></pre></div>\n<p>ご覧のとおり、最新バージョンが最も効率的で、V1 より 99% 、V2 より 78% 高速です。 </p>\n<p><code>strings.Builder</code> は、文字列のリストを連結するための解決策として推奨されます。通常、これはループ内で使用する必要があります。いくつかの文字列 （名前と姓など）を連結するだけの場合、 <code>strings.Builder</code> の使用は、 <code>+=</code> 演算子や <code>fmt.Sprintf</code> と比べて可読性が低くなるからです。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/39-string-concat/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"40\">無駄な文字列変換 (#40)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>bytes</code> パッケージは <code>strings</code> パッケージと同じ操作を提供してくれることを覚えておくと、余分なバイト・文字列変換を避けることができます。</p>\n</details>\n<p>文字列または <code>[]byte</code> を扱うことを選択する場合、ほとんどのプログラマーは利便性のために文字列を好む傾向があります。しかし、ほとんどの I/O は実際には <code>[]byte</code> で行われます。たとえば、<code>io.Reader</code>、<code>io.Writer</code>、および <code>io.ReadAll</code> は文字列ではなく <code>[]byte</code> を処理します。 </p>\n<p>文字列と <code>[]byte</code> のどちらを扱うべきか迷ったとき、<code>[]byte</code> を扱う方が必ずしも面倒だというわけではないことを思い出してください。strings パッケージからエクスポートされたすべての関数には、<code>bytes</code> パッケージに代替機能があります。 <code>Split</code>、<code>Count</code>、<code>Contains</code>、<code>Index</code> などです。したがって、I/O を実行しているかどうかに関係なく、文字列の代わりにバイトを使用してワークフロー全体を実装でき、追加の変換コストを回避できるかどうかを最初に確認しましょう。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/40-string-conversion/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"41\">部分文字列とメモリリーク (#41)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>部分文字列の代わりにコピーを使用すると、部分文字列操作によって返される文字列が同じバイト配列によってサポートされるため、メモリリークを防ぐことができます。</p>\n</details>\n<p><a href=\"#26\">スライスとメモリリーク (#26)</a> では、スライスまたは配列のスライスがメモリリークの状況を引き起こす可能性があることを確認しました。この原則は、文字列および部分文字列の操作にも当てはまります。 </p>\n<p>Go言語で部分文字列操作を使用するときは、2 つのことに留意する必要があります。まず、提供される間隔はルーン数ではなく、バイト数に基づいています。次に、結果の部分文字列が最初の文字列と同じバッキング配列を共有するため、部分文字列操作によりメモリリークが発生する可能性があります。これを防ぐ方法は、文字列のコピーを手動で実行するか、Go 1.18 から実装されている <code>strings.Clone</code> を使用することです。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/41-substring-memory-leak/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h2 id=\"_7\">関数とメソッド</h2>\n<h3 id=\"42\">どの型のレシーバーを使用すればよいかわかっていない (#42)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>値レシーバーとポインタレシーバーのどちらを使用するかは、どの型なのか、変化させる必要があるかどうか、コピーできないフィールドが含まれているかどうか、オブジェクトはどれくらい大きいのか、などの要素に基づいて決定する必要があります。分からない場合は、ポインタレシーバを使用してください。</p>\n</details>\n<p>値レシーバーとポインタレシーバーのどちらを選択するかは、必ずしも簡単ではありません。選択に役立ついくつかの条件について説明しましょう。 </p>\n<p><em>ポインタレシーバーでなければならない</em> とき</p>\n<ul>\n<li>メソッドがレシーバーを変化させる必要がある場合。このルールは、受信側がスライスであり、メソッドが要素を追加する必要がある場合にも有効です。</li>\n</ul>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-24-1\"><a id=\"__codelineno-24-1\" name=\"__codelineno-24-1\" href=\"#__codelineno-24-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">slice</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">int</span>\n</span><span id=\"__span-24-2\"><a id=\"__codelineno-24-2\" name=\"__codelineno-24-2\" href=\"#__codelineno-24-2\"></a>\n</span><span id=\"__span-24-3\"><a id=\"__codelineno-24-3\" name=\"__codelineno-24-3\" href=\"#__codelineno-24-3\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">slice</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">add</span><span class=\"p\">(</span><span class=\"nx\">element</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-24-4\"><a id=\"__codelineno-24-4\" name=\"__codelineno-24-4\" href=\"#__codelineno-24-4\"></a><span class=\"w\">    </span><span class=\"o\">*</span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">element</span><span class=\"p\">)</span>\n</span><span id=\"__span-24-5\"><a id=\"__codelineno-24-5\" name=\"__codelineno-24-5\" href=\"#__codelineno-24-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<ul>\n<li>メソッドレシーバーにコピーできないフィールドが含まれている場合。sync パッケージの型部分はその一例になります（ <a href=\"#sync-74\">sync 型のコピー (#74)</a> を参照）。</li>\n</ul>\n<p><em>ポインタレシーバーであるべき</em> とき</p>\n<ul>\n<li>レシーバーが大きなオブジェクトの場合。ポインタを使用すると、大規模なコピーの作成が防止されるため、呼び出しがより効率的になります。どれくらいの大きさなのか確証がない場合は、ベンチマークが解決策になる可能性があります。多くの要因に依存するため、特定のサイズを指定することはほとんど不可能です。 </li>\n</ul>\n<p><em>値レシーバーでなければならない</em> とき</p>\n<ul>\n<li>レシーバーの不変性を強制する必要がある場合。 </li>\n<li>レシーバーがマップ、関数、チャネルの場合。それ以外の場合はコンパイルエラーが発生します。 </li>\n</ul>\n<p><em>値レシーバーであるべき</em> とき</p>\n<ul>\n<li>レシーバーが変化させる必要のないスライスの場合。 </li>\n<li>レシーバーが、<code>time.Time</code> などの小さな配列または構造体で、可変フィールドを持たない値型である場合。 </li>\n<li>レシーバーが <code>int</code>、<code>float64</code>、または <code>string</code> などの基本型の場合。 </li>\n</ul>\n<p>もちろん、特殊なケースは常に存在するため、すべてを網羅することは不可能ですが、このセクションの目標は、ほとんどのケースをカバーするためのガイダンスを提供することです。通常は、そうしない正当な理由がない限り、値レシーバーを使用して間違いありません。分からない場合は、ポインタレシーバを使用する必要があります。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/42-receiver/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"43\">名前付き結果パラメータをまったく使用していない (#43)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>名前付き結果パラメーターの使用は、特に複数の結果パラメーターが同じ型を持つ場合、関数・メソッドの読みやすさを向上させる効率的な方法です。場合によっては、名前付き結果パラメータはゼロ値に初期化されるため、この方法が便利ですらあることもあります。ただし潜在的な副作用には注意してください。</p>\n</details>\n<p>関数またはメソッドでパラメータを返すとき、これらのパラメータに名前を付けて、通常の変数として使用できます。結果パラメーターに名前を付けると、関数・メソッドの開始時にそのパラメーターはゼロ値に初期化されます。名前付き結果パラメータを使用すると、 むき出しの return 文（引数なし） を呼び出すこともできます。その場合、結果パラメータの現在の値が戻り値として使用されます。 </p>\n<p>以下は、名前付き結果パラメータ <code>b</code> を用いた例です。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-25-1\"><a id=\"__codelineno-25-1\" name=\"__codelineno-25-1\" href=\"#__codelineno-25-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">(</span><span class=\"nx\">a</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-25-2\"><a id=\"__codelineno-25-2\" name=\"__codelineno-25-2\" href=\"#__codelineno-25-2\"></a><span class=\"w\">    </span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">a</span>\n</span><span id=\"__span-25-3\"><a id=\"__codelineno-25-3\" name=\"__codelineno-25-3\" href=\"#__codelineno-25-3\"></a><span class=\"w\">    </span><span class=\"k\">return</span>\n</span><span id=\"__span-25-4\"><a id=\"__codelineno-25-4\" name=\"__codelineno-25-4\" href=\"#__codelineno-25-4\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>この例では、結果パラメータに名前 <code>b</code> を付けています。引数なしで return を呼び出すと、<code>b</code> の現在の値が返されます。 </p>\n<p>場合によっては、名前付きの結果パラメーターによって可読性が向上することもあります。たとえば、2 つのパラメーターが同じ型である場合などです。その他にも、利便性のために用いることができます。ゆえに、明確な利点がある場合は、慎重になりながらも名前付き結果パラメータを使用するべきです。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/43-named-result-parameters/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"44\">名前付き結果パラメータによる予想外の副作用 (#44)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><a href=\"#43\">#43</a> を参照してください。</p>\n</details>\n<p>名前付き結果パラメータが状況によっては役立つ理由について説明しました。 ただし、これらはゼロ値に初期化されるため、十分に注意しないと、軽微なバグが発生する可能性があります。たとえば、このコードはどこが間違っているでしょうか。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-26-1\"><a id=\"__codelineno-26-1\" name=\"__codelineno-26-1\" href=\"#__codelineno-26-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">l</span><span class=\"w\"> </span><span class=\"nx\">loc</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">getCoordinates</span><span class=\"p\">(</span><span class=\"nx\">ctx</span><span class=\"w\"> </span><span class=\"nx\">context</span><span class=\"p\">.</span><span class=\"nx\">Context</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">address</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span>\n</span><span id=\"__span-26-2\"><a id=\"__codelineno-26-2\" name=\"__codelineno-26-2\" href=\"#__codelineno-26-2\"></a><span class=\"w\">    </span><span class=\"nx\">lat</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">lng</span><span class=\"w\"> </span><span class=\"kt\">float32</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-26-3\"><a id=\"__codelineno-26-3\" name=\"__codelineno-26-3\" href=\"#__codelineno-26-3\"></a><span class=\"w\">    </span><span class=\"nx\">isValid</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">l</span><span class=\"p\">.</span><span class=\"nx\">validateAddress</span><span class=\"p\">(</span><span class=\"nx\">address</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-26-4\"><a id=\"__codelineno-26-4\" name=\"__codelineno-26-4\" href=\"#__codelineno-26-4\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"p\">!</span><span class=\"nx\">isValid</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-26-5\"><a id=\"__codelineno-26-5\" name=\"__codelineno-26-5\" href=\"#__codelineno-26-5\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">errors</span><span class=\"p\">.</span><span class=\"nx\">New</span><span class=\"p\">(</span><span class=\"s\">\"invalid address\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-26-6\"><a id=\"__codelineno-26-6\" name=\"__codelineno-26-6\" href=\"#__codelineno-26-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-26-7\"><a id=\"__codelineno-26-7\" name=\"__codelineno-26-7\" href=\"#__codelineno-26-7\"></a>\n</span><span id=\"__span-26-8\"><a id=\"__codelineno-26-8\" name=\"__codelineno-26-8\" href=\"#__codelineno-26-8\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">ctx</span><span class=\"p\">.</span><span class=\"nx\">Err</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n</span><span id=\"__span-26-9\"><a id=\"__codelineno-26-9\" name=\"__codelineno-26-9\" href=\"#__codelineno-26-9\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-26-10\"><a id=\"__codelineno-26-10\" name=\"__codelineno-26-10\" href=\"#__codelineno-26-10\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-26-11\"><a id=\"__codelineno-26-11\" name=\"__codelineno-26-11\" href=\"#__codelineno-26-11\"></a>\n</span><span id=\"__span-26-12\"><a id=\"__codelineno-26-12\" name=\"__codelineno-26-12\" href=\"#__codelineno-26-12\"></a><span class=\"w\">    </span><span class=\"c1\">// 座標を取得して返す</span>\n</span><span id=\"__span-26-13\"><a id=\"__codelineno-26-13\" name=\"__codelineno-26-13\" href=\"#__codelineno-26-13\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>一瞥しただけではエラーは明らかではないかもしれません。<code>if ctx.Err() != nil</code> スコープで返されるエラーは <code>err</code> です。しかし、<code>err</code> 変数には値を割り当てていません。<code>error</code> 型のゼロ値、 <code>nil</code> に割り当てられたままです。したがって、このコードは常に nil エラーを返します。 </p>\n<p>名前付き結果パラメータを使用する場合、各パラメータはゼロ値に初期化されることに注意してください。このセクションで説明したように、これにより、見つけるのが必ずしも簡単ではない軽微なバグが発生する可能性があります。ゆえに、潜在的な副作用を避けるために、名前付き結果パラメーターを使用するときは注意してください。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/44-side-effects-named-result-parameters/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"nil-45\">nil レシーバーを返す (#45)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>インタフェースを返すときは、nil ポインタを返すのではなく、明示的な nil 値を返すように注意してください。そうしなければ、意図しない結果が発生し、呼び出し元が nil ではない値を受け取る可能性があります。</p>\n</details>\n<!-- TODO -->\n\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/45-nil-receiver/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"46\">関数入力にファイル名を使用している (#46)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>ファイル名の代わりに <code>io.Reader</code> 型を受け取るように関数を設計すると、関数の再利用性が向上し、テストが容易になります。</p>\n</details>\n<p>ファイル名をファイルから読み取るための関数入力として受け入れることは、ほとんどの場合、「コードの臭い」とみなされるべきです（ <code>os.Open</code> などの特定の関数を除く）。複数のファイルを作成することにになるかもしれず、単体テストがより複雑になる可能性があるからです。また、関数の再利用性も低下します （ただし、すべての関数が再利用されるわけではありません）。 <code>io.Reader</code> インタフェースを使用すると、データソースが抽象化されます。入力がファイル、文字列、HTTP リクエスト、gRPC リクエストのいずれであるかに関係なく、実装は再利用でき、簡単にテストできます。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/46-function-input/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"defer-47\"><code>defer</code> 引数とレシーバーがどのように評価されるかを知らない（引数の評価、ポインター、および値レシーバー） (#47)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>ポインタを <code>defer</code> 関数に渡すことと、呼び出しをクロージャ内にラップすることが、引数とレシーバーの即時評価を克服するために実現可能な解決策です。 </p>\n</details>\n<p><code>defer</code> 関数では、引数は、上位ブロックの関数が戻ってからではなく、すぐに評価されます。たとえば、このコードでは、常に同じステータス――空の文字列――で <code>notify</code> と <code>incrementCounter</code> を呼び出します。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-27-1\"><a id=\"__codelineno-27-1\" name=\"__codelineno-27-1\" href=\"#__codelineno-27-1\"></a><span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"p\">(</span>\n</span><span id=\"__span-27-2\"><a id=\"__codelineno-27-2\" name=\"__codelineno-27-2\" href=\"#__codelineno-27-2\"></a><span class=\"w\">    </span><span class=\"nx\">StatusSuccess</span><span class=\"w\">  </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"s\">\"success\"</span>\n</span><span id=\"__span-27-3\"><a id=\"__codelineno-27-3\" name=\"__codelineno-27-3\" href=\"#__codelineno-27-3\"></a><span class=\"w\">    </span><span class=\"nx\">StatusErrorFoo</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"s\">\"error_foo\"</span>\n</span><span id=\"__span-27-4\"><a id=\"__codelineno-27-4\" name=\"__codelineno-27-4\" href=\"#__codelineno-27-4\"></a><span class=\"w\">    </span><span class=\"nx\">StatusErrorBar</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"s\">\"error_bar\"</span>\n</span><span id=\"__span-27-5\"><a id=\"__codelineno-27-5\" name=\"__codelineno-27-5\" href=\"#__codelineno-27-5\"></a><span class=\"p\">)</span>\n</span><span id=\"__span-27-6\"><a id=\"__codelineno-27-6\" name=\"__codelineno-27-6\" href=\"#__codelineno-27-6\"></a>\n</span><span id=\"__span-27-7\"><a id=\"__codelineno-27-7\" name=\"__codelineno-27-7\" href=\"#__codelineno-27-7\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-27-8\"><a id=\"__codelineno-27-8\" name=\"__codelineno-27-8\" href=\"#__codelineno-27-8\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"kt\">string</span>\n</span><span id=\"__span-27-9\"><a id=\"__codelineno-27-9\" name=\"__codelineno-27-9\" href=\"#__codelineno-27-9\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">notify</span><span class=\"p\">(</span><span class=\"nx\">status</span><span class=\"p\">)</span>\n</span><span id=\"__span-27-10\"><a id=\"__codelineno-27-10\" name=\"__codelineno-27-10\" href=\"#__codelineno-27-10\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">incrementCounter</span><span class=\"p\">(</span><span class=\"nx\">status</span><span class=\"p\">)</span>\n</span><span id=\"__span-27-11\"><a id=\"__codelineno-27-11\" name=\"__codelineno-27-11\" href=\"#__codelineno-27-11\"></a>\n</span><span id=\"__span-27-12\"><a id=\"__codelineno-27-12\" name=\"__codelineno-27-12\" href=\"#__codelineno-27-12\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">foo</span><span class=\"p\">();</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-27-13\"><a id=\"__codelineno-27-13\" name=\"__codelineno-27-13\" href=\"#__codelineno-27-13\"></a><span class=\"w\">        </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">StatusErrorFoo</span>\n</span><span id=\"__span-27-14\"><a id=\"__codelineno-27-14\" name=\"__codelineno-27-14\" href=\"#__codelineno-27-14\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-27-15\"><a id=\"__codelineno-27-15\" name=\"__codelineno-27-15\" href=\"#__codelineno-27-15\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-27-16\"><a id=\"__codelineno-27-16\" name=\"__codelineno-27-16\" href=\"#__codelineno-27-16\"></a>\n</span><span id=\"__span-27-17\"><a id=\"__codelineno-27-17\" name=\"__codelineno-27-17\" href=\"#__codelineno-27-17\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">bar</span><span class=\"p\">();</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-27-18\"><a id=\"__codelineno-27-18\" name=\"__codelineno-27-18\" href=\"#__codelineno-27-18\"></a><span class=\"w\">        </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">StatusErrorBar</span>\n</span><span id=\"__span-27-19\"><a id=\"__codelineno-27-19\" name=\"__codelineno-27-19\" href=\"#__codelineno-27-19\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-27-20\"><a id=\"__codelineno-27-20\" name=\"__codelineno-27-20\" href=\"#__codelineno-27-20\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-27-21\"><a id=\"__codelineno-27-21\" name=\"__codelineno-27-21\" href=\"#__codelineno-27-21\"></a>\n</span><span id=\"__span-27-22\"><a id=\"__codelineno-27-22\" name=\"__codelineno-27-22\" href=\"#__codelineno-27-22\"></a><span class=\"w\">    </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">StatusSuccess</span>\n</span><span id=\"__span-27-23\"><a id=\"__codelineno-27-23\" name=\"__codelineno-27-23\" href=\"#__codelineno-27-23\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-27-24\"><a id=\"__codelineno-27-24\" name=\"__codelineno-27-24\" href=\"#__codelineno-27-24\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>たしかに、<code>notify(status)</code> と <code>incrementCounter(status)</code> を <code>defer</code> 関数として呼び出しています。したがって、Go言語は、defer を使用した段階で <code>f</code> がステータスの現在の値を返すと、これらの呼び出しの実行を遅らせ、空の文字列を渡します。 </p>\n<p><code>defer</code> を使い続けたい場合の主な方法は 2 つあります。 </p>\n<p>最初の解決策は文字列ポインタを渡すことです。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-28-1\"><a id=\"__codelineno-28-1\" name=\"__codelineno-28-1\" href=\"#__codelineno-28-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-28-2\"><a id=\"__codelineno-28-2\" name=\"__codelineno-28-2\" href=\"#__codelineno-28-2\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"kt\">string</span>\n</span><span id=\"__span-28-3\"><a id=\"__codelineno-28-3\" name=\"__codelineno-28-3\" href=\"#__codelineno-28-3\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">notify</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">status</span><span class=\"p\">)</span><span class=\"w\"> </span>\n</span></span><span id=\"__span-28-4\"><a id=\"__codelineno-28-4\" name=\"__codelineno-28-4\" href=\"#__codelineno-28-4\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">incrementCounter</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">status</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-28-5\"><a id=\"__codelineno-28-5\" name=\"__codelineno-28-5\" href=\"#__codelineno-28-5\"></a>\n</span><span id=\"__span-28-6\"><a id=\"__codelineno-28-6\" name=\"__codelineno-28-6\" href=\"#__codelineno-28-6\"></a><span class=\"w\">    </span><span class=\"c1\">// 関数のそれ以外の部分は変更なし</span>\n</span><span id=\"__span-28-7\"><a id=\"__codelineno-28-7\" name=\"__codelineno-28-7\" href=\"#__codelineno-28-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p><code>defer</code> を使用すると、引数（ここではステータスのアドレス）がすぐに評価されます。ステータス自体は関数全体で変更されますが、そのアドレスは割り当てに関係なく一定のままです。よって、<code>notify</code> または <code>incrementCounter</code> が文字列ポインタによって参照される値を使用する場合、期待どおりに動作します。ただし、この解決策では 2 つの関数のシグネチャを変更する必要があり、それが常に可能であるとは限りません。 </p>\n<p>別の解決策があります――クロージャ（本体の外部から変数を参照する匿名関数値）を <code>defer</code> 文として呼び出すことです。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-29-1\"><a id=\"__codelineno-29-1\" name=\"__codelineno-29-1\" href=\"#__codelineno-29-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-29-2\"><a id=\"__codelineno-29-2\" name=\"__codelineno-29-2\" href=\"#__codelineno-29-2\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"kt\">string</span>\n</span><span id=\"__span-29-3\"><a id=\"__codelineno-29-3\" name=\"__codelineno-29-3\" href=\"#__codelineno-29-3\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span></span><span id=\"__span-29-4\"><a id=\"__codelineno-29-4\" name=\"__codelineno-29-4\" href=\"#__codelineno-29-4\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"nx\">notify</span><span class=\"p\">(</span><span class=\"nx\">status</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-29-5\"><a id=\"__codelineno-29-5\" name=\"__codelineno-29-5\" href=\"#__codelineno-29-5\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"nx\">incrementCounter</span><span class=\"p\">(</span><span class=\"nx\">status</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-29-6\"><a id=\"__codelineno-29-6\" name=\"__codelineno-29-6\" href=\"#__codelineno-29-6\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span></span><span id=\"__span-29-7\"><a id=\"__codelineno-29-7\" name=\"__codelineno-29-7\" href=\"#__codelineno-29-7\"></a>\n</span><span id=\"__span-29-8\"><a id=\"__codelineno-29-8\" name=\"__codelineno-29-8\" href=\"#__codelineno-29-8\"></a><span class=\"w\">    </span><span class=\"c1\">// 関数のそれ以外の部分は変更なし</span>\n</span><span id=\"__span-29-9\"><a id=\"__codelineno-29-9\" name=\"__codelineno-29-9\" href=\"#__codelineno-29-9\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>ここでは、<code>notify</code> と <code>incrementCounter</code> の両方の呼び出しをクロージャ内にラップします。このクロージャは、本体の外部からステータス変数を参照します。ゆえに、<code>status</code> は、<code>defer</code> を呼び出したときではなく、クロージャが実行されたときに評価されます。この解決策は正しく機能する上に、シグネチャを変更するために <code>notify</code> や <code>incrementCounter</code> を必要としません。 </p>\n<p>この動作はメソッドレシーバーにも適用されることにも注意してください。レシーバーはすぐに評価されます。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/47-defer-evaluation/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h2 id=\"_8\">エラー処理</h2>\n<h3 id=\"48\">パニック (#48)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>panic</code> の使用は、Go言語でエラーに対処するための手段です。ただし、これは回復不能な状況でのみ使用するようにしてください。たとえば、ヒューマンエラーを通知する場合や、必須の依存関係の読み込みに失敗した場合などです。</p>\n</details>\n<p>Go言語では、panic は通常の流れを停止する組み込み関数です。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-30-1\"><a id=\"__codelineno-30-1\" name=\"__codelineno-30-1\" href=\"#__codelineno-30-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-30-2\"><a id=\"__codelineno-30-2\" name=\"__codelineno-30-2\" href=\"#__codelineno-30-2\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"s\">\"a\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-30-3\"><a id=\"__codelineno-30-3\" name=\"__codelineno-30-3\" href=\"#__codelineno-30-3\"></a><span class=\"w\">    </span><span class=\"nb\">panic</span><span class=\"p\">(</span><span class=\"s\">\"foo\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-30-4\"><a id=\"__codelineno-30-4\" name=\"__codelineno-30-4\" href=\"#__codelineno-30-4\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"s\">\"b\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-30-5\"><a id=\"__codelineno-30-5\" name=\"__codelineno-30-5\" href=\"#__codelineno-30-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>このコードは a を出力し、b を出力する前に停止します。</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-31-1\"><a id=\"__codelineno-31-1\" name=\"__codelineno-31-1\" href=\"#__codelineno-31-1\"></a>a\n</span><span id=\"__span-31-2\"><a id=\"__codelineno-31-2\" name=\"__codelineno-31-2\" href=\"#__codelineno-31-2\"></a>panic: foo\n</span><span id=\"__span-31-3\"><a id=\"__codelineno-31-3\" name=\"__codelineno-31-3\" href=\"#__codelineno-31-3\"></a>\n</span><span id=\"__span-31-4\"><a id=\"__codelineno-31-4\" name=\"__codelineno-31-4\" href=\"#__codelineno-31-4\"></a>goroutine 1 [running]:\n</span><span id=\"__span-31-5\"><a id=\"__codelineno-31-5\" name=\"__codelineno-31-5\" href=\"#__codelineno-31-5\"></a>main.main()\n</span><span id=\"__span-31-6\"><a id=\"__codelineno-31-6\" name=\"__codelineno-31-6\" href=\"#__codelineno-31-6\"></a>        main.go:7 +0xb3\n</span></code></pre></div>\n<p>panic の使用は慎重にすべきです。代表的なケースが 2 つあり、1 つはヒューマンエラーを通知する場合（例: <a href=\"https://cs.opensource.google/go/go/+/refs/tags/go1.20.7:src/database/sql/sql.go;l=44\"><code>sql.Register</code></a>ドライバーが <code>nil</code> または既に登録されている場合に panic を起こします）、もう 1 つはアプリケーションが必須の依存関係の生成に失敗した場合です。結果として、例外的にアプリケーションを停止します。それ以外のほとんどの場合においては、エラー処理は、最後の戻り引数として適切なエラー型を返す関数を通じて行うべきです。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/48-panic/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"49\">エラーをラップすべきときを知らない (#49)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>エラーをラップすると、エラーをマークしたり、追加のコンテキストを提供したりできます。ただし、エラーラッピングにより、呼び出し元がソースエラーを利用できるようになるため、潜在的な結合が発生します。それを避けたい場合は、エラーラッピングを使用しないでください。</p>\n</details>\n<p>Go 1.13 以降、%w ディレクティブを使用すれば簡単にエラーをラップできるようになりました。エラーラッピングとは、ソースエラーも使用できるようにするラッパーコンテナ内でエラーをラップまたはパックすることです。一般に、エラーラッピングの主な使用例は次の 2 つです。 </p>\n<ul>\n<li>エラーにさらにコンテキストを加える</li>\n<li>エラーを特定のエラーとしてマークする </li>\n</ul>\n<p>エラーを処理するとき、エラーをラップするかどうかを決定できます。ラッピングとは、エラーにさらにコンテキストを追加したり、エラーを特定のタイプとしてマークしたりすることです。エラーをマークする必要がある場合は、独自のエラー型を作成する必要があります。ですが、新たにコンテキストを加えたいだけの場合は、新しいエラー型を作成する必要がないため、%w ディレクティブを指定して fmt.Errorf を使用しましょう。ただし、エラーラッピングにより、呼び出し元がソースエラーを利用できるようになるため、潜在的な結合が生じます。それを避けたい場合は、エラーのラッピングではなく、エラーの変換を使用する必要があります。たとえば、%v ディレクティブを指定した fmt.Errorf を使用します。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/49-error-wrapping/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"50\">エラー型の不正な比較 (#50)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>Go 1.13 のエラーラッピングを <code>%w</code> ディレクティブと <code>fmt.Errorf</code> で使用する場合、型に対するエラーの比較は <code>errors.As</code> を通じて行う必要があります。そうでなければ、返されたエラーがラップされている場合、評価に失敗します。</p>\n</details>\n<!-- TODO -->\n\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/50-compare-error-type/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"51\">エラー値の不正な比較 (#51)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>Go 1.13 のエラーラッピングを <code>%w</code> ディレクティブと <code>fmt.Errorf</code> で使用する場合、エラーと値の比較は <code>errors.As</code> を通じて行う必要があります。そうでなければ、返されたエラーがラップされている場合、評価に失敗します。 </p>\n</details>\n<p>センチネルエラーはグローバル変数として定義されたエラーのことです。</p>\n<p></p><div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-32-1\"><a id=\"__codelineno-32-1\" name=\"__codelineno-32-1\" href=\"#__codelineno-32-1\"></a><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"s\">\"errors\"</span>\n</span><span id=\"__span-32-2\"><a id=\"__codelineno-32-2\" name=\"__codelineno-32-2\" href=\"#__codelineno-32-2\"></a>\n</span><span id=\"__span-32-3\"><a id=\"__codelineno-32-3\" name=\"__codelineno-32-3\" href=\"#__codelineno-32-3\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">ErrFoo</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">errors</span><span class=\"p\">.</span><span class=\"nx\">New</span><span class=\"p\">(</span><span class=\"s\">\"foo\"</span><span class=\"p\">)</span>\n</span></code></pre></div>\n一般に、慣例として <code>Err</code> で始め、その後にエラー型を続けます。ここでは <code>ErrFoo</code> です。センチネルエラーは、<em>予期される</em> エラー、つまりクライアントが確認することを期待するエラーを伝えます。一般的なガイドラインとして<p></p>\n<ul>\n<li>予期されるエラーはエラー値（センチネルエラー）として設計する必要があります： <code>var ErrFoo =errors.New(\"foo\")</code>。 </li>\n<li>予期しないエラーはエラー型として設計する必要があります： <code>BarError</code> は <code>error</code> インタフェースを実装した上で <code>type BarError struct { ... }</code>。 </li>\n</ul>\n<p>アプリケーションで <code>%w</code> ディレクティブと <code>fmt.Errorf</code> を使用してエラーラップを使用する場合、特定の値に対するエラーのチェックは <code>==</code> の代わりに <code>errors.Is</code> を使用して行いましょう。それによって、センチネルエラーがラップされている場合でも、<code>errors.Is</code> はそれを再帰的にアンラップし、チェーン内の各エラーを提供された値と比較できます。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/51-comparing-error-value/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"2-52\">エラーの 2 回処理 (#52)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>ほとんどの場合、エラーは 1 回で処理されるべきです。エラーをログに記録することは、エラーを処理することです。すなわち、ログに記録するかエラーを返すかを選択する必要があります。多くの場合、エラーラッピングは、エラーに追加のコンテキストを提供し、ソースエラーを返すことができるため、解決策になります。 </p>\n</details>\n<p>エラーを複数回処理することは、特にGo言語に限らず、開発者が頻繁にやってしまうミスです。これにより、同じエラーが複数回ログに記録され、デバッグが困難になる状況が発生する可能性があります。 </p>\n<p>エラー処理は 1 度で済ますべきだということを覚えておきましょう。エラーをログに記録することは、エラーを処理することです。つまり、行うべきは、ログに記録するか、エラーを返すかのどちらかだということです。これにより、コードが簡素化され、エラーの状況についてより適切な洞察が得られます。エラーラッピングは、ソースエラーを伝え、エラーにコンテキストを追加できるため、最も使い勝手の良い手段になります。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/52-handling-error-twice/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"53\">エラー処理をしない (#53)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>関数呼び出し中であっても、<code>defer</code> 関数内であっても、エラーを無視するときは、ブランク識別子を使用して明確に行うべきです。そうしないと、将来の読み手がそれが意図的だったのか、それともミスだったのか困惑する可能性があります。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/53-not-handling-error/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"defer-54\"><code>defer</code> エラーを処理しない (#54)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>多くの場合、<code>defer</code> 関数によって返されるエラーを無視すべきではありません。状況に応じて、直接処理するか、呼び出し元に伝えましょう。これを無視する場合は、ブランク識別子を使用してください。 </p>\n</details>\n<p>次のコードを考えてみましょう。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-33-1\"><a id=\"__codelineno-33-1\" name=\"__codelineno-33-1\" href=\"#__codelineno-33-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-33-2\"><a id=\"__codelineno-33-2\" name=\"__codelineno-33-2\" href=\"#__codelineno-33-2\"></a><span class=\"w\">  </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-33-3\"><a id=\"__codelineno-33-3\" name=\"__codelineno-33-3\" href=\"#__codelineno-33-3\"></a><span class=\"w\">  </span><span class=\"nx\">notify</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// エラー処理は省略されています</span>\n</span><span id=\"__span-33-4\"><a id=\"__codelineno-33-4\" name=\"__codelineno-33-4\" href=\"#__codelineno-33-4\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-33-5\"><a id=\"__codelineno-33-5\" name=\"__codelineno-33-5\" href=\"#__codelineno-33-5\"></a>\n</span><span id=\"__span-33-6\"><a id=\"__codelineno-33-6\" name=\"__codelineno-33-6\" href=\"#__codelineno-33-6\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">notify</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-33-7\"><a id=\"__codelineno-33-7\" name=\"__codelineno-33-7\" href=\"#__codelineno-33-7\"></a><span class=\"w\">  </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-33-8\"><a id=\"__codelineno-33-8\" name=\"__codelineno-33-8\" href=\"#__codelineno-33-8\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>保守性の観点から、このコードはいくつかの問題を引き起こす可能性があります。ある人がこれを読むことを考えてみます。読み手は、notify がエラーを返すにもかかわらず、そのエラーが親関数によって処理されないことに気づきます。エラー処理が意図的であるかどうかを果たして推測できるでしょうか。以前の開発者がそれを処理するのを忘れたのか、それとも意図的に処理したのかを知ることができるでしょうか。</p>\n<p>これらの理由により、エラーを無視したい場合、ブランク識別子（ <code>_</code> ）を使うほかありません。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-34-1\"><a id=\"__codelineno-34-1\" name=\"__codelineno-34-1\" href=\"#__codelineno-34-1\"></a><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">notify</span>\n</span></code></pre></div>\n<p>コンパイルと実行時間の点では、この方法は最初のコード部分と比べて何も変わりません。しかし、この新しいバージョンでは、私たちがエラーに関心がないことを明らかにしています。また、エラーが無視される理由を示すコメントを追加することもできます。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-35-1\"><a id=\"__codelineno-35-1\" name=\"__codelineno-35-1\" href=\"#__codelineno-35-1\"></a><span class=\"c1\">// 最大でも 1 回の伝達 </span>\n</span><span id=\"__span-35-2\"><a id=\"__codelineno-35-2\" name=\"__codelineno-35-2\" href=\"#__codelineno-35-2\"></a><span class=\"c1\">// それゆえ、エラーが発生した場合にそれらの一部が失われることは許容されます</span>\n</span><span id=\"__span-35-3\"><a id=\"__codelineno-35-3\" name=\"__codelineno-35-3\" href=\"#__codelineno-35-3\"></a><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">notify</span><span class=\"p\">()</span>\n</span></code></pre></div>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/54-defer-errors/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h2 id=\"_9\">並行処理：基礎</h2>\n<h3 id=\"55\">並行処理と並列処理の混同 (#55)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>並行処理と並列処理の基本的な違いを理解することは、 Go 開発者にとって必須です。並行処理は構造に関するものですが、並列処理は実行に関するものです。 </p>\n</details>\n<p>並行処理と並列処理は同じではありません。 </p>\n<ul>\n<li>並行処理は構造に関するものです。別々の並行ゴルーチンが取り組むことができるさまざまな段階を導入することで、逐次処理を並行処理に変更できます。 </li>\n<li>並列処理は実行に関するものです。並列ゴルーチンをさらに追加することで、段階レベルで並列処理を使用できます。 </li>\n</ul>\n<p>まとめると、並行処理は、並列化できる部分をもつ問題を解決するための構造を提供します。すなわち、<em>並行処理により並列処理が可能</em> になります 。</p>\n<!-- TODO Include Rob Pike's talk link-->\n\n<h3 id=\"56\">並行処理のほうが常に早いと考えている (#56)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>熟練した開発者になるには、並行処理が必ずしも高速であるとは限らないことを認識する必要があります。最小限のワークロードの並列処理を伴う解決策は、必ずしも逐次処理より高速であるとは限りません。逐次処理と並行処理のベンチマークは、仮定を検証する方法であるべきです。</p>\n</details>\n<p>セクション全文は<a href=\"../56-concurrency-faster/\">こちら</a>。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/56-faster/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"57\">チャネルまたはミューテックスをいつ使用するべきかについて戸惑っている (#57)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>ゴルーチンの相互作用を認識していることは、チャネルとミューテックスのどちらを選択するかを決定するときにも役立ちます。一般に、並列ゴルーチンには同期が必要であり、したがってミューテックスが必要です。反対に、並行ゴルーチンは通常、調整とオーケストレーション、つまりチャネルを必要とします。 </p>\n</details>\n<p>並行処理の問題を考慮すると、チャネルまたはミューテックスを使用した解決策を実装できるかどうかが必ずしも明確ではない可能性があります。Go言語は通信によるメモリの共有を促進するため、起こりうる間違いのうちの一つは、ユースケースにかかわらず、チャネルの使用を常に強制することです。しかしながら、2 つの方法は補完的なものであると見なすべきです。  </p>\n<p>チャネルまたはミューテックスはどのような場合に使用する必要があるのでしょうか。次の図の例をバックボーンとして使用します。この例には、特定の関係を持つ 3 つの異なるゴルーチンがあります。 </p>\n<ul>\n<li>G1 と G2 は並列ゴルーチンです。チャネルからメッセージを受信し続ける同じ関数を実行する 2 つのゴルーチン、あるいは同じ HTTP ハンドラを同時に実行する 2 つのゴルーチンかもしれません。 </li>\n<li>G1 と G3 は並行ゴルーチンであり、G2 と G3 も同様です。すべてのゴルーチンは全体の並行構造の一部ですが、G1 と G2 が最初のステップを実行し、G3 が次のステップを実行します。 </li>\n</ul>\n<!-- TODO Include figure-->\n\n<p>原則として、並列ゴルーチンは、スライスなどの共有リソースにアクセスしたり変更したりする必要がある場合などに、_同期_する必要があります。同期はミューテックスでは強制されますが、どのチャネル型でも強制されません（バッファありチャネルを除く）。したがって、一般に、並列ゴルーチン間の同期はミューテックスを介して達成される必要があります。 </p>\n<p>一方、一般に、並行ゴルーチンは <em>調整およびオーケストレーション</em> をする必要があります。たとえば、G3 が G1 と G2 の両方からの結果を集約する必要がある場合、G1 と G2 は新しい中間結果が利用可能であることを G3 に通知する必要があります。この調整はコミュニケーションの範囲、つまりチャネルに該当します。 </p>\n<p>並行ゴルーチンに関しては、リソースの所有権をあるステップ（G1 および G2）から別のステップ（G3）に移管したい場合もあります。たとえば、G1 と G2 によって共有リソースが豊かになっている場合、ある時点でこのジョブは完了したと見なされます。ここでは、チャネルを使用して、特定のリソースの準備ができていることを通知し、所有権の移転を処理する必要があります。 </p>\n<p>ミューテックスとチャネルには異なるセマンティクスがあります。ステートを共有したいとき、または共有リソースにアクセスしたいときは、ミューテックスによってこのリソースへの排他的アクセスが保証されます。反対に、チャネルはデータの有無（<code>chan struct{}</code> の有無）に関係なくシグナルを行う仕組みです。調整や所有権の移転はチャネルを通じて行う必要があります。ゴルーチンが並列か並行かを知ることが重要です。一般に、並列ゴルーチンにはミューテックスが必要で、並行ゴルーチンにはチャネルが必要です。</p>\n<h3 id=\"go-58\">競合問題を理解していない（データ競合と競合状態、そしてGo言語のメモリモデル） (#58)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>並行処理に熟達するということは、データ競合と競合状態が異なる概念であることを理解することも意味します。データ競合は、複数のゴルーチンが同じメモリ位置に同時にアクセスし、そのうちの少なくとも 1 つが書き込みを行っている場合に発生します。一方、データ競合がないことが必ずしも決定的実行を意味するわけではありません。動作が制御できないイベントの順序やタイミングに依存している場合、これは競合状態です。</p>\n</details>\n<p>競合問題は、プログラマーが直面する可能性のあるバグの中で最も困難かつ最も潜伏性の高いバグの 1 つとなります。Go 開発者として、私たちはデータ競合と競合状態、それらが及ぼしうる影響、およびそれらを回避する方法などの重要な側面を理解する必要があります。</p>\n<h4 id=\"_10\">データ競合</h4>\n<p>データ競合は、2 つ以上のゴルーチンが同じメモリ位置に同時にアクセスし、少なくとも 1 つが書き込みを行っている場合に発生します。この場合、危険な結果が生じる可能性があります。さらに悪いことに、状況によっては、メモリ位置に無意味なビットの組み合わせを含む値が保持されてしまう可能性があります。 </p>\n<p>さまざまな手法を駆使して、データ競合の発生を防ぐことができます。たとえば </p>\n<ul>\n<li><code>sync/atomic</code> パッケージを使用する </li>\n<li>2 つのゴルーチンを同期する際にミューテックスのような特定の目的のためのデータ構造を利用する</li>\n<li>チャネルを使用して 2 つのゴルーチンが通信し、変数が一度に 1 つのゴルーチンだけによって更新されるようにする</li>\n</ul>\n<h4 id=\"_11\">競合状態</h4>\n<p>実行したい操作に応じて、データ競合のないアプリケーションが必ずしも決定的な結果を意味するでしょうか。そうとはいえません。</p>\n<p>競合状態は、動作が制御できないイベントのシーケンスまたはタイミングに依存する場合に発生します。ここでは、イベントのタイミングがゴルーチンの実行順序です。 </p>\n<p>まとめると、並行処理のアプリケーションで作業する場合、データ競合は競合状態とは異なることを理解することが不可欠です。データ競合は、複数のゴルーチンが同じメモリ位置に同時にアクセスし、そのうちの少なくとも 1 つが書き込みを行っている場合に発生します。データ競合とは、予想外の動作を意味します。ただし、データ競合のないアプリケーションが必ずしも決定的な結果を意味するわけではありません。データ競合がなくても、アプリケーションは制御されていないイベント（ゴルーチンの実行、チャネルへのメッセージの発信速度、データベースへの呼び出しの継続時間など）に依存する挙動を持つことがあります。その場合は競合状態です。並行処理のアプリケーションの設計に熟練するには、両方の概念を理解することが肝要です。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/58-races/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"59\">ワークロードタイプごとの並行処理の影響を理解していない (#59)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>一定数のゴルーチンを作成するときは、ワークロードのタイプを考慮してください。CPU バウンドのゴルーチンを作成するということは、この数を <code>GOMAXPROCS</code> 変数（デフォルトではホスト上の CPU コアの数に基づく）に近づけることを意味します。I/O バウンドのゴルーチンの作成は、外部システムなどの他の要因に依存します。 </p>\n</details>\n<p>プログラミングでは、ワークロードの実行時間は次のいずれかによって制限されます。 </p>\n<ul>\n<li>CPU の速度 - たとえば、マージソートアルゴリズムの実行がこれにあたります。このワークロードは CPU バウンドと呼ばれます。 </li>\n<li>I/O の速度 - たとえば、REST 呼び出しやデータベースクエリの実行がこれにあたります。このワークロードは I/O バウンドと呼ばれます。 </li>\n<li>利用可能なメモリの量 - このワークロードはメモリバウンドと呼ばれます。</li>\n</ul>\n<details class=\"note\" open=\"open\">\n<summary>補足</summary>\n<p>ここ数十年でメモリが非常に安価になったことを考慮すると、 3 つ目は現在では最もまれです。したがって、このセクションでは、最初の 2 つのワークロードタイプ、CPU バウンドと I/O バウンドに焦点を当てます。 </p>\n</details>\n<p>ワーカーによって実行されるワークロードが I/O バウンドである場合、値は主に外部システムに依存します。逆に、ワークロードが CPU に依存している場合、ゴルーチンの最適な数は利用可能な CPU コアの数に近くなります（ベストプラクティスは <code>runtime.GOMAXPROCS</code> を使用することです）。並行処理のアプリケーションを設計する場合、ワークロードのタイプ（ I/O あるいは CPU ）を知ることが重要です。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/59-workload-type/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"go-context-60\">Go Context に対する誤解 (#60)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>Go Context は、Go言語の並行処理の基礎の一部でもあります。 Context を使用すると、デッドライン、キーと値のリストを保持できます。</p>\n</details>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">https://pkg.go.dev/context</p>\n<p>Context は、デッドライン、キャンセルシグナル、その他の値を API の境界を越えて伝達します。</p>\n</div>\n<h4 id=\"_12\">デッドライン</h4>\n<p>デッドラインとは、次のいずれかで決定される特定の時点を指します。 </p>\n<ul>\n<li>現在からの <code>time.Duration</code> （例：250 ms）</li>\n<li><code>time.Time</code> （例：2023-02-07 00:00:00 UTC） </li>\n</ul>\n<p>デッドラインのセマンティクスは、これを過ぎた場合は進行中のアクティビティを停止する必要があることを伝えます。アクティビティとは、たとえば、チャネルからのメッセージの受信を待機している I/O リクエストやゴルーチンです。 </p>\n<h4 id=\"_13\">キャンセルシグナル</h4>\n<p>Go Context のもう 1 つの使用例は、キャンセルシグナルを伝送することです。別のゴルーチン内で <code>CreateFileWatcher(ctx context.Context, filename string)</code> を呼び出すアプリケーションを作成することを想像してみましょう。この関数は、ファイルから読み取りを続けて更新をキャッチする特定のファイルウォッチャーを作成します。提供された Context が期限切れになるかキャンセルされると、この関数はそれを処理してファイル記述子を閉じます。 </p>\n<h4 id=\"context-value\">Context Value</h4>\n<p>Go Context の最後の使用例は、キーと値のリストを運ぶことです。 Context にキーと値のリストを含める意味は何でしょうか。Go Context は汎用的であるため、使用例は無限にあります。 </p>\n<p>たとえば、トレースを使用する場合、異なるサブ関数の間で同じ相関 ID を共有したいことがあるかもしれません。一部の開発者は、この ID を関数シグネチャの一部にするにはあまりに侵略的だと考えるかもしれません。この点に関して、与えられた Context の一部としてそれを含めることを決定することもできます。 </p>\n<h4 id=\"context\">Context のキャンセルをキャッチする</h4>\n<p><code>context.Context</code> タイプは、受信専用の通知チャネル <code>&lt;-chan struct{}</code> を返す <code>Done</code> メソッドをエクスポートします。このチャネルは、 Context に関連付けられた作業をキャンセルする必要がある場合に閉じられます。たとえば </p>\n<ul>\n<li><code>context.WithCancel</code>で作成された Context に関連する Done チャネルは、cancel関数が呼び出されると閉じられます。 </li>\n<li><code>context.WithDeadline</code>で作成した Context に関連する Done チャネルは、デッドラインを過ぎると閉じられます。 </li>\n</ul>\n<p>注意すべき点の 1 つは、内部チャネルは、特定の値を受け取ったときではなく、 Context がキャンセルされたとき、またはデッドラインに達したときに閉じる必要があるということです。チャネルのクローズは、すべての消費者ゴルーチンが受け取る唯一のチャネルアクションであるためです。このようにして、 Context がキャンセルされるか、デッドラインに達すると、すべての消費者に通知が届きます。 </p>\n<p>まとめると、熟練した Go 開発者になるには、 Context とその使用方法について理解する必要があります。原則として、ユーザーが待機させられる関数は Context を取得するべきです。これにより、上流の呼び出し元がこの関数をいつ呼び出すかを決定できるようになるからです。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/60-contexts/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h2 id=\"_14\">並行処理：実践</h2>\n<h3 id=\"context-61\">不適切な Context を広めてしまう (#61)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>Context を伝播する際には、Context をキャンセルできる条件を理解することが重要です。たとえば、レスポンスが送信された際に HTTP ハンドラが Context をキャンセルするときなどです。 </p>\n</details>\n<p>多くの状況では、Go Context を伝播することが推奨されます。ただし、Context の伝播によって軽微なバグが発生し、サブ関数が正しく実行されなくなる場合があります。 </p>\n<p>次の例を考えてみましょう。いくつかのタスクを実行してレスポンスを返す HTTP ハンドラを公開します。ただし、レスポンスを返す直前に、それを Kafka トピックに送信したいと思っています。HTTP コンシューマにレイテンシの点でペナルティを課したくないので、publish アクションを新しいゴルーチン内で非同期に処理したいと考えています。たとえば、Context がキャンセルされた場合にメッセージの publish アクションを中断できるように、Context を受け入れる <code>publish</code> 関数を自由に使えるとします。可能な実装は次のとおりです。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-36-1\"><a id=\"__codelineno-36-1\" name=\"__codelineno-36-1\" href=\"#__codelineno-36-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">handler</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">ResponseWriter</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Request</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-36-2\"><a id=\"__codelineno-36-2\" name=\"__codelineno-36-2\" href=\"#__codelineno-36-2\"></a><span class=\"w\">    </span><span class=\"nx\">response</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">doSomeTask</span><span class=\"p\">(</span><span class=\"nx\">r</span><span class=\"p\">.</span><span class=\"nx\">Context</span><span class=\"p\">(),</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"p\">)</span>\n</span><span id=\"__span-36-3\"><a id=\"__codelineno-36-3\" name=\"__codelineno-36-3\" href=\"#__codelineno-36-3\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-36-4\"><a id=\"__codelineno-36-4\" name=\"__codelineno-36-4\" href=\"#__codelineno-36-4\"></a><span class=\"w\">        </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Error</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">Error</span><span class=\"p\">(),</span><span class=\"w\"> </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">StatusInternalServerError</span><span class=\"p\">)</span>\n</span><span id=\"__span-36-5\"><a id=\"__codelineno-36-5\" name=\"__codelineno-36-5\" href=\"#__codelineno-36-5\"></a><span class=\"w\">    </span><span class=\"k\">return</span>\n</span><span id=\"__span-36-6\"><a id=\"__codelineno-36-6\" name=\"__codelineno-36-6\" href=\"#__codelineno-36-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-36-7\"><a id=\"__codelineno-36-7\" name=\"__codelineno-36-7\" href=\"#__codelineno-36-7\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-36-8\"><a id=\"__codelineno-36-8\" name=\"__codelineno-36-8\" href=\"#__codelineno-36-8\"></a><span class=\"w\">        </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">publish</span><span class=\"p\">(</span><span class=\"nx\">r</span><span class=\"p\">.</span><span class=\"nx\">Context</span><span class=\"p\">(),</span><span class=\"w\"> </span><span class=\"nx\">response</span><span class=\"p\">)</span>\n</span><span id=\"__span-36-9\"><a id=\"__codelineno-36-9\" name=\"__codelineno-36-9\" href=\"#__codelineno-36-9\"></a><span class=\"w\">        </span><span class=\"c1\">// err の処理をする</span>\n</span><span id=\"__span-36-10\"><a id=\"__codelineno-36-10\" name=\"__codelineno-36-10\" href=\"#__codelineno-36-10\"></a><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span><span id=\"__span-36-11\"><a id=\"__codelineno-36-11\" name=\"__codelineno-36-11\" href=\"#__codelineno-36-11\"></a><span class=\"w\">    </span><span class=\"nx\">writeResponse</span><span class=\"p\">(</span><span class=\"nx\">response</span><span class=\"p\">)</span>\n</span><span id=\"__span-36-12\"><a id=\"__codelineno-36-12\" name=\"__codelineno-36-12\" href=\"#__codelineno-36-12\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>このコードの何が問題なのでしょうか。HTTP リクエストに付された Context は、さまざまな状況でキャンセルされる可能性があることを知っておく必要があります。 </p>\n<ul>\n<li>クライアントの接続が終了したとき </li>\n<li>HTTP/2リクエストの場合、リクエストがキャンセルされたとき</li>\n<li>クライアントにレスポンスが書き戻されたとき </li>\n</ul>\n<p>最初の 2 つのケースでは、処理はおそらく正しく行われます。たとえば、doSomeTask からレスポンスを受け取ったものの、クライアントが接続を閉じた場合、メッセージが publish されないように、Context が既にキャンセルされた状態で publish を呼び出しても問題はおそらく起きません。しかし、最後のケースはどうでしょうか。</p>\n<p>レスポンスがクライアントに書き込まれると、要求に関連付けられた Context がキャンセルされます。したがって、競合状態に直面します。 </p>\n<ul>\n<li>レスポンスが Kafka の publish 後に書かれた場合、レスポンスを返し、メッセージを正常に公開します。 </li>\n<li>ただし、Kafka の publish 前または publish 中にレスポンスが書かれた場合、メッセージは publish されるべきではありません。 </li>\n</ul>\n<p>後者の場合、HTTP レスポンスをすぐに返すので、publish を呼び出すとエラーが返されます。</p>\n<details class=\"note\" open=\"open\">\n<summary>補足</summary>\n<p>Go 1.21 からは、キャンセルせずに新しい Context を作成する方法が追加されました。 <a href=\"https://pkg.go.dev/context#WithoutCancel\"><code>context.WithoutCancel</code></a> は、親がキャンセルされたときにキャンセルされていない親のコピーを返します。 </p>\n</details>\n<p>まとめると、Context の伝播は慎重に行う必要があります。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/61-inappropriate-context/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"62\">停止すべきときを知らずにゴルーチンを開始してしまう (#62)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>リークを避けることは、ゴルーチンが開始されるたびに、最終的に停止する必要があることを意味します。</p>\n</details>\n<p>ゴルーチンは簡単に行うことができます。非常に簡単であるため、新しいゴルーチンをいつ停止するかについての計画を必ずしも立てていない可能性があり、リークにつながることがあります。ゴルーチンをいつ停止すればよいかわからないのは、Go言語でよくある設計上の問題であり、並行処理におけるミスです。 </p>\n<p>具体的な例について説明しましょう。外部設定（データベース接続などを使用したものなど）を監視する必要があるアプリケーションを設計します。まず、次のような実装をしてみます。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-37-1\"><a id=\"__codelineno-37-1\" name=\"__codelineno-37-1\" href=\"#__codelineno-37-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-37-2\"><a id=\"__codelineno-37-2\" name=\"__codelineno-37-2\" href=\"#__codelineno-37-2\"></a><span class=\"w\">    </span><span class=\"nx\">newWatcher</span><span class=\"p\">()</span>\n</span><span id=\"__span-37-3\"><a id=\"__codelineno-37-3\" name=\"__codelineno-37-3\" href=\"#__codelineno-37-3\"></a><span class=\"w\">    </span><span class=\"c1\">// アプリケーションを実行する</span>\n</span><span id=\"__span-37-4\"><a id=\"__codelineno-37-4\" name=\"__codelineno-37-4\" href=\"#__codelineno-37-4\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-37-5\"><a id=\"__codelineno-37-5\" name=\"__codelineno-37-5\" href=\"#__codelineno-37-5\"></a>\n</span><span id=\"__span-37-6\"><a id=\"__codelineno-37-6\" name=\"__codelineno-37-6\" href=\"#__codelineno-37-6\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"cm\">/* いくつかのリソース */</span><span class=\"w\"> </span><span class=\"p\">}</span>\n</span><span id=\"__span-37-7\"><a id=\"__codelineno-37-7\" name=\"__codelineno-37-7\" href=\"#__codelineno-37-7\"></a>\n</span><span id=\"__span-37-8\"><a id=\"__codelineno-37-8\" name=\"__codelineno-37-8\" href=\"#__codelineno-37-8\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">newWatcher</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-37-9\"><a id=\"__codelineno-37-9\" name=\"__codelineno-37-9\" href=\"#__codelineno-37-9\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"p\">{}</span>\n</span><span id=\"__span-37-10\"><a id=\"__codelineno-37-10\" name=\"__codelineno-37-10\" href=\"#__codelineno-37-10\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">watch</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// 外部設定を監視するゴルーチンを作成する</span>\n</span><span id=\"__span-37-11\"><a id=\"__codelineno-37-11\" name=\"__codelineno-37-11\" href=\"#__codelineno-37-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>このコードの問題は、メインのゴルーチンが終了すると（おそらく OS シグナルまたは有限のワークロードのため）、アプリケーションが停止してしまうことです。したがって、ウォッチャーによって作成されたリソースは正常に閉じられません。これを防ぐにはどうすればよいでしょうか。</p>\n<p>1 つの方法としては、main が戻ったときにキャンセルされる Context を newWatcher に渡すことが挙げられます。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-38-1\"><a id=\"__codelineno-38-1\" name=\"__codelineno-38-1\" href=\"#__codelineno-38-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-38-2\"><a id=\"__codelineno-38-2\" name=\"__codelineno-38-2\" href=\"#__codelineno-38-2\"></a><span class=\"w\">    </span><span class=\"nx\">ctx</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">cancel</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">context</span><span class=\"p\">.</span><span class=\"nx\">WithCancel</span><span class=\"p\">(</span><span class=\"nx\">context</span><span class=\"p\">.</span><span class=\"nx\">Background</span><span class=\"p\">())</span>\n</span><span id=\"__span-38-3\"><a id=\"__codelineno-38-3\" name=\"__codelineno-38-3\" href=\"#__codelineno-38-3\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">cancel</span><span class=\"p\">()</span>\n</span><span id=\"__span-38-4\"><a id=\"__codelineno-38-4\" name=\"__codelineno-38-4\" href=\"#__codelineno-38-4\"></a><span class=\"w\">    </span><span class=\"nx\">newWatcher</span><span class=\"p\">(</span><span class=\"nx\">ctx</span><span class=\"p\">)</span>\n</span><span id=\"__span-38-5\"><a id=\"__codelineno-38-5\" name=\"__codelineno-38-5\" href=\"#__codelineno-38-5\"></a><span class=\"w\">    </span><span class=\"c1\">// アプリケーションを実行する</span>\n</span><span id=\"__span-38-6\"><a id=\"__codelineno-38-6\" name=\"__codelineno-38-6\" href=\"#__codelineno-38-6\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-38-7\"><a id=\"__codelineno-38-7\" name=\"__codelineno-38-7\" href=\"#__codelineno-38-7\"></a>\n</span><span id=\"__span-38-8\"><a id=\"__codelineno-38-8\" name=\"__codelineno-38-8\" href=\"#__codelineno-38-8\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">newWatcher</span><span class=\"p\">(</span><span class=\"nx\">ctx</span><span class=\"w\"> </span><span class=\"nx\">context</span><span class=\"p\">.</span><span class=\"nx\">Context</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-38-9\"><a id=\"__codelineno-38-9\" name=\"__codelineno-38-9\" href=\"#__codelineno-38-9\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"p\">{}</span>\n</span><span id=\"__span-38-10\"><a id=\"__codelineno-38-10\" name=\"__codelineno-38-10\" href=\"#__codelineno-38-10\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">watch</span><span class=\"p\">(</span><span class=\"nx\">ctx</span><span class=\"p\">)</span>\n</span><span id=\"__span-38-11\"><a id=\"__codelineno-38-11\" name=\"__codelineno-38-11\" href=\"#__codelineno-38-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>作成した Context を watch メソッドに伝播します。Context がキャンセルされると、ウォッチャー構造体はそのリソースを閉じます。しかし、watch がそれを行う時間が確実にあるとはいえません。これは設計上の欠陥です。 </p>\n<p>問題は、ゴルーチンを停止する必要があることを伝えるためにシグナルを使用したことです。リソースが閉じられるまで、親のゴルーチンをブロックしませんでした。そうならないようにしましょう。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-39-1\"><a id=\"__codelineno-39-1\" name=\"__codelineno-39-1\" href=\"#__codelineno-39-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-39-2\"><a id=\"__codelineno-39-2\" name=\"__codelineno-39-2\" href=\"#__codelineno-39-2\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">newWatcher</span><span class=\"p\">()</span>\n</span><span id=\"__span-39-3\"><a id=\"__codelineno-39-3\" name=\"__codelineno-39-3\" href=\"#__codelineno-39-3\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nb\">close</span><span class=\"p\">()</span>\n</span><span id=\"__span-39-4\"><a id=\"__codelineno-39-4\" name=\"__codelineno-39-4\" href=\"#__codelineno-39-4\"></a><span class=\"w\">    </span><span class=\"c1\">// アプリケーションを実行する</span>\n</span><span id=\"__span-39-5\"><a id=\"__codelineno-39-5\" name=\"__codelineno-39-5\" href=\"#__codelineno-39-5\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-39-6\"><a id=\"__codelineno-39-6\" name=\"__codelineno-39-6\" href=\"#__codelineno-39-6\"></a>\n</span><span id=\"__span-39-7\"><a id=\"__codelineno-39-7\" name=\"__codelineno-39-7\" href=\"#__codelineno-39-7\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">newWatcher</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-39-8\"><a id=\"__codelineno-39-8\" name=\"__codelineno-39-8\" href=\"#__codelineno-39-8\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"p\">{}</span>\n</span><span id=\"__span-39-9\"><a id=\"__codelineno-39-9\" name=\"__codelineno-39-9\" href=\"#__codelineno-39-9\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">watch</span><span class=\"p\">()</span>\n</span><span id=\"__span-39-10\"><a id=\"__codelineno-39-10\" name=\"__codelineno-39-10\" href=\"#__codelineno-39-10\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">w</span>\n</span><span id=\"__span-39-11\"><a id=\"__codelineno-39-11\" name=\"__codelineno-39-11\" href=\"#__codelineno-39-11\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-39-12\"><a id=\"__codelineno-39-12\" name=\"__codelineno-39-12\" href=\"#__codelineno-39-12\"></a>\n</span><span id=\"__span-39-13\"><a id=\"__codelineno-39-13\" name=\"__codelineno-39-13\" href=\"#__codelineno-39-13\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nb\">close</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-39-14\"><a id=\"__codelineno-39-14\" name=\"__codelineno-39-14\" href=\"#__codelineno-39-14\"></a><span class=\"w\">    </span><span class=\"c1\">// リソースを閉じる</span>\n</span><span id=\"__span-39-15\"><a id=\"__codelineno-39-15\" name=\"__codelineno-39-15\" href=\"#__codelineno-39-15\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>リソースを閉じる時間になったことを <code>watcher</code> に通知する代わりに、 <code>defer</code> を使用してこの　<code>close</code> メソッドを呼び出し、アプリケーションが終了する前にリソースが確実に閉じられるようにします。 </p>\n<p>まとめると、ゴルーチンは他のリソースと同様、メモリや他のリソースを解放するために最終的に閉じる必要があることに注意してください。ゴルーチンをいつ停止するかを知らずに開始するのは設計上の問題です。ゴルーチンが開始されるときは常に、いつ停止するかについて明確な計画を立てる必要があります。最後になりましたが、ゴルーチンがリソースを作成し、その有効期間がアプリケーションの存続期間にバインドされている場合は、アプリケーションを終了する前にそのゴルーチンが完了するのを待った方がおそらく確実です。そうすることで、リソースを間違いなく解放できます。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/62-starting-goroutine/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"63\">ゴルーチンとループ変数に注意しない (#63)</h3>\n<details class=\"warning\" open=\"open\">\n<summary>注意</summary>\n<p>このミスは Go　1.22 からは気にする必要がありません（<a href=\"https://go.dev/blog/loopvar-preview\">詳細</a>）。</p>\n</details>\n<h3 id=\"select-64\"><code>select</code> とチャネルを使用して決定的動作を期待する (#64)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>複数のオプションが可能な場合、複数のチャネルで <code>select</code> するとケースがランダムに選択されることを理解すると、並行処理における軽微なバグにつながる可能性のある誤った仮定を立てることがなくなります。</p>\n</details>\n<p>Go 開発者がチャネルを操作するときにありがちな間違いの 1 つは、select が複数のチャネルでどのように動作するかについて誤った理解をすることです。 </p>\n<p>たとえば、次の場合を考えてみましょう（ <code>disconnectCh</code> はバッファなしチャネルです）。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-40-1\"><a id=\"__codelineno-40-1\" name=\"__codelineno-40-1\" href=\"#__codelineno-40-1\"></a><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-40-2\"><a id=\"__codelineno-40-2\" name=\"__codelineno-40-2\" href=\"#__codelineno-40-2\"></a><span class=\"w\">  </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">10</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-40-3\"><a id=\"__codelineno-40-3\" name=\"__codelineno-40-3\" href=\"#__codelineno-40-3\"></a><span class=\"w\">      </span><span class=\"nx\">messageCh</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"w\"> </span><span class=\"nx\">i</span>\n</span><span id=\"__span-40-4\"><a id=\"__codelineno-40-4\" name=\"__codelineno-40-4\" href=\"#__codelineno-40-4\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-40-5\"><a id=\"__codelineno-40-5\" name=\"__codelineno-40-5\" href=\"#__codelineno-40-5\"></a><span class=\"w\">    </span><span class=\"nx\">disconnectCh</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"p\">{}{}</span>\n</span><span id=\"__span-40-6\"><a id=\"__codelineno-40-6\" name=\"__codelineno-40-6\" href=\"#__codelineno-40-6\"></a><span class=\"p\">}()</span>\n</span><span id=\"__span-40-7\"><a id=\"__codelineno-40-7\" name=\"__codelineno-40-7\" href=\"#__codelineno-40-7\"></a>\n</span><span id=\"__span-40-8\"><a id=\"__codelineno-40-8\" name=\"__codelineno-40-8\" href=\"#__codelineno-40-8\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-40-9\"><a id=\"__codelineno-40-9\" name=\"__codelineno-40-9\" href=\"#__codelineno-40-9\"></a><span class=\"w\">    </span><span class=\"k\">select</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-40-10\"><a id=\"__codelineno-40-10\" name=\"__codelineno-40-10\" href=\"#__codelineno-40-10\"></a><span class=\"w\">    </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">messageCh</span><span class=\"p\">:</span>\n</span><span id=\"__span-40-11\"><a id=\"__codelineno-40-11\" name=\"__codelineno-40-11\" href=\"#__codelineno-40-11\"></a><span class=\"w\">        </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">v</span><span class=\"p\">)</span>\n</span><span id=\"__span-40-12\"><a id=\"__codelineno-40-12\" name=\"__codelineno-40-12\" href=\"#__codelineno-40-12\"></a><span class=\"w\">    </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">disconnectCh</span><span class=\"p\">:</span>\n</span><span id=\"__span-40-13\"><a id=\"__codelineno-40-13\" name=\"__codelineno-40-13\" href=\"#__codelineno-40-13\"></a><span class=\"w\">        </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"s\">\"disconnection, return\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-40-14\"><a id=\"__codelineno-40-14\" name=\"__codelineno-40-14\" href=\"#__codelineno-40-14\"></a><span class=\"w\">        </span><span class=\"k\">return</span>\n</span><span id=\"__span-40-15\"><a id=\"__codelineno-40-15\" name=\"__codelineno-40-15\" href=\"#__codelineno-40-15\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-40-16\"><a id=\"__codelineno-40-16\" name=\"__codelineno-40-16\" href=\"#__codelineno-40-16\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>この例を複数回実行した場合、結果はランダムになります。</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-41-1\"><a id=\"__codelineno-41-1\" name=\"__codelineno-41-1\" href=\"#__codelineno-41-1\"></a>0\n</span><span id=\"__span-41-2\"><a id=\"__codelineno-41-2\" name=\"__codelineno-41-2\" href=\"#__codelineno-41-2\"></a>1\n</span><span id=\"__span-41-3\"><a id=\"__codelineno-41-3\" name=\"__codelineno-41-3\" href=\"#__codelineno-41-3\"></a>2\n</span><span id=\"__span-41-4\"><a id=\"__codelineno-41-4\" name=\"__codelineno-41-4\" href=\"#__codelineno-41-4\"></a>disconnection, return\n</span><span id=\"__span-41-5\"><a id=\"__codelineno-41-5\" name=\"__codelineno-41-5\" href=\"#__codelineno-41-5\"></a>\n</span><span id=\"__span-41-6\"><a id=\"__codelineno-41-6\" name=\"__codelineno-41-6\" href=\"#__codelineno-41-6\"></a>0\n</span><span id=\"__span-41-7\"><a id=\"__codelineno-41-7\" name=\"__codelineno-41-7\" href=\"#__codelineno-41-7\"></a>disconnection, return\n</span></code></pre></div>\n<p>どういうわけか 10 通のメッセージを消費するのではなく、そのうちの数通だけを受信しました。これは、複数のチャネルと併用した場合の select 文の仕様によるものです（https:// go.dev/ref/spec）。</p>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">Quote</p>\n<p>1 つ以上の通信を続行できる場合、均一の擬似ランダム選択によって、続行できる 1 つの通信が選択されます。 </p>\n</div>\n<p>最初に一致したケースが優先される switch 文とは異なり、select 文は複数のオプションが可能な場合にランダムに選択します。 </p>\n<p>この動作は最初は奇妙に思えるかもしれません。しかし、これはスタベーションを防ぐという理由があってのことです。最初に選択された通信がソースの順序に基づいているとします。その場合、送信速度が速いために、たとえば 1 つのチャネルからしか受信できないという状況に陥る可能性があります。これを防ぐために、Go言語の設計者はランダム選択を使用することにしました。 </p>\n<p>複数のチャネルで <code>select</code> を使用する場合、複数のオプションがあるなら、ソース順序の最初のケースが自動的に優先されるわけではないことに注意する必要があります。代わりに、Go言語はランダムに選択するため、どのオプションが選択されるかは保証されません。この動作を克服するには、単一の生産者ゴルーチンの場合、バッファなしのチャネルまたは単一のチャネルを使用することができます。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/64-select-behavior/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"65\">通知チャネルを使用していない (#65)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>chan struct{}</code> 型を使用して通知を送信しましょう。 </p>\n</details>\n<p>チャネルは、シグナルを介してゴルーチン間で通信するためのメカニズムです。シグナルにはデータが含まれているかどうかは関係ありません。 </p>\n<p>具体的な例を見てみましょう。通信の切断が発生するたびにそれを通知するチャネルを作成します。 1 つの方法として、これを <code>chan bool</code> として扱うことが挙げられます。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-42-1\"><a id=\"__codelineno-42-1\" name=\"__codelineno-42-1\" href=\"#__codelineno-42-1\"></a><span class=\"nx\">disconnectCh</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">bool</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>ここで、そのようなチャネルを提供する API と対話するとします。これは真偽値のチャネルであるため、<code>true</code> または <code>false</code> のメッセージを受信できます。<code>true</code> が何を伝えているかはおそらく明らかでしょう。しかし、 <code>false</code> とは何を意味するのでしょうか。通信が切断されていないということでしょうか。その場合、どれくらいの頻度でそのようなシグナルを受信するのでしょうか。あるいは再接続したということでしょうか。そもそも <code>false</code> を受け取ることを期待すべきなのでしょうか。おそらく <code>true</code> メッセージを受け取ることだけを期待すべきでしょう。 </p>\n<p>その場合、情報を伝えるために特定の値は必要ないことを意味し、データの <em>ない</em> チャネルが必要になります。これを処理する慣用的な方法は、空の構造体のチャネル―― <code>chan struct{}</code>――を使用することです。</p>\n<h3 id=\"nil-66\">nil チャネルを使用していない (#66)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>nil チャネルを使用することによって、たとえば <code>select</code> 文からケースを <em>削除</em> できるため、並行処理を行う際の道具の一つとして使えるようになるべきです。 </p>\n</details>\n<p>次のコードによって何が行われるでしょうか。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-43-1\"><a id=\"__codelineno-43-1\" name=\"__codelineno-43-1\" href=\"#__codelineno-43-1\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span>\n</span><span id=\"__span-43-2\"><a id=\"__codelineno-43-2\" name=\"__codelineno-43-2\" href=\"#__codelineno-43-2\"></a><span class=\"o\">&lt;-</span><span class=\"nx\">ch</span>\n</span></code></pre></div>\n<p><code>ch</code> は <code>chan int</code> 型です。チャネルのゼロ値は nil であるので、 <code>ch</code> は <code>nil</code> です。ゴルーチンは panic を起こしません。ただし、永久にブロックします。 </p>\n<p>nil チャネルにメッセージを送信する場合も原理は同じです。以下のゴルーチンは永久にブロックします。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-44-1\"><a id=\"__codelineno-44-1\" name=\"__codelineno-44-1\" href=\"#__codelineno-44-1\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span>\n</span><span id=\"__span-44-2\"><a id=\"__codelineno-44-2\" name=\"__codelineno-44-2\" href=\"#__codelineno-44-2\"></a><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"w\"> </span><span class=\"mi\">0</span>\n</span></code></pre></div>\n<p>では、Go言語が nil チャネルとの間でメッセージの送受信を許可する目的は何でしょうか。たとえば、2 つのチャネルをマージする慣用的な方法を実装するのに、 nil チャネルを使用することができます。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-45-1\"><a id=\"__codelineno-45-1\" name=\"__codelineno-45-1\" href=\"#__codelineno-45-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">merge</span><span class=\"p\">(</span><span class=\"nx\">ch1</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">ch2</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-45-2\"><a id=\"__codelineno-45-2\" name=\"__codelineno-45-2\" href=\"#__codelineno-45-2\"></a><span class=\"w\">    </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-45-3\"><a id=\"__codelineno-45-3\" name=\"__codelineno-45-3\" href=\"#__codelineno-45-3\"></a>\n</span><span id=\"__span-45-4\"><a id=\"__codelineno-45-4\" name=\"__codelineno-45-4\" href=\"#__codelineno-45-4\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-45-5\"><a id=\"__codelineno-45-5\" name=\"__codelineno-45-5\" href=\"#__codelineno-45-5\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">ch1</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"o\">||</span><span class=\"w\"> </span><span class=\"nx\">ch2</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// 最低でも一つのチャネルが nil でなければ続行する</span>\n</span></span><span id=\"__span-45-6\"><a id=\"__codelineno-45-6\" name=\"__codelineno-45-6\" href=\"#__codelineno-45-6\"></a><span class=\"w\">            </span><span class=\"k\">select</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-45-7\"><a id=\"__codelineno-45-7\" name=\"__codelineno-45-7\" href=\"#__codelineno-45-7\"></a><span class=\"w\">            </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">open</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">ch1</span><span class=\"p\">:</span>\n</span><span id=\"__span-45-8\"><a id=\"__codelineno-45-8\" name=\"__codelineno-45-8\" href=\"#__codelineno-45-8\"></a><span class=\"w\">                </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"p\">!</span><span class=\"nx\">open</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-45-9\"><a id=\"__codelineno-45-9\" name=\"__codelineno-45-9\" href=\"#__codelineno-45-9\"></a><span class=\"hll\"><span class=\"w\">                    </span><span class=\"nx\">ch1</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"c1\">// 閉じたら ch1 を nil チャネルに割り当てる</span>\n</span></span><span id=\"__span-45-10\"><a id=\"__codelineno-45-10\" name=\"__codelineno-45-10\" href=\"#__codelineno-45-10\"></a><span class=\"w\">                    </span><span class=\"k\">break</span>\n</span><span id=\"__span-45-11\"><a id=\"__codelineno-45-11\" name=\"__codelineno-45-11\" href=\"#__codelineno-45-11\"></a><span class=\"w\">                </span><span class=\"p\">}</span>\n</span><span id=\"__span-45-12\"><a id=\"__codelineno-45-12\" name=\"__codelineno-45-12\" href=\"#__codelineno-45-12\"></a><span class=\"w\">                </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"w\"> </span><span class=\"nx\">v</span>\n</span><span id=\"__span-45-13\"><a id=\"__codelineno-45-13\" name=\"__codelineno-45-13\" href=\"#__codelineno-45-13\"></a><span class=\"w\">            </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">open</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">ch2</span><span class=\"p\">:</span>\n</span><span id=\"__span-45-14\"><a id=\"__codelineno-45-14\" name=\"__codelineno-45-14\" href=\"#__codelineno-45-14\"></a><span class=\"w\">                </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"p\">!</span><span class=\"nx\">open</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-45-15\"><a id=\"__codelineno-45-15\" name=\"__codelineno-45-15\" href=\"#__codelineno-45-15\"></a><span class=\"hll\"><span class=\"w\">                    </span><span class=\"nx\">ch2</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"c1\">// 閉じたら ch2 を nil チャネルに割り当てる</span>\n</span></span><span id=\"__span-45-16\"><a id=\"__codelineno-45-16\" name=\"__codelineno-45-16\" href=\"#__codelineno-45-16\"></a><span class=\"w\">                    </span><span class=\"k\">break</span>\n</span><span id=\"__span-45-17\"><a id=\"__codelineno-45-17\" name=\"__codelineno-45-17\" href=\"#__codelineno-45-17\"></a><span class=\"w\">                </span><span class=\"p\">}</span>\n</span><span id=\"__span-45-18\"><a id=\"__codelineno-45-18\" name=\"__codelineno-45-18\" href=\"#__codelineno-45-18\"></a><span class=\"w\">                </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"w\"> </span><span class=\"nx\">v</span>\n</span><span id=\"__span-45-19\"><a id=\"__codelineno-45-19\" name=\"__codelineno-45-19\" href=\"#__codelineno-45-19\"></a><span class=\"w\">            </span><span class=\"p\">}</span>\n</span><span id=\"__span-45-20\"><a id=\"__codelineno-45-20\" name=\"__codelineno-45-20\" href=\"#__codelineno-45-20\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-45-21\"><a id=\"__codelineno-45-21\" name=\"__codelineno-45-21\" href=\"#__codelineno-45-21\"></a><span class=\"w\">        </span><span class=\"nb\">close</span><span class=\"p\">(</span><span class=\"nx\">ch</span><span class=\"p\">)</span>\n</span><span id=\"__span-45-22\"><a id=\"__codelineno-45-22\" name=\"__codelineno-45-22\" href=\"#__codelineno-45-22\"></a><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span><span id=\"__span-45-23\"><a id=\"__codelineno-45-23\" name=\"__codelineno-45-23\" href=\"#__codelineno-45-23\"></a>\n</span><span id=\"__span-45-24\"><a id=\"__codelineno-45-24\" name=\"__codelineno-45-24\" href=\"#__codelineno-45-24\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">ch</span>\n</span><span id=\"__span-45-25\"><a id=\"__codelineno-45-25\" name=\"__codelineno-45-25\" href=\"#__codelineno-45-25\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>この洗練された解決策は、nil チャネルを利用して、何らかの方法で <code>select</code> 文から 1 つのケースを <em>削除</em> します。 </p>\n<p>nil チャネルは状況によっては便利であり、Go 開発者は並行処理を扱う際に使いこなせるようになっておくべきです。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/66-nil-channels/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"67\">チャネルの容量について困惑している (#67)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>問題が発生した場合は、使用するチャネルの型を慎重に決定してください。同期を強力に保証してくれるのはバッファなしチャネルのみです。 </p>\n</details>\n<p>バッファありチャネル以外のチャネルの容量を指定するには正当な理由があるべきです。</p>\n<h3 id=\"etcd-68\">文字列フォーマットで起こり得る副作用を忘れてしまう（ etcd データ競合の例とデッドロック） (#68)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>文字列の書式設定が既存の関数が呼び出す可能性があることを認識することは、デッドロックやその他のデータ競合の可能性に注意することを意味します。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/68-string-formatting/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"append-69\"><code>append</code> でデータ競合を起こしてしまう (#69)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>append</code> の呼び出しは必ずしもデータ競合がないわけではありません。ゆえに、共有スライス上で同時に使用してはいけません。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/69-data-race-append/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"70\">スライスとマップでミューテックスを正しく使用していない (#70)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>スライスとマップはポインタであることを覚えておくと、典型的なデータ競合を防ぐことができます。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/70-mutex-slices-maps/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"syncwaitgroup-71\"><code>sync.WaitGroup</code> を正しく使用していない (#71)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>sync.WaitGroup</code> を正しく使用するには、ゴルーチンを起動する前に <code>Add</code> メソッドを呼び出しましょう。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/71-wait-group/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"synccond-72\"><code>sync.Cond</code> について忘れてしまう (#72)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>sync.Cond</code> を使用すると、複数のゴルーチンに繰り返し通知を送信できます。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/72-cond/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"errgroup-73\"><code>errgroup</code> を使用していない (#73)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>errgroup</code> パッケージを使用して、ゴルーチンのグループを同期し、エラーと Context を処理できます。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/73-errgroup/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"sync-74\"><code>sync</code> 型のコピー (#74)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>sync</code> 型はコピーされるべきではありません。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/74-copying-sync/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h2 id=\"_15\">標準ライブラリ</h2>\n<h3 id=\"75\">間違った時間を指定する (#75)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>time.Duration</code> を受け入れる関数には注意を払ってください。整数を渡すことは許可されていますが、混乱を招かないように time API を使用するよう努めてください。</p>\n</details>\n<p>標準ライブラリの多くの関数は、<code>int64</code> 型のエイリアスである <code>time.Duration</code> を受け入れます。ただし、1 単位の <code>time.Duration</code> は、他のプログラミング言語で一般的に見られる 1 ミリ秒ではなく、1 ナノ秒を表します。その結果、<code>time.Duration</code> API を使用する代わりに数値型を渡すと、予想外の動作が発生する可能性があります。 </p>\n<p>他言語を使用したことのある開発者の方は、次のコードによって 1 秒周期の新しい <code>time.Ticker</code> が生成されると考えるかもしれません。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-46-1\"><a id=\"__codelineno-46-1\" name=\"__codelineno-46-1\" href=\"#__codelineno-46-1\"></a><span class=\"nx\">ticker</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">NewTicker</span><span class=\"p\">(</span><span class=\"mi\">1000</span><span class=\"p\">)</span>\n</span><span id=\"__span-46-2\"><a id=\"__codelineno-46-2\" name=\"__codelineno-46-2\" href=\"#__codelineno-46-2\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-46-3\"><a id=\"__codelineno-46-3\" name=\"__codelineno-46-3\" href=\"#__codelineno-46-3\"></a><span class=\"w\">    </span><span class=\"k\">select</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-46-4\"><a id=\"__codelineno-46-4\" name=\"__codelineno-46-4\" href=\"#__codelineno-46-4\"></a><span class=\"w\">    </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">ticker</span><span class=\"p\">.</span><span class=\"nx\">C</span><span class=\"p\">:</span>\n</span><span id=\"__span-46-5\"><a id=\"__codelineno-46-5\" name=\"__codelineno-46-5\" href=\"#__codelineno-46-5\"></a><span class=\"w\">        </span><span class=\"c1\">// 処理をする</span>\n</span><span id=\"__span-46-6\"><a id=\"__codelineno-46-6\" name=\"__codelineno-46-6\" href=\"#__codelineno-46-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-46-7\"><a id=\"__codelineno-46-7\" name=\"__codelineno-46-7\" href=\"#__codelineno-46-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>しかしながら、1,000 <code>time.Duration</code> = 1,000 ナノ秒であるため、想定されている 1秒 ではなく、1,000 ナノ秒 = 1 マイクロ秒の周期になります。 </p>\n<p>混乱や予想外の動作を招かないよう、いつも <code>time.Duration</code> API を使用するべきです。</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-47-1\"><a id=\"__codelineno-47-1\" name=\"__codelineno-47-1\" href=\"#__codelineno-47-1\"></a><span class=\"nx\">ticker</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">NewTicker</span><span class=\"p\">(</span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">Microsecond</span><span class=\"p\">)</span>\n</span><span id=\"__span-47-2\"><a id=\"__codelineno-47-2\" name=\"__codelineno-47-2\" href=\"#__codelineno-47-2\"></a><span class=\"c1\">// もしくは</span>\n</span><span id=\"__span-47-3\"><a id=\"__codelineno-47-3\" name=\"__codelineno-47-3\" href=\"#__codelineno-47-3\"></a><span class=\"nx\">ticker</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">NewTicker</span><span class=\"p\">(</span><span class=\"mi\">1000</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"w\"> </span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">Nanosecond</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/75-wrong-time-duration/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"timeafter-76\"><code>time.After</code> とメモリリーク (#76)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>繰り返される関数（ループや HTTP ハンドラなど）で <code>time.After</code> の呼び出しを回避すると、ピーク時のメモリ消費を回避できます。<code>time.After</code> によって生成されたリソースは、 timer が終了したときにのみ解放されます。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/76-time-after/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"json-77\">JSON 処理でありがちな間違い (#77)</h3>\n<ul>\n<li>型の埋め込みによる予想外の動作 </li>\n</ul>\n<p>Go 構造体で埋め込みフィールドを使用する場合は注意してください。 なぜなら <code>json.Marshaler</code> インタフェースを実装する time.Time 埋め込みフィールドのようなやっかいなバグが発生して、デフォルトのマーシャリング動作がオーバーライドされる可能性があるからです。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/type-embedding/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<ul>\n<li>JSON と monotonic clock</li>\n</ul>\n<p>2 つの <code>time.Time</code> 構造体を比較する場合、<code>time.Time</code> には wall clock と monotonic clock の両方が含まれており、== 演算子を使用した比較は両方の clock に対して行われることを思い出してください。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/monotonic-clock/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<ul>\n<li><code>any</code> のマップ</li>\n</ul>\n<p>JSON データのアンマーシャリング中にマップを提供するときに間違いを避けるために、数値はデフォルトで <code>float64</code> に変換されることに注意してください。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/map-any/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"sql-78\">SQL でありがちな間違い (#78)</h3>\n<ul>\n<li><code>sql.Open</code> が必ずしもデータベースへの接続を確立するわけではないことを忘れている</li>\n</ul>\n<p>設定を試し、データベースにアクセスできることを確認する必要がある場合は、 <code>Ping</code> または <code>PingContext</code> メソッドを呼び出しましょう。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/sql-open\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<ul>\n<li>コネクションプーリングのことを忘れる </li>\n</ul>\n<p>実運用水準のアプリケーションでは、データベース接続パラメータを設定しましょう。</p>\n<ul>\n<li>プリペアドステートメントを使用していない</li>\n</ul>\n<p>SQL のプリペアドステートメントを使用すると、クエリがより効率的かつ確実になります。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/prepared-statements\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<ul>\n<li>null 値を誤った方法で処理している</li>\n</ul>\n<p>テーブル内の null が許容されている列は、ポインタまたは <code>sql.NullXXX</code> 型を使用して処理しましょう。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/null-values/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<ul>\n<li>行の反復処理によるエラーを処理しない </li>\n</ul>\n<p>行の反復処理の後に <code>sql.Rows</code> の <code>Err</code> メソッドを呼び出して、次の行の準備中にエラーを見逃していないことを確認しましょう。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/rows-iterations-errors\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"http-bodysqlrows-osfile-79\">一時的なリソース（ HTTP body、<code>sql.Rows</code>、および <code>os.File</code> ）を閉じていない (#79)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>リークを避けるために、 <code>io.Closer</code> を実装しているすべての構造体を最後には閉じましょう。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/79-closing-resources/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"http-return-80\">HTTP リクエストに応答した後の return 文を忘れてしまう (#80)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>HTTP ハンドラの実装での予想外の動作を避けるため、<code>http.Error</code> の後にハンドラを停止したい場合は、<code>return</code> 文を忘れないようにしてください。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/80-http-return/main.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"http-81\">標準の HTTP クライアントとサーバーを使用している (#81)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>実運用水準のアプリケーションを求めている場合は、標準の HTTP クライアントとサーバーの実装を使用しないでください。これらの実装には、タイムアウトや稼働環境で必須であるべき動作が欠落しています。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/81-default-http-client-server/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h2 id=\"_16\">テスト</h2>\n<h3 id=\"82\">テストを分類していない（ビルドタグ、環境変数、ショートモード） (#82)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>ビルドフラグ、環境変数、またはショートモードを使用してテストを分類すると、テストプロセスがより効率的になります。ビルドフラグまたは環境変数を使用してテストカテゴリ（たとえば、単体テストと統合テスト）を作成し、短期間のテストと長時間のテストを区別することで、実行するテストの種類を決定できます。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/82-categorizing-tests/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"-race-83\"><code>-race</code> フラグを有効にしていない (#83)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>並行アプリケーションを作成する場合は、 <code>-race</code> フラグを有効にすることを強くお勧めします。そうすることで、ソフトウェアのバグにつながる可能性のある潜在的なデータ競合を発見できるようになります。</p>\n</details>\n<h3 id=\"-parallel-shuffle-84\">テスト実行モード（ <code>-parallel</code> および <code>-shuffle</code> ）を使用していない (#84)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><code>-parallel</code> フラグを使用するのは、特に長時間実行されるテストを高速化するのに効果的です。 <code>-shuffle</code> フラグを使用すると、テストスイートがバグを隠す可能性のある間違った仮定に依存しないようにすることができます。</p>\n</details>\n<h3 id=\"85\">テーブル駆動テストを使用しない (#85)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>テーブル駆動テストは、コードの重複を防ぎ、将来の更新の処理を容易にするために、一連の類似したテストをグループ化する効率的な方法です。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/85-table-driven-tests/main_test.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"86\">単体テストでのスリープ (#86)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>テストの不安定さをなくし、より堅牢にするために、同期を使用してスリープを回避しましょう。同期が不可能な場合は、リトライ手法を検討してください。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/86-sleeping/main_test.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"time-api-87\">time API を効率的に処理できていない (#87)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>time API を使用して関数を処理する方法を理解することで、テストの不安定さを軽減することができます。隠れた依存関係の一部として time を処理したり、クライアントに time を提供するように要求したりするなど、標準的な手段を利用できます。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/87-time-api/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"httptest-iotest-88\">テストに関するユーティリティパッケージ（ <code>httptest</code> および <code>iotest</code> ）を使用していない (#88)</h3>\n<ul>\n<li><code>httptest</code> パッケージは、HTTP アプリケーションを扱うのに役立ちます。クライアントとサーバーの両方をテストするための一連のユーティリティを提供します。</li>\n</ul>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/88-utility-package/httptest/main_test.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<ul>\n<li><code>iotest</code> パッケージは、io.Reader を作成し、アプリケーションのエラー耐性をテストするのに役立ちます。</li>\n</ul>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/88-utility-package/iotest/main_test.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"89\">不正確なベンチマークの作成 (#89)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>ベンチマークについて</p>\n<ul>\n<li>ベンチマークの精度を維持するには、time メソッドを使用しましょう。 </li>\n<li>ベンチタイムを増やすか、benchstat などのツールを使用することで、マイクロベンチマークが扱いやすくなります。 </li>\n<li>アプリケーションを最終的に実行するシステムがマイクロベンチマークを実行するシステムと異なる場合は、マイクロベンチマークの結果に注意してください。 </li>\n<li>コンパイラの最適化によってベンチマークの結果が誤魔化されないよう、テスト対象の関数が副作用を引き起こすようにしてください。 </li>\n<li>オブザーバー効果を防ぐには、CPU に依存する関数が使用するデータをベンチマークが再生成するよう強制してください。</li>\n</ul>\n</details>\n<p>セクション全文は<a href=\"../89-benchmarks/\">こちら</a>。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/89-benchmark/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"go-90\">Go言語のテスト機能をすべて試していない (#90)</h3>\n<ul>\n<li>コードカバレッジ </li>\n</ul>\n<p>コードのどの部分に注意が必要かをすぐに確認するために、<code>-coverprofile</code> フラグを指定してコードカバレッジを使用しましょう。 </p>\n<ul>\n<li>別のパッケージからのテスト </li>\n</ul>\n<p>内部ではなく公開された動作に焦点を当てたテストの作成を強制するために、単体テストは別々のパッケージに配置しましょう。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/different-package/main_test.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<ul>\n<li>ユーティリティ関数 </li>\n</ul>\n<p>従来の <code>if err != nil</code> の代わりに <code>*testing.T</code> 変数を使用してエラーを処理すると、コードが短く、読みやすくなります。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/utility-function/main_test.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<ul>\n<li>setup と teardown</li>\n</ul>\n<p>setup および teardown 機能を利用して、統合テストの場合など、複雑な環境を構成できます。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/setup-teardown/main_test.go\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"community-mistake\">ファジングを使用していない（community mistake）</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>ファジングは、複雑な関数やメソッドへのランダムな、予想外の、または不正な入力を検出し、脆弱性、バグ、さらには潜在的なクラッシュを発見するのに効率的です。</p>\n</details>\n<p><a href=\"https://github.com/jeromedoucet\">@jeromedoucet</a> さんのご協力に感謝いたします。</p>\n<h2 id=\"_17\">最適化</h2>\n<h3 id=\"cpu-91\">CPU キャッシュを理解していない (#91)</h3>\n<ul>\n<li>CPU アーキテクチャ </li>\n</ul>\n<p>L1 キャッシュはメインメモリよりも約 50 ～ 100 倍高速であるため、CPU バウンドのアプリケーションを最適化するには、CPU キャッシュの使用方法を理解することが重要です。 </p>\n<ul>\n<li>キャッシュライン </li>\n</ul>\n<p>キャッシュラインの概念を意識することは、データ集約型アプリケーションでデータを整理する方法を理解するのに重要です。CPU はメモリをワードごとにフェッチしません。代わりに、通常はメモリブロックを 64 バイトのキャッシュラインにコピーします。個々のキャッシュラインを最大限に活用するには、空間的局所性を強制してください。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/cache-line/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<ul>\n<li>構造体のスライスとスライスの構造体</li>\n</ul>\n<!-- TODO -->\n\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/slice-structs/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<ul>\n<li>予測可能性 </li>\n</ul>\n<p>CPU にとって予測可能なコードにすることは、特定の関数を最適化する効率的な方法でもあります。たとえば、ユニットまたは定数ストライドは CPU にとって予測可能ですが、非ユニットストライド（連結リストなど）は予測できません。</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/predictability/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<ul>\n<li>キャッシュ配置ポリシー </li>\n</ul>\n<p>キャッシュがパーティション化されていることを認識することで、重大なストライドを回避し、キャッシュのごく一部のみを使用するようにすることができます。</p>\n<h3 id=\"92\">誤った共有を引き起こす並行処理(#92)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>下位レベルの CPU キャッシュがすべてのコアで共有されるわけではないことを知っておくと、並行処理におけるの誤った共有などでパフォーマンスを低下させてしまうことを回避できます。メモリの共有はありえないのです。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/92-false-sharing/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"93\">命令レベルの並列性を考慮しない (#93)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>命令レベルの並列性（<abbr title=\"Instruction-Level Parallelism\">ILP</abbr>）を使用してコードの特定の部分を最適化し、CPU ができるだけ多くの命令を並列実行できるようにしましょう。主な手順の 1 つにデータハザードの特定があります。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/93-instruction-level-parallelism/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"94\">データの配置を意識していない (#94)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>Go言語では、基本型は各々のサイズに合わせて配置されることを覚えておくことで、ありがちな間違いを避けることができます。たとえば、構造体のフィールドをサイズで降順に再編成すると、構造体がよりコンパクトになる（メモリ割り当てが少なくなり、空間的局所性が向上する）可能性があることに留意してください。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/94-data-alignment/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"95\">ヒープとスタックの違いを理解していない (#95)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>ヒープとスタックの基本的な違いを理解することも、Go アプリケーションを最適化する際には大切です。スタック割り当ては容易なのに対して、ヒープ割り当ては遅く、メモリのクリーンアップに <abbr title=\"Garbage Collector\">GC</abbr> を利用します。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/95-stack-heap/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"api-syncpool-96\">割り当てを減らす方法がわかっていない（ API の変更、コンパイラの最適化、および <code>sync.Pool</code>） (#96)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>割り当てを減らすことも、Go アプリケーションを最適化する上で重要です。これは、共有を防ぐために API を慎重に設計する、一般的な Go コンパイラの最適化を理解する、<code>sync.Pool</code> を使用するなど、さまざまな方法で行うことができます。</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/96-reduce-allocations/\">ソースコード <span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span></a></p>\n<h3 id=\"97\">インライン展開をしていない (#97)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>ファストパスのインライン化手法を使用して、関数の呼び出しにかかる償却時間を効率的に削減しましょう。</p>\n</details>\n<h3 id=\"go-98\">Go言語の診断ツールを利用していない (#98)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>プロファイリングと実行トレーサを利用して、アプリケーションのパフォーマンスと最適化すべき部分について理解しましょう。</p>\n</details>\n<p>セクション全文は<a href=\"../98-profiling-execution-tracing/\">こちら</a>。</p>\n<h3 id=\"gc-99\"><abbr title=\"Garbage Collector\">GC</abbr> の仕組みを理解していない (#99)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p><abbr title=\"Garbage Collector\">GC</abbr> の調整方法を理解すると、突然の負荷の増加をより効率的に処理できるなど、さまざまな恩恵が得られます。</p>\n</details>\n<h3 id=\"docker-kubernetes-go-100\">Docker と Kubernetes 上でGo言語を実行することの影響を理解していない (#100)</h3>\n<details class=\"info\" open=\"open\">\n<summary>要約</summary>\n<p>Docker と Kubernetes にデプロイする際の CPU スロットリングを回避するには、Go言語が <abbr title=\"Completely Fair Scheduler\">CFS</abbr> 対応ではないことに留意してください。</p>\n</details>\n\n\n\n\n\n\n\n  \n  \n\n\n\n  \n\n\n\n\n<h2 id=\"__comments\">Comments</h2>\n<!-- Insert generated snippet here -->\n<script src=\"https://giscus.app/client.js\" data-repo=\"teivah/100-go-mistakes\" data-repo-id=\"MDEwOlJlcG9zaXRvcnkzMjA4MTg5NjI=\" data-category=\"Discussions\" data-category-id=\"DIC_kwDOEx9PEs4CZQUm\" data-mapping=\"pathname\" data-strict=\"0\" data-reactions-enabled=\"1\" data-emit-metadata=\"0\" data-input-position=\"bottom\" data-theme=\"preferred_color_scheme\" data-lang=\"en\" crossorigin=\"anonymous\" async>\n</script>\n<!-- Synchronize Giscus theme with palette -->\n<script>\n  var giscus = document.querySelector(\"script[src*=giscus]\")\n\n  // Set palette on initial load\n  var palette = __md_get(\"__palette\")\n  if (palette && typeof palette.color === \"object\") {\n    var theme = palette.color.scheme === \"slate\"\n        ? \"transparent_dark\"\n        : \"light\"\n\n    // Instruct Giscus to set theme\n    giscus.setAttribute(\"data-theme\", theme)\n  }\n\n  // Register event handlers after documented loaded\n  document.addEventListener(\"DOMContentLoaded\", function() {\n    var ref = document.querySelector(\"[data-md-component=palette]\")\n    ref.addEventListener(\"change\", function() {\n      var palette = __md_get(\"__palette\")\n      if (palette && typeof palette.color === \"object\") {\n        var theme = palette.color.scheme === \"slate\"\n            ? \"transparent_dark\"\n            : \"light\"\n\n        // Instruct Giscus to change theme\n        var frame = document.querySelector(\".giscus-frame\")\n        frame.contentWindow.postMessage(\n            { giscus: { setConfig: { theme } } },\n            \"https://giscus.app\"\n        )\n      }\n    })\n  })\n</script>\n\n                \n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright © 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"></path></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \"..\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"../assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"../assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  \n<script id=\"init-glightbox\">const lightbox = GLightbox({\"touchNavigation\": true, \"loop\": false, \"zoomable\": true, \"draggable\": true, \"openEffect\": \"zoom\", \"closeEffect\": \"zoom\", \"slideEffect\": \"slide\"});\ndocument$.subscribe(()=>{ lightbox.reload(); });\n</script></body></html>"
  },
  {
    "path": "site/pt-br/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\" class=\"no-js\"><head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n      \n      \n        <link rel=\"canonical\" href=\"https://100go.co/pt-br/\">\n      \n      \n        <link rel=\"prev\" href=\"../ja/\">\n      \n      \n        <link rel=\"next\" href=\"../book/\">\n      \n      \n      <link rel=\"icon\" href=\"../img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>Brazilian Portuguese Version - 100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"../assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\"..\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n      \n        <meta property=\"og:type\" content=\"website\">\n      \n        <meta property=\"og:title\" content=\"Brazilian Portuguese Version - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta property=\"og:description\" content=\"None\">\n      \n        <meta property=\"og:image\" content=\"https://100go.co/assets/images/social/pt-br.png\">\n      \n        <meta property=\"og:image:type\" content=\"image/png\">\n      \n        <meta property=\"og:image:width\" content=\"1200\">\n      \n        <meta property=\"og:image:height\" content=\"630\">\n      \n        <meta property=\"og:url\" content=\"https://100go.co/pt-br/\">\n      \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n      \n        <meta name=\"twitter:title\" content=\"Brazilian Portuguese Version - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta name=\"twitter:description\" content=\"None\">\n      \n        <meta name=\"twitter:image\" content=\"https://100go.co/assets/images/social/pt-br.png\">\n      \n    \n    \n  <link href=\"../assets/stylesheets/glightbox.min.css\" rel=\"stylesheet\"><script src=\"../assets/javascripts/glightbox.min.js\"></script><style id=\"glightbox-style\">\n            html.glightbox-open { overflow: initial; height: 100%; }\n            .gslide-title { margin-top: 0px; user-select: text; }\n            .gslide-desc { color: #666; user-select: text; }\n            .gslide-image img { background: white; }\n            .gscrollbar-fixer { padding-right: 15px; }\n            .gdesc-inner { font-size: 0.75rem; }\n            body[data-md-color-scheme=\"slate\"] .gdesc-inner { background: var(--md-default-bg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-title { color: var(--md-default-fg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-desc { color: var(--md-default-fg-color); }\n        </style></head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n        \n        <a href=\"#erros-comuns-de-go\" class=\"md-skip\">\n          Skip to content\n        </a>\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"></path></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              Brazilian Portuguese Version\n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"></path></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"></path></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"></path></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n    \n  \n  \n    \n    \n      <li class=\"md-tabs__item md-tabs__item--active\">\n        <a href=\"..\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"../book/\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n        \n        \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"..\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../5-interface-pollution/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../9-generics/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../20-slice/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../28-maps-memory-leaks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../56-concurrency-faster/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../89-benchmarks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../92-false-sharing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../98-profiling-execution-tracing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1_3\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../zh/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../ja/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    <li class=\"md-nav__item md-nav__item--active\">\n      \n      <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n      \n      \n        \n      \n      \n        <label class=\"md-nav__link md-nav__link--active\" for=\"__toc\">\n          \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n          <span class=\"md-nav__icon md-icon\"></span>\n        </label>\n      \n      <a href=\"./\" class=\"md-nav__link md-nav__link--active\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n      \n        \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#codigo-e-organizacao-do-projeto\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Código e Organização do Projeto\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Código e Organização do Projeto\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#sombreamento-nao-intencional-de-variavel-1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Sombreamento não intencional de variável (#1)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#codigo-aninhado-desnecessario-2\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Código aninhado desnecessário (#2)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#uso-indevido-de-funcoes-init-3\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Uso indevido de funções init (#3)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#uso-excessivo-de-getters-e-setters-4\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Uso excessivo de getters e setters (#4)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#interface-poluidas-5\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Interface poluidas (#5)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#interface-do-lado-do-producer-6\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Interface do lado do producer (#6)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#interfaces-de-retorno-7\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Interfaces de retorno (#7)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#any-nao-diz-nada-8\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      any não diz nada (#8)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ficar-confuso-sobre-quando-usar-genericos-9\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ficar confuso sobre quando usar genéricos (#9)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-estar-ciente-dos-possiveis-problemas-com-a-incorporacao-de-tipos-10\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não estar ciente dos possíveis problemas com a incorporação de tipos (#10)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-o-padrao-de-opcoes-funcionais-functional-options-pattern-11\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar o padrão de opções funcionais (functional options pattern) (#11)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#desorganizacao-do-projeto-estrutura-do-projeto-e-organizacao-do-pacote-12\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Desorganização do projeto (estrutura do projeto e organização do pacote) (#12)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#criando-pacotes-de-utilitarios-13\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Criando pacotes de utilitários (#13)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignorando-colisoes-de-nomes-de-pacotes-14\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignorando colisões de nomes de pacotes (#14)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#documentacao-de-codigo-ausente-15\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Documentação de código ausente (#15)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usando-linters-16\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usando linters (#16)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#tipos-de-dados\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Tipos de dados\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Tipos de dados\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#criando-confusao-com-literais-octais-17\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Criando confusão com literais octais (#17)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#negligenciando-estouros-de-numero-inteiro-18\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Negligenciando estouros de número inteiro (#18)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entendendo-os-pontos-flutuantes-19\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entendendo os pontos flutuantes (#19)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entendendo-o-comprimento-e-a-capacidade-de-slice-20\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entendendo o comprimento e a capacidade de slice (#20)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#inicializacao-de-slice-ineficiente-21\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Inicialização de slice ineficiente (#21)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#estar-confuso-sobre-slice-nula-vs-slice-vazia-22\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Estar confuso sobre slice nula vs. slice vazia (#22)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-verificar-corretamente-se-um-slice-esta-vazio-23\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não verificar corretamente se um slice está vazio (#23)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-fazer-copias-de-slcies-corretamente-24\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não fazer cópias de slcies corretamente (#24)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#efeitos-colaterais-inesperados-usando-o-slice-append-25\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Efeitos colaterais inesperados usando o slice append (#25)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slices-e-vazamentos-de-memoria-26\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Slices e vazamentos de memória (#26)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Slices e vazamentos de memória (#26)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#vazamento-de-capacidade\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Vazamento de capacidade\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-e-ponteiros\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Slice e ponteiros\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#inicializacao-ineficiente-do-mapa-27\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Inicialização ineficiente do mapa (#27)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#mapas-e-vazamentos-de-memoria-28\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Mapas e vazamentos de memória (#28)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#comparando-valores-incorretamente-29\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Comparando valores incorretamente (#29)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#estruturas-de-controle\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Estruturas de Controle\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Estruturas de Controle\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignorando-que-os-elementos-sao-copiados-em-loops-de-range-30\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignorando que os elementos são copiados em loops de range (#30)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignorando-como-os-argumentos-sao-avaliados-em-range-loops-canais-e-arrays-31\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignorando como os argumentos são avaliados em range loops (canais e arrays) (#31)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignorando-os-impactos-do-uso-de-elementos-ponteiros-em-range-loops-32\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignorando os impactos do uso de elementos ponteiros em range loops (#32)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#fazendo-suposicoes-erradas-durante-as-iteracoes-de-maps-ordenacao-e-insercao-do-mapa-durante-a-iteracao-33\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Fazendo suposições erradas durante as iterações de maps (ordenação e inserção do mapa durante a iteração) (#33)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignorando-como-a-declaracao-break-funciona-34\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignorando como a declaração break funciona (#34)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#usando-defer-dentro-de-um-loop-35\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Usando defer dentro de um loop (#35)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#strings\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Strings\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Strings\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entendendo-o-conceito-de-rune-36\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entendendo o conceito de rune (#36)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#iteracao-de-string-imprecisa-37\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Iteração de string imprecisa (#37)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#uso-indevido-de-funcoes-de-trim-38\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Uso indevido de funções de trim (#38)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#concatenacao-de-strings-subotimizada-39\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Concatenação de strings subotimizada (#39)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#conversoes-de-string-inuteis-40\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Conversões de string inúteis (#40)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#vazamentos-de-substring-e-memoria-41\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Vazamentos de substring e memória (#41)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#functions-and-methods\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Functions and Methods\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Functions and Methods\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-saber-que-tipo-de-receptor-usar-42\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não saber que tipo de receptor usar (#42)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nunca-usando-parametros-de-resultado-nomeados-43\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Nunca usando parâmetros de resultado nomeados (#43)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#efeitos-colaterais-nao-intencionais-com-parametros-de-resultado-nomeados-44\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Efeitos colaterais não intencionais com parâmetros de resultado nomeados (#44)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#retornando-um-receptor-nulo-45\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Retornando um receptor nulo (#45)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#usando-um-nome-de-arquivo-como-entrada-de-funcao-46\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Usando um nome de arquivo como entrada de função (#46)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignorando-como-argumentos-defer-e-receptores-sao-avaliados-avaliacao-de-argumentos-ponteiros-e-receptores-de-valor-47\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignorando como argumentos defer e receptores são avaliados (avaliação de argumentos, ponteiros e receptores de valor) (#47)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#error-management\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Error Management\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Error Management\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#panico-48\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Pânico (#48)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignorando-quando-embrulhar-um-erro-49\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignorando quando embrulhar um erro (#49)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#comparando-um-tipo-de-erro-de-forma-imprecisa-50\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Comparando um tipo de erro de forma imprecisa (#50)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#comparando-um-valor-de-erro-incorretamente-51\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Comparando um valor de erro incorretamente (#51)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#lidando-com-um-erro-duas-vezes-52\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Lidando com um erro duas vezes (#52)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-tratando-de-um-erro-53\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não tratando de um erro (#53)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-tratando-erros-de-defer-54\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não tratando erros de defer (#54)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#concurrency-foundations\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Concurrency: Foundations\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Concurrency: Foundations\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#misturando-simultaneidade-e-paralelismo-55\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Misturando simultaneidade e paralelismo (#55)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#pensar-que-a-simultaneidade-e-sempre-mais-rapida-56\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Pensar que a simultaneidade é sempre mais rápida (#56)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ficar-confuso-sobre-quando-usar-canais-ou-mutexes-57\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ficar confuso sobre quando usar canais ou mutexes (#57)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entender-os-problemas-de-corrida-corridas-de-dados-vs-condicoes-de-corrida-e-o-modelo-de-memoria-go-58\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entender os problemas de corrida (corridas de dados vs. condições de corrida e o modelo de memória Go) (#58)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Não entender os problemas de corrida (corridas de dados vs. condições de corrida e o modelo de memória Go) (#58)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#data-race\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Data Race\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#race-condition\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Race Condition\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-compreender-os-impactos-de-simultaneidade-de-um-tipo-de-carga-de-trabalho-59\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não compreender os impactos de simultaneidade de um tipo de carga de trabalho (#59)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#incompreensao-dos-contextos-go-60\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Incompreensão dos contextos Go (#60)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Incompreensão dos contextos Go (#60)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#deadline\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Deadline\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#cancellation-signals\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Cancellation signals\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#context-values\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Context values\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#catching-a-context-cancellation\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Catching a context cancellation\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#concurrency-practice\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Concurrency: Practice\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Concurrency: Practice\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#propagando-um-contexto-improprio-61\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Propagando um contexto impróprio (#61)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#iniciando-uma-goroutine-sem-saber-quando-interrompe-la-62\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Iniciando uma goroutine sem saber quando interrompê-la (#62)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-ter-cuidado-com-goroutines-e-variaveis-de-loop-63\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não ter cuidado com goroutines e variáveis ​​de loop (#63)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#esperando-um-comportamento-deterministico-usando-selecao-e-canais-64\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Esperando um comportamento determinístico usando seleção e canais (#64)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-canais-de-notificacao-65\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar canais de notificação (#65)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-canais-nulos-66\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar canais nulos (#66)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ficar-intrigado-com-o-tamanho-do-canal-67\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ficar intrigado com o tamanho do canal (#67)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#esquecendo-os-possiveis-efeitos-colaterais-da-formatacao-de-strings-68\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Esquecendo os possíveis efeitos colaterais da formatação de strings (#68)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Esquecendo os possíveis efeitos colaterais da formatação de strings (#68)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#etcd-data-race\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      etcd data race\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#deadlock\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Deadlock\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#criando-corridas-de-dados-com-acrescimo-69\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Criando corridas de dados com acréscimo (#69)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#usando-mutexes-imprecisamente-com-slices-e-maps-70\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Usando mutexes imprecisamente com slices e maps (#70)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#uso-indevido-syncwaitgroup-71\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Uso indevido sync.WaitGroup (#71)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#esquecendo-synccond-72\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Esquecendo sync.Cond (#72)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usando-errgroup-73\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usando errgroup (#73)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#copiando-um-tipo-sync-74\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Copiando um tipo sync (#74)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#standard-library\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Standard Library\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Standard Library\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#fornecendo-uma-duracao-de-tempo-errada-75\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Fornecendo uma duração de tempo errada (#75)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#timeafter-e-vazamentos-de-memoria-76\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      time.After e vazamentos de memória (#76)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#lidando-com-erros-comuns-json-77\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Lidando com erros comuns JSON (#77)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#erros-comuns-de-sql-78\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Erros comuns de SQL (#78)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-fechando-recursos-transitorios-body-http-sqlrows-e-osfile-79\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não fechando recursos transitórios (body HTTP, sql.Rows e os.File) (#79)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#esquecendo-a-instrucao-return-apos-responder-a-uma-solicitacao-http-80\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Esquecendo a instrução return após responder a uma solicitação HTTP (#80)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#usando-o-cliente-e-servidor-http-padrao-81\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Usando o cliente e servidor HTTP padrão (#81)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#teste\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Teste\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Teste\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-categorizar-testes-tags-de-construcao-variaveis-de-ambiente-e-modo-abreviado-82\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não categorizar testes (tags de construção, variáveis ​​de ambiente e modo abreviado) (#82)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-habilitando-a-bandeira-de-corrida-83\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não habilitando a bandeira de corrida (#83)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-modos-de-execucao-de-teste-paralelo-e-aleatorio-84\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar modos de execução de teste (paralelo e aleatório) (#84)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-testes-baseados-em-tabela-85\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar testes baseados em tabela (#85)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#dormindo-em-testes-unitarios-86\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Dormindo em testes unitários (#86)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-lidar-com-a-api-de-tempo-de-forma-eficiente-87\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não lidar com a API de tempo de forma eficiente (#87)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-pacotes-de-utilitarios-de-teste-httptest-e-iotest-88\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar pacotes de utilitários de teste ( httptest e iotest) (#88)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#escrevendo-benchmarks-imprecisos-89\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Escrevendo benchmarks imprecisos (#89)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-explorando-todos-os-recursos-de-teste-do-go-90\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não explorando todos os recursos de teste do Go (#90)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-fuzzing-erro-da-comunidade\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar fuzzing (erro da comunidade)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#otimizacoes\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Otimizações\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Otimizações\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entendendo-os-caches-da-cpu-91\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entendendo os caches da CPU (#91)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#escrevendo-codigo-simultaneo-que-leva-a-compartilhamento-falso-92\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Escrevendo código simultâneo que leva a compartilhamento falso (#92)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-levando-em-consideracao-o-paralelismo-no-nivel-de-instrucao-93\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não levando em consideração o paralelismo no nível de instrução (#93)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-estar-ciente-do-alinhamento-dos-dados-94\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não estar ciente do alinhamento dos dados (#94)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entendendo-stack-vs-heap-95\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entendendo stack vs. heap (#95)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-saber-como-reduzir-alocacoes-mudanca-de-api-otimizacoes-de-compilador-e-syncpool-96\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não saber como reduzir alocações (mudança de API, otimizações de compilador e sync.Pool) (#96)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-dependendo-do-inlining-97\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não dependendo do inlining (#97)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-ferramentas-de-diagnostico-go-98\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar ferramentas de diagnóstico Go (#98)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entendendo-como-funciona-o-gc-99\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entendendo como funciona o GC (#99)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entendendo-os-impactos-da-execucao-do-go-no-docker-e-kubernetes-100\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entendendo os impactos da execução do Go no Docker e Kubernetes (#100)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#community\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Community\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../book/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../chapter-1/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../external/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#codigo-e-organizacao-do-projeto\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Código e Organização do Projeto\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Código e Organização do Projeto\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#sombreamento-nao-intencional-de-variavel-1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Sombreamento não intencional de variável (#1)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#codigo-aninhado-desnecessario-2\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Código aninhado desnecessário (#2)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#uso-indevido-de-funcoes-init-3\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Uso indevido de funções init (#3)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#uso-excessivo-de-getters-e-setters-4\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Uso excessivo de getters e setters (#4)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#interface-poluidas-5\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Interface poluidas (#5)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#interface-do-lado-do-producer-6\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Interface do lado do producer (#6)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#interfaces-de-retorno-7\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Interfaces de retorno (#7)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#any-nao-diz-nada-8\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      any não diz nada (#8)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ficar-confuso-sobre-quando-usar-genericos-9\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ficar confuso sobre quando usar genéricos (#9)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-estar-ciente-dos-possiveis-problemas-com-a-incorporacao-de-tipos-10\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não estar ciente dos possíveis problemas com a incorporação de tipos (#10)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-o-padrao-de-opcoes-funcionais-functional-options-pattern-11\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar o padrão de opções funcionais (functional options pattern) (#11)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#desorganizacao-do-projeto-estrutura-do-projeto-e-organizacao-do-pacote-12\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Desorganização do projeto (estrutura do projeto e organização do pacote) (#12)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#criando-pacotes-de-utilitarios-13\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Criando pacotes de utilitários (#13)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignorando-colisoes-de-nomes-de-pacotes-14\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignorando colisões de nomes de pacotes (#14)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#documentacao-de-codigo-ausente-15\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Documentação de código ausente (#15)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usando-linters-16\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usando linters (#16)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#tipos-de-dados\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Tipos de dados\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Tipos de dados\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#criando-confusao-com-literais-octais-17\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Criando confusão com literais octais (#17)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#negligenciando-estouros-de-numero-inteiro-18\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Negligenciando estouros de número inteiro (#18)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entendendo-os-pontos-flutuantes-19\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entendendo os pontos flutuantes (#19)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entendendo-o-comprimento-e-a-capacidade-de-slice-20\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entendendo o comprimento e a capacidade de slice (#20)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#inicializacao-de-slice-ineficiente-21\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Inicialização de slice ineficiente (#21)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#estar-confuso-sobre-slice-nula-vs-slice-vazia-22\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Estar confuso sobre slice nula vs. slice vazia (#22)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-verificar-corretamente-se-um-slice-esta-vazio-23\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não verificar corretamente se um slice está vazio (#23)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-fazer-copias-de-slcies-corretamente-24\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não fazer cópias de slcies corretamente (#24)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#efeitos-colaterais-inesperados-usando-o-slice-append-25\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Efeitos colaterais inesperados usando o slice append (#25)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slices-e-vazamentos-de-memoria-26\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Slices e vazamentos de memória (#26)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Slices e vazamentos de memória (#26)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#vazamento-de-capacidade\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Vazamento de capacidade\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-e-ponteiros\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Slice e ponteiros\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#inicializacao-ineficiente-do-mapa-27\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Inicialização ineficiente do mapa (#27)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#mapas-e-vazamentos-de-memoria-28\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Mapas e vazamentos de memória (#28)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#comparando-valores-incorretamente-29\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Comparando valores incorretamente (#29)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#estruturas-de-controle\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Estruturas de Controle\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Estruturas de Controle\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignorando-que-os-elementos-sao-copiados-em-loops-de-range-30\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignorando que os elementos são copiados em loops de range (#30)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignorando-como-os-argumentos-sao-avaliados-em-range-loops-canais-e-arrays-31\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignorando como os argumentos são avaliados em range loops (canais e arrays) (#31)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignorando-os-impactos-do-uso-de-elementos-ponteiros-em-range-loops-32\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignorando os impactos do uso de elementos ponteiros em range loops (#32)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#fazendo-suposicoes-erradas-durante-as-iteracoes-de-maps-ordenacao-e-insercao-do-mapa-durante-a-iteracao-33\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Fazendo suposições erradas durante as iterações de maps (ordenação e inserção do mapa durante a iteração) (#33)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignorando-como-a-declaracao-break-funciona-34\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignorando como a declaração break funciona (#34)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#usando-defer-dentro-de-um-loop-35\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Usando defer dentro de um loop (#35)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#strings\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Strings\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Strings\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entendendo-o-conceito-de-rune-36\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entendendo o conceito de rune (#36)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#iteracao-de-string-imprecisa-37\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Iteração de string imprecisa (#37)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#uso-indevido-de-funcoes-de-trim-38\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Uso indevido de funções de trim (#38)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#concatenacao-de-strings-subotimizada-39\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Concatenação de strings subotimizada (#39)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#conversoes-de-string-inuteis-40\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Conversões de string inúteis (#40)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#vazamentos-de-substring-e-memoria-41\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Vazamentos de substring e memória (#41)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#functions-and-methods\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Functions and Methods\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Functions and Methods\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-saber-que-tipo-de-receptor-usar-42\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não saber que tipo de receptor usar (#42)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nunca-usando-parametros-de-resultado-nomeados-43\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Nunca usando parâmetros de resultado nomeados (#43)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#efeitos-colaterais-nao-intencionais-com-parametros-de-resultado-nomeados-44\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Efeitos colaterais não intencionais com parâmetros de resultado nomeados (#44)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#retornando-um-receptor-nulo-45\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Retornando um receptor nulo (#45)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#usando-um-nome-de-arquivo-como-entrada-de-funcao-46\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Usando um nome de arquivo como entrada de função (#46)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignorando-como-argumentos-defer-e-receptores-sao-avaliados-avaliacao-de-argumentos-ponteiros-e-receptores-de-valor-47\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignorando como argumentos defer e receptores são avaliados (avaliação de argumentos, ponteiros e receptores de valor) (#47)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#error-management\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Error Management\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Error Management\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#panico-48\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Pânico (#48)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ignorando-quando-embrulhar-um-erro-49\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ignorando quando embrulhar um erro (#49)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#comparando-um-tipo-de-erro-de-forma-imprecisa-50\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Comparando um tipo de erro de forma imprecisa (#50)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#comparando-um-valor-de-erro-incorretamente-51\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Comparando um valor de erro incorretamente (#51)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#lidando-com-um-erro-duas-vezes-52\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Lidando com um erro duas vezes (#52)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-tratando-de-um-erro-53\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não tratando de um erro (#53)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-tratando-erros-de-defer-54\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não tratando erros de defer (#54)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#concurrency-foundations\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Concurrency: Foundations\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Concurrency: Foundations\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#misturando-simultaneidade-e-paralelismo-55\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Misturando simultaneidade e paralelismo (#55)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#pensar-que-a-simultaneidade-e-sempre-mais-rapida-56\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Pensar que a simultaneidade é sempre mais rápida (#56)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ficar-confuso-sobre-quando-usar-canais-ou-mutexes-57\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ficar confuso sobre quando usar canais ou mutexes (#57)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entender-os-problemas-de-corrida-corridas-de-dados-vs-condicoes-de-corrida-e-o-modelo-de-memoria-go-58\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entender os problemas de corrida (corridas de dados vs. condições de corrida e o modelo de memória Go) (#58)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Não entender os problemas de corrida (corridas de dados vs. condições de corrida e o modelo de memória Go) (#58)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#data-race\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Data Race\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#race-condition\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Race Condition\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-compreender-os-impactos-de-simultaneidade-de-um-tipo-de-carga-de-trabalho-59\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não compreender os impactos de simultaneidade de um tipo de carga de trabalho (#59)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#incompreensao-dos-contextos-go-60\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Incompreensão dos contextos Go (#60)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Incompreensão dos contextos Go (#60)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#deadline\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Deadline\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#cancellation-signals\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Cancellation signals\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#context-values\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Context values\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#catching-a-context-cancellation\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Catching a context cancellation\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#concurrency-practice\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Concurrency: Practice\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Concurrency: Practice\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#propagando-um-contexto-improprio-61\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Propagando um contexto impróprio (#61)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#iniciando-uma-goroutine-sem-saber-quando-interrompe-la-62\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Iniciando uma goroutine sem saber quando interrompê-la (#62)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-ter-cuidado-com-goroutines-e-variaveis-de-loop-63\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não ter cuidado com goroutines e variáveis ​​de loop (#63)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#esperando-um-comportamento-deterministico-usando-selecao-e-canais-64\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Esperando um comportamento determinístico usando seleção e canais (#64)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-canais-de-notificacao-65\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar canais de notificação (#65)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-canais-nulos-66\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar canais nulos (#66)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#ficar-intrigado-com-o-tamanho-do-canal-67\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Ficar intrigado com o tamanho do canal (#67)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#esquecendo-os-possiveis-efeitos-colaterais-da-formatacao-de-strings-68\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Esquecendo os possíveis efeitos colaterais da formatação de strings (#68)\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Esquecendo os possíveis efeitos colaterais da formatação de strings (#68)\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#etcd-data-race\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      etcd data race\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#deadlock\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Deadlock\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#criando-corridas-de-dados-com-acrescimo-69\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Criando corridas de dados com acréscimo (#69)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#usando-mutexes-imprecisamente-com-slices-e-maps-70\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Usando mutexes imprecisamente com slices e maps (#70)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#uso-indevido-syncwaitgroup-71\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Uso indevido sync.WaitGroup (#71)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#esquecendo-synccond-72\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Esquecendo sync.Cond (#72)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usando-errgroup-73\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usando errgroup (#73)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#copiando-um-tipo-sync-74\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Copiando um tipo sync (#74)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#standard-library\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Standard Library\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Standard Library\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#fornecendo-uma-duracao-de-tempo-errada-75\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Fornecendo uma duração de tempo errada (#75)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#timeafter-e-vazamentos-de-memoria-76\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      time.After e vazamentos de memória (#76)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#lidando-com-erros-comuns-json-77\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Lidando com erros comuns JSON (#77)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#erros-comuns-de-sql-78\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Erros comuns de SQL (#78)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-fechando-recursos-transitorios-body-http-sqlrows-e-osfile-79\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não fechando recursos transitórios (body HTTP, sql.Rows e os.File) (#79)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#esquecendo-a-instrucao-return-apos-responder-a-uma-solicitacao-http-80\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Esquecendo a instrução return após responder a uma solicitação HTTP (#80)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#usando-o-cliente-e-servidor-http-padrao-81\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Usando o cliente e servidor HTTP padrão (#81)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#teste\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Teste\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Teste\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-categorizar-testes-tags-de-construcao-variaveis-de-ambiente-e-modo-abreviado-82\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não categorizar testes (tags de construção, variáveis ​​de ambiente e modo abreviado) (#82)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-habilitando-a-bandeira-de-corrida-83\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não habilitando a bandeira de corrida (#83)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-modos-de-execucao-de-teste-paralelo-e-aleatorio-84\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar modos de execução de teste (paralelo e aleatório) (#84)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-testes-baseados-em-tabela-85\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar testes baseados em tabela (#85)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#dormindo-em-testes-unitarios-86\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Dormindo em testes unitários (#86)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-lidar-com-a-api-de-tempo-de-forma-eficiente-87\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não lidar com a API de tempo de forma eficiente (#87)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-pacotes-de-utilitarios-de-teste-httptest-e-iotest-88\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar pacotes de utilitários de teste ( httptest e iotest) (#88)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#escrevendo-benchmarks-imprecisos-89\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Escrevendo benchmarks imprecisos (#89)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-explorando-todos-os-recursos-de-teste-do-go-90\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não explorando todos os recursos de teste do Go (#90)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-fuzzing-erro-da-comunidade\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar fuzzing (erro da comunidade)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#otimizacoes\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Otimizações\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"Otimizações\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entendendo-os-caches-da-cpu-91\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entendendo os caches da CPU (#91)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#escrevendo-codigo-simultaneo-que-leva-a-compartilhamento-falso-92\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Escrevendo código simultâneo que leva a compartilhamento falso (#92)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-levando-em-consideracao-o-paralelismo-no-nivel-de-instrucao-93\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não levando em consideração o paralelismo no nível de instrução (#93)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-estar-ciente-do-alinhamento-dos-dados-94\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não estar ciente do alinhamento dos dados (#94)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entendendo-stack-vs-heap-95\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entendendo stack vs. heap (#95)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-saber-como-reduzir-alocacoes-mudanca-de-api-otimizacoes-de-compilador-e-syncpool-96\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não saber como reduzir alocações (mudança de API, otimizações de compilador e sync.Pool) (#96)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-dependendo-do-inlining-97\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não dependendo do inlining (#97)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-usar-ferramentas-de-diagnostico-go-98\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não usar ferramentas de diagnóstico Go (#98)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entendendo-como-funciona-o-gc-99\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entendendo como funciona o GC (#99)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nao-entendendo-os-impactos-da-execucao-do-go-no-docker-e-kubernetes-100\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Não entendendo os impactos da execução do Go no Docker e Kubernetes (#100)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#community\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Community\n    </span>\n  </a>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n                  \n\n\n  \n  \n\n\n<h1 id=\"erros-comuns-de-go\">Erros comuns de Go</h1>\n<details class=\"tip\" open=\"open\">\n<summary>The Coder Cafe</summary>\n<p>Se você gostou do meu livro, talvez se interesse pelo meu novo projeto: <a href=\"https://thecoder.cafe?rd=100go.co/pt-br\">The Coder Cafe</a>, uma newsletter diária para programadores.</p>\n<blockquote>\n<p>Feeling overwhelmed by the endless stream of tech content? At The Coder Cafe, we serve one essential concept for coders. Written by a senior software engineer at Google, it's perfectly brewed for your morning coffee, helping you grow your skills deeply.</p>\n</blockquote>\n<p></p><center><a href=\"https://thecoder.cafe?rd=100go.co/pt-br\"><img src=\"../img/thecodercafe.png\" alt=\"\" style=\"width:480px;height:240px;\"></a></center><p></p>\n</details>\n<p>Esta página é um resumo dos erros do <a href=\"../book/\">100 Go Mistakes and How to Avoid Them book</a>. Enquanto isso, também está aberto à comunidade. Se você acredita que um erro comum do Go deve ser adicionado, crie uma <a href=\"https://github.com/teivah/100-go-mistakes/issues/new?assignees=&amp;labels=community+mistake&amp;template=community_mistake.md&amp;title=\">issue</a>.</p>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/inside-cover.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/inside-cover.png\"></a></p>\n<details class=\"warning\" open=\"open\">\n<summary>Beta</summary>\n<p>Você está visualizando uma versão beta enriquecida com muito mais conteúdo. No entanto, esta versão ainda não está completa e estou procurando voluntários para me ajudar a resumir os erros restantes (<a href=\"https://github.com/teivah/100-go-mistakes/issues/43\">GitHub issue #43</a>).</p>\n<p>Progresso:\n<progress value=\"81\" max=\"100\"></progress></p>\n</details>\n<h2 id=\"codigo-e-organizacao-do-projeto\">Código e Organização do Projeto</h2>\n<h3 id=\"sombreamento-nao-intencional-de-variavel-1\">Sombreamento não intencional de variável (#1)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Evitar variáveis ​​sombreadas pode ajudar a evitar erros, como fazer referência à variável errada ou confundir os desenvolvedores.</p>\n</details>\n<p>O sombreamento de variável ocorre quando um nome de variável é redeclarado em um bloco interno, mas essa prática está sujeita a erros. A imposição de uma regra para proibir variáveis ​​obscuras depende do gosto pessoal. Por exemplo, às vezes pode ser conveniente reutilizar um nome de variável existente, como <code>err</code> no caso de erros. Porém, em geral, devemos ser cautelosos porque agora sabemos que podemos enfrentar um cenário onde o código compila, mas a variável que recebe o valor não é a esperada.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/1-variable-shadowing/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"codigo-aninhado-desnecessario-2\">Código aninhado desnecessário (#2)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Evitar níveis aninhados e manter o caminho feliz alinhado à esquerda facilita a construção de um modelo de código mental.</p>\n</details>\n<p>Em geral, quanto mais níveis aninhados uma função exigir, mais complexa será sua leitura e compreensão. Vamos ver algumas aplicações diferentes desta regra para otimizar a legibilidade do nosso código:</p>\n<ul>\n<li>Quando um bloco <code>if</code> retorna, devemos omitir o <code>else</code> em todos os casos. Por exemplo, não deveríamos escrever:</li>\n</ul>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-0-1\"><a id=\"__codelineno-0-1\" name=\"__codelineno-0-1\" href=\"#__codelineno-0-1\"></a><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">foo</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-0-2\"><a id=\"__codelineno-0-2\" name=\"__codelineno-0-2\" href=\"#__codelineno-0-2\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-0-3\"><a id=\"__codelineno-0-3\" name=\"__codelineno-0-3\" href=\"#__codelineno-0-3\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">true</span>\n</span><span id=\"__span-0-4\"><a id=\"__codelineno-0-4\" name=\"__codelineno-0-4\" href=\"#__codelineno-0-4\"></a><span class=\"p\">}</span><span class=\"w\"> </span><span class=\"k\">else</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-0-5\"><a id=\"__codelineno-0-5\" name=\"__codelineno-0-5\" href=\"#__codelineno-0-5\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-0-6\"><a id=\"__codelineno-0-6\" name=\"__codelineno-0-6\" href=\"#__codelineno-0-6\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Em vez disso, omitimos o bloco <code>else</code> assim:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-1-1\"><a id=\"__codelineno-1-1\" name=\"__codelineno-1-1\" href=\"#__codelineno-1-1\"></a><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">foo</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-1-2\"><a id=\"__codelineno-1-2\" name=\"__codelineno-1-2\" href=\"#__codelineno-1-2\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-1-3\"><a id=\"__codelineno-1-3\" name=\"__codelineno-1-3\" href=\"#__codelineno-1-3\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">true</span>\n</span><span id=\"__span-1-4\"><a id=\"__codelineno-1-4\" name=\"__codelineno-1-4\" href=\"#__codelineno-1-4\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-1-5\"><a id=\"__codelineno-1-5\" name=\"__codelineno-1-5\" href=\"#__codelineno-1-5\"></a><span class=\"c1\">// ...</span>\n</span></code></pre></div>\n<ul>\n<li>Também podemos seguir esta lógica com um caminho não feliz:</li>\n</ul>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-2-1\"><a id=\"__codelineno-2-1\" name=\"__codelineno-2-1\" href=\"#__codelineno-2-1\"></a><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"s\">\"\"</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-2-2\"><a id=\"__codelineno-2-2\" name=\"__codelineno-2-2\" href=\"#__codelineno-2-2\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-2-3\"><a id=\"__codelineno-2-3\" name=\"__codelineno-2-3\" href=\"#__codelineno-2-3\"></a><span class=\"p\">}</span><span class=\"w\"> </span><span class=\"k\">else</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-2-4\"><a id=\"__codelineno-2-4\" name=\"__codelineno-2-4\" href=\"#__codelineno-2-4\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">errors</span><span class=\"p\">.</span><span class=\"nx\">New</span><span class=\"p\">(</span><span class=\"s\">\"empty string\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-2-5\"><a id=\"__codelineno-2-5\" name=\"__codelineno-2-5\" href=\"#__codelineno-2-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Aqui, um <code>s</code> vazio representa o caminho não feliz. Portanto, devemos inverter a condição assim:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-3-1\"><a id=\"__codelineno-3-1\" name=\"__codelineno-3-1\" href=\"#__codelineno-3-1\"></a><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">==</span><span class=\"w\"> </span><span class=\"s\">\"\"</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-3-2\"><a id=\"__codelineno-3-2\" name=\"__codelineno-3-2\" href=\"#__codelineno-3-2\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">errors</span><span class=\"p\">.</span><span class=\"nx\">New</span><span class=\"p\">(</span><span class=\"s\">\"empty string\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-3-3\"><a id=\"__codelineno-3-3\" name=\"__codelineno-3-3\" href=\"#__codelineno-3-3\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-3-4\"><a id=\"__codelineno-3-4\" name=\"__codelineno-3-4\" href=\"#__codelineno-3-4\"></a><span class=\"c1\">// ...</span>\n</span></code></pre></div>\n<p>Escrever código legível é um desafio importante para todo desenvolvedor. Esforçar-se para reduzir o número de blocos aninhados, alinhar o caminho feliz à esquerda e retornar o mais cedo possível são meios concretos para melhorar a legibilidade do nosso código.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/2-nested-code/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"uso-indevido-de-funcoes-init-3\">Uso indevido de funções init (#3)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Ao inicializar variáveis, lembre-se de que as funções init têm tratamento de erros limitado e tornam o tratamento de estado e os testes mais complexos. Na maioria dos casos, as inicializações devem ser tratadas como funções específicas.</p>\n</details>\n<p>Uma função init é uma função usada para inicializar o estado de um aplicativo. Não aceita argumentos e não retorna nenhum resultado (uma função <code>func()</code>). Quando um pacote é inicializado, todas as declarações de constantes e variáveis ​​do pacote são avaliadas. Então, as funções init são executadas.</p>\n<p>As funções de inicialização podem levar a alguns problemas:</p>\n<ul>\n<li>Elas podem limitar o gerenciamento de erros.</li>\n<li>Elas podem complicar a implementação de testes (por exemplo, uma dependência externa deve ser configurada, o que pode não ser necessário para o escopo dos testes unitários).</li>\n<li>Se a inicialização exigir que definamos um estado, isso deverá ser feito por meio de variáveis ​​globais.</li>\n</ul>\n<p>Devemos ser cautelosos com as funções init. No entanto, elas podem ser úteis em algumas situações, como na definição de configuração estática. Caso contrário, e na maioria dos casos, devemos tratar as inicializações através de funções ad hoc.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/3-init-functions/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"uso-excessivo-de-getters-e-setters-4\">Uso excessivo de getters e setters (#4)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Forcing the use of getters and setters isn’t idiomatic in Go. Being pragmatic and finding the right balance between efficiency and blindly following certain idioms should be the way to go.</p>\n</details>\n<p>O encapsulamento de dados refere-se a ocultar os valores ou o estado de um objeto. Getters e setters são meios de habilitar o encapsulamento, fornecendo métodos exportados sobre campos de objetos não exportados.</p>\n<p>No Go, não há suporte automático para getters e setters como vemos em algumas linguagens. Também não é considerado obrigatório nem idiomático o uso de getters e setters para acessar campos struct. Não devemos sobrecarregar nosso código com getters e setters em structs se eles não trouxerem nenhum valor. Deveríamos ser pragmáticos e nos esforçar para encontrar o equilíbrio certo entre eficiência e seguir expressões que às vezes são consideradas indiscutíveis em outros paradigmas de programação.</p>\n<p>Lembre-se de que Go é uma linguagem única projetada para muitas características, incluindo simplicidade. No entanto, se encontrarmos necessidade de getters e setters ou, como mencionado, prevermos uma necessidade futura e ao mesmo tempo garantirmos a compatibilidade futura, não há nada de errado em usá-los.</p>\n<h3 id=\"interface-poluidas-5\">Interface poluidas (#5)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Abstrações devem ser descobertas, não criadas. Para evitar complexidade desnecessária, crie uma interface quando precisar dela e não quando você prevêr que será necessária, ou se puder pelo menos provar que a abstração é válida.</p>\n</details>\n<p>Leia a seção completa <a href=\"../5-interface-pollution/\">aqui</a>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/5-interface-pollution/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"interface-do-lado-do-producer-6\">Interface do lado do producer (#6)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Manter interfaces no lado do cliente evita abstrações desnecessárias.</p>\n</details>\n<p>As interfaces são satisfeitas implicitamente em Go, o que tende a ser um divisor de águas em comparação com linguagens com implementação explícita. Na maioria dos casos, a abordagem a seguir é semelhante à que descrevemos na seção anterior: <em>as abstrações devem ser descobertas, não criadas</em>. Isso significa que não cabe ao producer forçar uma determinada abstração para todos os clientes. Em vez disso, cabe ao cliente decidir se precisa de alguma forma de abstração e então determinar o melhor nível de abstração para suas necessidades.</p>\n<p>Uma interface deve residir no lado do consumidor na maioria dos casos. Contudo, em contextos específicos (por exemplo, quando sabemos – e não prevemos – que uma abstração será útil para os consumidores), podemos querer tê-la do lado do procuder. Se o fizermos, devemos nos esforçar para mantê-lo o mínimo possível, aumentando o seu potencial de reutilização e tornando-o mais facilmente combinável.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/6-interface-producer/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"interfaces-de-retorno-7\">Interfaces de retorno (#7)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Para evitar restrições em termos de flexibilidade, uma função não deve retornar interfaces, mas implementações concretas na maioria dos casos. Por outro lado, uma função deve aceitar interfaces sempre que possível.</p>\n</details>\n<p>Na maioria dos casos, não devemos retornar interfaces, mas implementações concretas. Caso contrário, isso pode tornar nosso design mais complexo devido às dependências do pacote e pode restringir a flexibilidade porque todos os clientes teriam que contar com a mesma abstração. Novamente, a conclusão é semelhante às seções anteriores: se sabemos (não prevemos) que uma abstração será útil para os clientes, podemos considerar o retorno de uma interface. Caso contrário, não deveríamos forçar abstrações; eles devem ser descobertas pelos clientes. Se um cliente precisar abstrair uma implementação por qualquer motivo, ele ainda poderá fazer isso do lado do cliente.</p>\n<h3 id=\"any-nao-diz-nada-8\"><code>any</code> não diz nada (#8)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Use apenas <code>any</code> se precisar aceitar ou retornar qualquer tipo possível, como <code>json.Marshal</code>. Caso contrário, <code>any</code> não fornece informações significativas e pode levar a problemas de tempo de compilação, permitindo que um chamador chame métodos com qualquer tipo de dados.</p>\n</details>\n<p>O tipo <code>any</code> pode ser útil se houver uma necessidade genuína de aceitar ou retornar qualquer tipo possível (por exemplo, quando se trata de empacotamento ou formatação). Em geral, devemos evitar a todo custo generalizar demais o código que escrevemos. Talvez um pouco de código duplicado possa ocasionalmente ser melhor se melhorar outros aspectos, como a expressividade do código.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/8-any/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"ficar-confuso-sobre-quando-usar-genericos-9\">Ficar confuso sobre quando usar genéricos (#9)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Depender de parâmetros genéricos e de tipo pode impedir a gravação de código clichê (boilerplate) para fatorar elementos ou comportamentos. No entanto, não use parâmetros de tipo prematuramente, mas somente quando você perceber uma necessidade concreta deles. Caso contrário, introduzem abstrações e complexidade desnecessárias.</p>\n</details>\n<p>Leia a seção completa <a href=\"../9-generics/\">aqui</a>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/9-generics/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-estar-ciente-dos-possiveis-problemas-com-a-incorporacao-de-tipos-10\">Não estar ciente dos possíveis problemas com a incorporação de tipos (#10)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Usar a incorporação de tipo (type embedding) também pode ajudar a evitar código clichê (boilerplate); no entanto, certifique-se de que isso não leve a problemas de visibilidade onde alguns campos deveriam ter permanecido ocultos.</p>\n</details>\n<p>Ao criar uma struct, Go oferece a opção de incorporar tipos. Mas isso às vezes pode levar a comportamentos inesperados se não compreendermos todas as implicações da incorporação de tipos. Ao longo desta seção, veremos como incorporar tipos, o que eles trazem e os possíveis problemas.</p>\n<p>No Go, um campo struct é chamado de incorporado se for declarado sem nome. Por exemplo,</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-4-1\"><a id=\"__codelineno-4-1\" name=\"__codelineno-4-1\" href=\"#__codelineno-4-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Foo</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-4-2\"><a id=\"__codelineno-4-2\" name=\"__codelineno-4-2\" href=\"#__codelineno-4-2\"></a><span class=\"w\">    </span><span class=\"nx\">Bar</span><span class=\"w\"> </span><span class=\"c1\">// Embedded field</span>\n</span><span id=\"__span-4-3\"><a id=\"__codelineno-4-3\" name=\"__codelineno-4-3\" href=\"#__codelineno-4-3\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-4-4\"><a id=\"__codelineno-4-4\" name=\"__codelineno-4-4\" href=\"#__codelineno-4-4\"></a>\n</span><span id=\"__span-4-5\"><a id=\"__codelineno-4-5\" name=\"__codelineno-4-5\" href=\"#__codelineno-4-5\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Bar</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-4-6\"><a id=\"__codelineno-4-6\" name=\"__codelineno-4-6\" href=\"#__codelineno-4-6\"></a><span class=\"w\">    </span><span class=\"nx\">Baz</span><span class=\"w\"> </span><span class=\"kt\">int</span>\n</span><span id=\"__span-4-7\"><a id=\"__codelineno-4-7\" name=\"__codelineno-4-7\" href=\"#__codelineno-4-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Na estrutura <code>Foo</code>, o tipo <code>Bar</code> é declarado sem nome associado; portanto, é um campo incorporado.</p>\n<p>Usamos incorporação para promover os campos e métodos de um tipo incorporado. Como <code>Bar</code> contém um campo <code>Baz</code>, esse campo é promovido para <code>Foo</code>. Portanto, <code>Baz</code> fica disponível a partir de <code>Foo</code>.</p>\n<p>O que podemos dizer sobre a incorporação de tipos? Primeiro, observemos que raramente é uma necessidade e significa que, qualquer que seja o caso de uso, provavelmente também poderemos resolvê-lo sem incorporação de tipo. A incorporação de tipos é usada principalmente por conveniência: na maioria dos casos, para promover comportamentos.</p>\n<p>Se decidirmos usar incorporação de tipo, precisamos ter em mente duas restrições principais:</p>\n<ul>\n<li>Não deve ser usado apenas como um açúcar sintático para simplificar o acesso a um campo (como <code>Foo.Baz()</code> em vez de <code>Foo.Bar.Baz()</code>). Se esta for a única justificativa, não vamos incorporar o tipo interno e usar um campo.</li>\n<li>Não deve promover dados (campos) ou um comportamento (métodos) que queremos ocultar do exterior: por exemplo, se permitir que os clientes acessem um comportamento de bloqueio que deve permanecer privado da struct.</li>\n</ul>\n<p>Usar a incorporação de tipo de forma consciente, mantendo essas restrições em mente, pode ajudar a evitar código clichê (boilerplate) com métodos de encaminhamento adicionais. No entanto, vamos garantir que não o fazemos apenas por motivos cosméticos e não promovemos elementos que deveriam permanecer ocultos.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/10-type-embedding/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-usar-o-padrao-de-opcoes-funcionais-functional-options-pattern-11\">Não usar o padrão de opções funcionais (functional options pattern) (#11)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Para lidar com opções de maneira conveniente e amigável à API, use o padrão de opções funcionais.</p>\n</details>\n<p>Embora existam diferentes implementações com pequenas variações, a ideia principal é a seguinte:</p>\n<ul>\n<li>Uma estrutura não exportada contém a configuração: opções.</li>\n<li>Cada opção é uma função que retorna o mesmo tipo: <code>type Option func(options *options) error</code>. Por exemplo, <code>WithPort</code> aceita um argumento <code>int</code>  que representa a porta e retorna um tipo <code>Option</code> que representa como atualizar a struct <code>options</code>.</li>\n</ul>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/options.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/options.png\"></a></p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-5-1\"><a id=\"__codelineno-5-1\" name=\"__codelineno-5-1\" href=\"#__codelineno-5-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">options</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-2\"><a id=\"__codelineno-5-2\" name=\"__codelineno-5-2\" href=\"#__codelineno-5-2\"></a><span class=\"w\">  </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"kt\">int</span>\n</span><span id=\"__span-5-3\"><a id=\"__codelineno-5-3\" name=\"__codelineno-5-3\" href=\"#__codelineno-5-3\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-5-4\"><a id=\"__codelineno-5-4\" name=\"__codelineno-5-4\" href=\"#__codelineno-5-4\"></a>\n</span><span id=\"__span-5-5\"><a id=\"__codelineno-5-5\" name=\"__codelineno-5-5\" href=\"#__codelineno-5-5\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Option</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">(</span><span class=\"nx\">options</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">options</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span>\n</span><span id=\"__span-5-6\"><a id=\"__codelineno-5-6\" name=\"__codelineno-5-6\" href=\"#__codelineno-5-6\"></a>\n</span><span id=\"__span-5-7\"><a id=\"__codelineno-5-7\" name=\"__codelineno-5-7\" href=\"#__codelineno-5-7\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">WithPort</span><span class=\"p\">(</span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">Option</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-8\"><a id=\"__codelineno-5-8\" name=\"__codelineno-5-8\" href=\"#__codelineno-5-8\"></a><span class=\"w\">  </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">(</span><span class=\"nx\">options</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">options</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-9\"><a id=\"__codelineno-5-9\" name=\"__codelineno-5-9\" href=\"#__codelineno-5-9\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-10\"><a id=\"__codelineno-5-10\" name=\"__codelineno-5-10\" href=\"#__codelineno-5-10\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">errors</span><span class=\"p\">.</span><span class=\"nx\">New</span><span class=\"p\">(</span><span class=\"s\">\"port should be positive\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-5-11\"><a id=\"__codelineno-5-11\" name=\"__codelineno-5-11\" href=\"#__codelineno-5-11\"></a><span class=\"w\">  </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-12\"><a id=\"__codelineno-5-12\" name=\"__codelineno-5-12\" href=\"#__codelineno-5-12\"></a><span class=\"w\">  </span><span class=\"nx\">options</span><span class=\"p\">.</span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"o\">&amp;</span><span class=\"nx\">port</span>\n</span><span id=\"__span-5-13\"><a id=\"__codelineno-5-13\" name=\"__codelineno-5-13\" href=\"#__codelineno-5-13\"></a><span class=\"w\">  </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-5-14\"><a id=\"__codelineno-5-14\" name=\"__codelineno-5-14\" href=\"#__codelineno-5-14\"></a><span class=\"w\">  </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-15\"><a id=\"__codelineno-5-15\" name=\"__codelineno-5-15\" href=\"#__codelineno-5-15\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-5-16\"><a id=\"__codelineno-5-16\" name=\"__codelineno-5-16\" href=\"#__codelineno-5-16\"></a>\n</span><span id=\"__span-5-17\"><a id=\"__codelineno-5-17\" name=\"__codelineno-5-17\" href=\"#__codelineno-5-17\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">NewServer</span><span class=\"p\">(</span><span class=\"nx\">addr</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">opts</span><span class=\"w\"> </span><span class=\"o\">...</span><span class=\"nx\">Option</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Server</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-18\"><a id=\"__codelineno-5-18\" name=\"__codelineno-5-18\" href=\"#__codelineno-5-18\"></a><span class=\"w\">  </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">options</span><span class=\"w\"> </span><span class=\"nx\">options</span>\n</span><span id=\"__span-5-19\"><a id=\"__codelineno-5-19\" name=\"__codelineno-5-19\" href=\"#__codelineno-5-19\"></a><span class=\"w\">  </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">opt</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">opts</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-20\"><a id=\"__codelineno-5-20\" name=\"__codelineno-5-20\" href=\"#__codelineno-5-20\"></a><span class=\"w\">    </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">opt</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">options</span><span class=\"p\">)</span>\n</span><span id=\"__span-5-21\"><a id=\"__codelineno-5-21\" name=\"__codelineno-5-21\" href=\"#__codelineno-5-21\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-22\"><a id=\"__codelineno-5-22\" name=\"__codelineno-5-22\" href=\"#__codelineno-5-22\"></a><span class=\"w\">      </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-5-23\"><a id=\"__codelineno-5-23\" name=\"__codelineno-5-23\" href=\"#__codelineno-5-23\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-24\"><a id=\"__codelineno-5-24\" name=\"__codelineno-5-24\" href=\"#__codelineno-5-24\"></a><span class=\"w\">  </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-25\"><a id=\"__codelineno-5-25\" name=\"__codelineno-5-25\" href=\"#__codelineno-5-25\"></a>\n</span><span id=\"__span-5-26\"><a id=\"__codelineno-5-26\" name=\"__codelineno-5-26\" href=\"#__codelineno-5-26\"></a><span class=\"w\">  </span><span class=\"c1\">// At this stage, the options struct is built and contains the config</span>\n</span><span id=\"__span-5-27\"><a id=\"__codelineno-5-27\" name=\"__codelineno-5-27\" href=\"#__codelineno-5-27\"></a><span class=\"w\">  </span><span class=\"c1\">// Therefore, we can implement our logic related to port configuration</span>\n</span><span id=\"__span-5-28\"><a id=\"__codelineno-5-28\" name=\"__codelineno-5-28\" href=\"#__codelineno-5-28\"></a><span class=\"w\">  </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"kt\">int</span>\n</span><span id=\"__span-5-29\"><a id=\"__codelineno-5-29\" name=\"__codelineno-5-29\" href=\"#__codelineno-5-29\"></a><span class=\"w\">  </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">options</span><span class=\"p\">.</span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"o\">==</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-30\"><a id=\"__codelineno-5-30\" name=\"__codelineno-5-30\" href=\"#__codelineno-5-30\"></a><span class=\"w\">    </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">defaultHTTPPort</span>\n</span><span id=\"__span-5-31\"><a id=\"__codelineno-5-31\" name=\"__codelineno-5-31\" href=\"#__codelineno-5-31\"></a><span class=\"w\">  </span><span class=\"p\">}</span><span class=\"w\"> </span><span class=\"k\">else</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-32\"><a id=\"__codelineno-5-32\" name=\"__codelineno-5-32\" href=\"#__codelineno-5-32\"></a><span class=\"w\">      </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">options</span><span class=\"p\">.</span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"o\">==</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-33\"><a id=\"__codelineno-5-33\" name=\"__codelineno-5-33\" href=\"#__codelineno-5-33\"></a><span class=\"w\">      </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">randomPort</span><span class=\"p\">()</span>\n</span><span id=\"__span-5-34\"><a id=\"__codelineno-5-34\" name=\"__codelineno-5-34\" href=\"#__codelineno-5-34\"></a><span class=\"w\">    </span><span class=\"p\">}</span><span class=\"w\"> </span><span class=\"k\">else</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-5-35\"><a id=\"__codelineno-5-35\" name=\"__codelineno-5-35\" href=\"#__codelineno-5-35\"></a><span class=\"w\">      </span><span class=\"nx\">port</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">options</span><span class=\"p\">.</span><span class=\"nx\">port</span>\n</span><span id=\"__span-5-36\"><a id=\"__codelineno-5-36\" name=\"__codelineno-5-36\" href=\"#__codelineno-5-36\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-37\"><a id=\"__codelineno-5-37\" name=\"__codelineno-5-37\" href=\"#__codelineno-5-37\"></a><span class=\"w\">  </span><span class=\"p\">}</span>\n</span><span id=\"__span-5-38\"><a id=\"__codelineno-5-38\" name=\"__codelineno-5-38\" href=\"#__codelineno-5-38\"></a>\n</span><span id=\"__span-5-39\"><a id=\"__codelineno-5-39\" name=\"__codelineno-5-39\" href=\"#__codelineno-5-39\"></a><span class=\"w\">  </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-5-40\"><a id=\"__codelineno-5-40\" name=\"__codelineno-5-40\" href=\"#__codelineno-5-40\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>O padrão de opções funcionais fornece uma maneira prática e amigável à API de lidar com opções. Embora o padrão do construtor possa ser uma opção válida, ele tem algumas desvantagens menores (ter que passar uma estrutura de configuração que pode estar vazia ou uma maneira menos prática de lidar com o gerenciamento de erros) que tendem a tornar o padrão de opções funcionais a maneira idiomática de lidar com esse tipo de problema no Go.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/11-functional-options/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"desorganizacao-do-projeto-estrutura-do-projeto-e-organizacao-do-pacote-12\">Desorganização do projeto (estrutura do projeto e organização do pacote) (#12)</h3>\n<p>No que diz respeito à organização geral, existem diferentes escolas de pensamento. Por exemplo, devemos organizar a nossa aplicação por contexto ou por camada? Depende de nossas preferências. Podemos preferir agrupar o código por contexto (como o contexto do cliente, o contexto do contrato, etc.), ou podemos preferir seguir os princípios da arquitetura hexagonal e agrupar por camada técnica. Se a decisão que tomarmos se adequar ao nosso caso de uso, não pode ser uma decisão errada, desde que permaneçamos consistentes com ela.</p>\n<p>Em relação aos pacotes, existem várias práticas recomendadas que devemos seguir. Primeiro, devemos evitar pacotes prematuros porque podem complicar demais um projeto. Às vezes, é melhor usar uma organização simples e fazer nosso projeto evoluir quando entendemos o que ele contém, em vez de nos forçarmos a fazer a estrutura perfeita desde o início. A granularidade é outra coisa essencial a considerar. Devemos evitar dezenas de pacotes nano contendo apenas um ou dois arquivos. Se o fizermos, é porque provavelmente perdemos algumas conexões lógicas entre esses pacotes, tornando nosso projeto mais difícil de ser compreendido pelos leitores. Por outro lado, também devemos evitar pacotes grandes que diluem o significado do nome de um pacote.</p>\n<p>A nomenclatura dos pacotes também deve ser considerada com cuidado. Como todos sabemos (como desenvolvedores), nomear é difícil. Para ajudar os clientes a entender um projeto Go, devemos nomear nossos pacotes de acordo com o que eles fornecem, não com o que contêm. Além disso, a nomenclatura deve ser significativa. Portanto, o nome de um pacote deve ser curto, conciso, expressivo e, por convenção, uma única palavra minúscula.</p>\n<p>Quanto ao que exportar, a regra é bastante simples. Devemos minimizar o que deve ser exportado tanto quanto possível para reduzir o acoplamento entre pacotes e manter ocultos os elementos exportados desnecessários. Se não tivermos certeza se devemos ou não exportar um elemento, devemos optar por não exportá-lo. Mais tarde, se descobrirmos que precisamos exportá-lo, poderemos ajustar nosso código. Vamos também ter em mente algumas exceções, como fazer com que os campos sejam exportados para que uma estrutura possa ser desempacotada com encoding/json.</p>\n<p>Organizar um projeto não é simples, mas seguir essas regras deve ajudar a facilitar sua manutenção. No entanto, lembre-se de que a consistência também é vital para facilitar a manutenção. Portanto, vamos nos certificar de manter as coisas o mais consistentes possível dentro de uma base de código.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>Em 2023, a equipe Go publicou uma diretriz oficial para organizar/estruturar um projeto Go: <a href=\"https://go.dev/doc/modules/layout\">go.dev/doc/modules/layout</a></p>\n</details>\n<h3 id=\"criando-pacotes-de-utilitarios-13\">Criando pacotes de utilitários (#13)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>A nomenclatura é uma parte crítica do design do aplicativo. Criar pacotes como <code>common</code>, <code>util</code> e <code>shared</code> não traz muito valor para o leitor. Refatore esses pacotes em nomes de pacotes significativos e específicos.</p>\n</details>\n<p>Além disso, tenha em mente que nomear um pacote com base no que ele fornece e não no que ele contém pode ser uma forma eficiente de aumentar sua expressividade.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/02-code-project-organization/13-utility-packages/stringset.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"ignorando-colisoes-de-nomes-de-pacotes-14\">Ignorando colisões de nomes de pacotes (#14)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Para evitar colisões de nomes entre variáveis ​​e pacotes, levando a confusão ou talvez até bugs, use nomes exclusivos para cada um. Se isso não for viável, use um alias de importação para alterar o qualificador para diferenciar o nome do pacote do nome da variável ou pense em um nome melhor.</p>\n</details>\n<p>As colisões de pacotes ocorrem quando um nome de variável colide com um nome de pacote existente, impedindo que o pacote seja reutilizado. Devemos evitar colisões de nomes de variáveis ​​para evitar ambiguidade. Se enfrentarmos uma colisão, devemos encontrar outro nome significativo ou usar um alias de importação.</p>\n<h3 id=\"documentacao-de-codigo-ausente-15\">Documentação de código ausente (#15)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Para ajudar clientes e mantenedores a entender a finalidade do seu código, documente os elementos exportados.</p>\n</details>\n<p>A documentação é um aspecto importante da programação. Simplifica como os clientes podem consumir uma API, mas também pode ajudar na manutenção de um projeto. No Go, devemos seguir algumas regras para tornar nosso código idiomático:</p>\n<p>Primeiro, cada elemento exportado deve ser documentado. Seja uma estrutura, uma interface, uma função ou qualquer outra coisa, se for exportado deve ser documentado. A convenção é adicionar comentários, começando com o nome do elemento exportado.</p>\n<p>Por convenção, cada comentário deve ser uma frase completa que termina com pontuação. Tenha também em mente que quando documentamos uma função (ou um método), devemos destacar o que a função pretende fazer, não como o faz; isso pertence ao núcleo de uma função e comentários, não à documentação. Além disso, o ideal é que a documentação forneça informações suficientes para que o consumidor não precise olhar nosso código para entender como usar um elemento exportado.</p>\n<p>Quando se trata de documentar uma variável ou constante, podemos estar interessados ​​em transmitir dois aspectos: sua finalidade e seu conteúdo. O primeiro deve funcionar como documentação de código para ser útil para clientes externos. Este último, porém, não deveria ser necessariamente público.</p>\n<p>Para ajudar clientes e mantenedores a entender o escopo de um pacote, devemos também documentar cada pacote. A convenção é iniciar o comentário com <code>// Package</code> seguido do nome do pacote. A primeira linha de um comentário de pacote deve ser concisa. Isso porque ele aparecerá no pacote. Então, podemos fornecer todas as informações que precisamos nas linhas seguintes.</p>\n<p>Documentar nosso código não deve ser uma restrição. Devemos aproveitar a oportunidade para garantir que isso ajude os clientes e mantenedores a entender o propósito do nosso código.</p>\n<h3 id=\"nao-usando-linters-16\">Não usando linters (#16)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Para melhorar a qualidade e consistência do código, use linters e formatadores.</p>\n</details>\n<p>Um linter é uma ferramenta automática para analisar código e detectar erros. O escopo desta seção não é fornecer uma lista exaustiva dos linters existentes; caso contrário, ele ficará obsoleto rapidamente. Mas devemos entender e lembrar por que os linters são essenciais para a maioria dos projetos Go.</p>\n<p>No entanto, se você não é um usuário regular de linters, aqui está uma lista que você pode usar diariamente:</p>\n<ul>\n<li><a href=\"https://golang.org/cmd/vet\">https://golang.org/cmd/vet</a>—A standard Go analyzer</li>\n<li><a href=\"https://github.com/kisielk/errcheck\">https://github.com/kisielk/errcheck</a>—An error checker</li>\n<li><a href=\"https://github.com/fzipp/gocyclo\">https://github.com/fzipp/gocyclo</a>—A cyclomatic complexity analyzer</li>\n<li><a href=\"https://github.com/jgautheron/goconst\">https://github.com/jgautheron/goconst</a>—A repeated string constants analyzer</li>\n</ul>\n<p>Além dos linters, também devemos usar formatadores de código para corrigir o estilo do código. Aqui está uma lista de alguns formatadores de código para você experimentar:</p>\n<ul>\n<li><a href=\"https://golang.org/cmd/gofmt\">https://golang.org/cmd/gofmt</a>—A standard Go code formatter</li>\n<li><a href=\"https://godoc.org/golang.org/x/tools/cmd/goimports\">https://godoc.org/golang.org/x/tools/cmd/goimports</a>—A standard Go imports formatter</li>\n</ul>\n<p>Enquanto isso, devemos também dar uma olhada em golangci-lint (<a href=\"https://github.com/golangci/golangci-lint\">https://github.com/golangci/golangci-lint</a>).\nÉ uma ferramenta de linting que fornece uma fachada sobre muitos linters e formatadores úteis. Além disso, permite executar os linters em paralelo para melhorar a velocidade de análise, o que é bastante útil.</p>\n<p>Linters e formatadores são uma forma poderosa de melhorar a qualidade e consistência de nossa base de código. Vamos dedicar um tempo para entender qual deles devemos usar e garantir que automatizamos sua execução (como um precommit hook de CI ou Git).</p>\n<h2 id=\"tipos-de-dados\">Tipos de dados</h2>\n<h3 id=\"criando-confusao-com-literais-octais-17\">Criando confusão com literais octais (#17)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Ao ler o código existente, lembre-se de que literais inteiros começando com <code>0</code> são números octais. Além disso, para melhorar a legibilidade, torne os inteiros octais explícitos prefixando-os com <code>0o</code>.</p>\n</details>\n<p>Os números octais começam com 0 (por exemplo, <code>010</code> é igual a 8 na base 10). Para melhorar a legibilidade e evitar possíveis erros para futuros leitores de código, devemos tornar os números octais explícitos usando o prefixo <code>0o</code> (por exemplo, <code>0o10</code>).</p>\n<p>Devemos também observar as outras representações literais inteiras:</p>\n<ul>\n<li><em>Binário</em>—Usa um prefixo <code>0b</code> ou <code>0B</code>(por exemplo, <code>0b100</code> é igual a 4 na base 10)</li>\n<li><em>Hexadecimal</em>—Usa um prefixo <code>0x</code> ou <code>0X</code> (por exemplo, <code>0xF</code> é igual a 15 na base 10)</li>\n<li><em>Imaginário</em>—Usa um <code>i</code> sufixo (por exemplo, <code>3i</code>)</li>\n</ul>\n<p>Também podemos usar um caractere de sublinhado (_) como separador para facilitar a leitura. Por exemplo, podemos escrever 1 bilhão desta forma: <code>1_000_000_000</code>. Também podemos usar o caractere sublinhado com outras representações (por exemplo, <code>0b00_00_01</code>).</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/17-octal-literals/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"negligenciando-estouros-de-numero-inteiro-18\">Negligenciando estouros de número inteiro (#18)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Como os overflows e underflows de números inteiros são tratados silenciosamente no Go, você pode implementar suas próprias funções para capturá-los.</p>\n</details>\n<p>No Go, um estouro de número inteiro que pode ser detectado em tempo de compilação gera um erro de compilação. Por exemplo,</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-6-1\"><a id=\"__codelineno-6-1\" name=\"__codelineno-6-1\" href=\"#__codelineno-6-1\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">counter</span><span class=\"w\"> </span><span class=\"kt\">int32</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">math</span><span class=\"p\">.</span><span class=\"nx\">MaxInt32</span><span class=\"w\"> </span><span class=\"o\">+</span><span class=\"w\"> </span><span class=\"mi\">1</span>\n</span></code></pre></div>\n<div class=\"language-shell highlight\"><pre><span></span><code><span id=\"__span-7-1\"><a id=\"__codelineno-7-1\" name=\"__codelineno-7-1\" href=\"#__codelineno-7-1\"></a>constant<span class=\"w\"> </span><span class=\"m\">2147483648</span><span class=\"w\"> </span>overflows<span class=\"w\"> </span>int32\n</span></code></pre></div>\n<p>No entanto, em tempo de execução, um overflow ou underflow de inteiro é silencioso; isso não leva ao pânico do aplicativo. É essencial ter esse comportamento em mente, pois ele pode levar a bugs sorrateiros (por exemplo, um incremento de número inteiro ou adição de números inteiros positivos que leva a um resultado negativo).</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/18-integer-overflows\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-entendendo-os-pontos-flutuantes-19\">Não entendendo os pontos flutuantes (#19)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Fazer comparações de ponto flutuante dentro de um determinado delta pode garantir que seu código seja portátil. Ao realizar adição ou subtração, agrupe as operações com ordem de grandeza semelhante para favorecer a precisão. Além disso, execute multiplicação e divisão antes da adição e subtração.</p>\n</details>\n<p>Em Go, existem dois tipos de ponto flutuante (se omitirmos os números imaginários): float32 e float64. O conceito de ponto flutuante foi inventado para resolver o principal problema dos números inteiros: sua incapacidade de representar valores fracionários. Para evitar surpresas desagradáveis, precisamos saber que a aritmética de ponto flutuante é uma aproximação da aritmética real.</p>\n<p>Para isso, veremos um exemplo de multiplicação:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-8-1\"><a id=\"__codelineno-8-1\" name=\"__codelineno-8-1\" href=\"#__codelineno-8-1\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">n</span><span class=\"w\"> </span><span class=\"kt\">float32</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"mf\">1.0001</span>\n</span><span id=\"__span-8-2\"><a id=\"__codelineno-8-2\" name=\"__codelineno-8-2\" href=\"#__codelineno-8-2\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">n</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"w\"> </span><span class=\"nx\">n</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>Podemos esperar que este código imprima o resultado de 1.0001 * 1.0001 = 1,00020001, certo? No entanto, executá-lo na maioria dos processadores x86 imprime 1.0002.</p>\n<p>Como os tipos <code>float32</code> e <code>float64</code> em Go são aproximações, temos que ter algumas regras em mente:</p>\n<ul>\n<li>Ao comparar dois números de ponto flutuante, verifique se a diferença está dentro de um intervalo aceitável.</li>\n<li>Ao realizar adições ou subtrações, agrupe operações com ordem de magnitude semelhante para melhor precisão.</li>\n<li>Para favorecer a precisão, se uma sequência de operações exigir adição, subtração, multiplicação ou divisão, execute primeiro as operações de multiplicação e divisão.</li>\n</ul>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/19-floating-points/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-entendendo-o-comprimento-e-a-capacidade-de-slice-20\">Não entendendo o comprimento e a capacidade de slice (#20)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Compreender a diferença entre comprimento e capacidade da slice deve fazer parte do conhecimento básico de um desenvolvedor Go. O comprimento de slice é o número de elementos disponíveis na slice, enquanto a capacidade de slice é o número de elementos na matriz de apoio.</p>\n</details>\n<p>Leia a seção completa <a href=\"../20-slice/\">aqui</a>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/20-slice-length-cap/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"inicializacao-de-slice-ineficiente-21\">Inicialização de slice ineficiente (#21)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Ao criar uma fatia, inicialize-a com um determinado comprimento ou capacidade se o seu comprimento já for conhecido. Isso reduz o número de alocações e melhora o desempenho.</p>\n</details>\n<p>Ao inicializar uma fatia usando <code>make</code>, podemos fornecer um comprimento e uma capacidade opcional. Esquecer de passar um valor apropriado para ambos os parâmetros quando faz sentido é um erro generalizado. Na verdade, isso pode levar a múltiplas cópias e esforço adicional para o <abbr title=\"Garbage Collector\">GC</abbr> limpar as matrizes de apoio temporárias. Em termos de desempenho, não há uma boa razão para não ajudar o tempo de execução do Go.</p>\n<p>Nossas opções são alocar uma fatia com determinada capacidade ou comprimento. Destas duas soluções, vimos que a segunda tende a ser um pouco mais rápida. Mas usar uma determinada capacidade e anexar pode ser mais fácil de implementar e ler em alguns contextos.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/21-slice-init/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"estar-confuso-sobre-slice-nula-vs-slice-vazia-22\">Estar confuso sobre slice nula vs. slice vazia (#22)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>To prevent common confusions such as when using the <code>encoding/json</code> or the <code>reflect</code> package, you need to understand the difference between nil and empty slices. Both are zero-length, zero-capacity slices, but only a nil slice doesn’t require allocation.</p>\n</details>\n<p>No Go, há uma distinção entre slices nulas e vazias. Uma slice nula é igual a <code>nil</code>, enquanto uma slice vazia tem comprimento zero. Uma slice nula está vazia, mas uma slice vazia não é necessariamente <code>nil</code>. Enquanto isso, uma slice nula não requer nenhuma alocação. Vimos ao longo desta seção como inicializar uma slice dependendo do contexto usando</p>\n<ul>\n<li><code>var s []string</code> se não tivermos certeza sobre o comprimento final e a fatia pode estar vazia</li>\n<li><code>[]string(nil)</code> como açúcar sintático para criar uma fatia nula e vazia</li>\n<li><code>make([]string, length)</code> se o comprimento futuro for conhecido</li>\n</ul>\n<p>A última opção, <code>[]string{}</code> deve ser evitada se inicializarmos a fatia sem elementos. Finalmente, vamos verificar se as bibliotecas que usamos fazem distinções entre fatias nulas e vazias para evitar comportamentos inesperados.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/22-nil-empty-slice/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-verificar-corretamente-se-um-slice-esta-vazio-23\">Não verificar corretamente se um slice está vazio (#23)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Para verificar se uma fatia não contém nenhum elemento, verifique seu comprimento. Esta verificação funciona independentemente de o slice estar <code>nil</code> ou vazio. O mesmo vale para maps. Para projetar APIs inequívocas, você não deve distinguir entre slice nulos e vazios.</p>\n</details>\n<p>Para determinar se um slice possui elementos, podemos fazê-lo verificando se o slice é nulo ou se seu comprimento é igual a 0. Verificar o comprimento é a melhor opção a seguir, pois cobrirá ambos se o slice estiver vazio ou se o slice é nulo.</p>\n<p>Enquanto isso, ao projetar interfaces, devemos evitar distinguir slices nulos e vazios, o que leva a erros sutis de programação. Ao retornar slices, não deve haver diferença semântica nem técnica se retornarmos um slice nulo ou vazio. Ambos devem significar a mesma coisa para quem liga. Este princípio é o mesmo com maps. Para verificar se um map está vazio, verifique seu comprimento, não se é nulo.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/23-checking-slice-empty/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-fazer-copias-de-slcies-corretamente-24\">Não fazer cópias de slcies corretamente (#24)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Para copiar um slice para outro usando a função <code>copy</code>, lembre-se que o número de elementos copiados corresponde ao mínimo entre os comprimentos dos dois slices.</p>\n</details>\n<p>Copiar elementos de um slice para outro é uma operação razoavelmente frequente. Ao utilizar a cópia, devemos lembrar que o número de elementos copiados para o destino corresponde ao mínimo entre os comprimentos dos dois slices. Tenha também em mente que existem outras alternativas para copiar um slice, por isso não devemos nos surpreender se as encontrarmos em uma base de código.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/24-slice-copy/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"efeitos-colaterais-inesperados-usando-o-slice-append-25\">Efeitos colaterais inesperados usando o slice append (#25)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Usar <code>copy</code> ou a expressão de slice completa é uma forma de evitar que <code>append</code> crie conflitos se duas funções diferentes usarem slices apoiados pela mesmo array. No entanto, apenas uma cópia de slice evita vazamentos de memória se você quiser reduzir um slice grande.</p>\n</details>\n<p>Ao usar o slicing, devemos lembrar que podemos enfrentar uma situação que leva a efeitos colaterais não intencionais. Se o slice resultante tiver um comprimento menor que sua capacidade, o acréscimo poderá alterar o slice original. Se quisermos restringir a gama de possíveis efeitos colaterais, podemos usar uma cópia de slice ou a expressão de slice completa, o que nos impede de fazer uma cópia.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p><code>s[low:high:max]</code>(expressão de slice completo): Esta instrução cria um slice semelhante àquele criado com <code>s[low:high]</code>, exceto que a capacidade de slice resultante é igual a <code>max - low</code>.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/25-slice-append/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"slices-e-vazamentos-de-memoria-26\">Slices e vazamentos de memória (#26)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Trabalhando com um slice de ponteiros ou estruturas com campos de ponteiro, você pode evitar vazamentos de memória marcando como nulos os elementos excluídos por uma operação de fatiamento.</p>\n</details>\n<h4 id=\"vazamento-de-capacidade\">Vazamento de capacidade</h4>\n<p>Lembre-se de que fatiar um slice ou array grande pode levar a um potencial alto consumo de memória. O espaço restante não será recuperado pelo <abbr title=\"Garbage Collector\">GC</abbr> e podemos manter um grande array de apoio, apesar de usarmos apenas alguns elementos. Usar uma cópia em slice é a solução para evitar tal caso.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/26-slice-memory-leak/capacity-leak\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h4 id=\"slice-e-ponteiros\">Slice e ponteiros</h4>\n<p>Quando usamos a operação de fatiamento com ponteiros ou estruturas com campos de ponteiro, precisamos saber que o <abbr title=\"Garbage Collector\">GC</abbr> não recuperará esses elementos. Nesse caso, as duas opções são realizar uma cópia ou marcar explicitamente os elementos restantes ou seus campos como <code>nil</code>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/26-slice-memory-leak/slice-pointers\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"inicializacao-ineficiente-do-mapa-27\">Inicialização ineficiente do mapa (#27)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Ao criar um mapa, inicialize-o com um determinado comprimento se o seu comprimento já for conhecido. Isso reduz o número de alocações e melhora o desempenho.</p>\n</details>\n<p>Um mapa fornece uma coleção não ordenada de pares chave-valor em que todas as chaves são distintas. No Go, um mapa é baseado na estrutura de dados da tabela hash. Internamente, uma tabela hash é uma matriz de intervalos e cada intervalo é um ponteiro para uma matriz de pares de valores-chave.</p>\n<p>Se soubermos de antemão o número de elementos que um mapa conterá, devemos criá-lo fornecendo um tamanho inicial. Fazer isso evita o crescimento potencial do mapa, o que é bastante pesado em termos de computação porque requer a realocação de espaço suficiente e o reequilíbrio de todos os elementos.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/27-map-init/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"mapas-e-vazamentos-de-memoria-28\">Mapas e vazamentos de memória (#28)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Um mapa sempre pode crescer na memória, mas nunca diminui. Portanto, se isso causar alguns problemas de memória, você pode tentar diferentes opções, como forçar Go a recriar o mapa ou usar ponteiros.</p>\n</details>\n<p>Leia a seção completa <a href=\"../28-maps-memory-leaks/\">aqui</a>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/28-map-memory-leak/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"comparando-valores-incorretamente-29\">Comparando valores incorretamente (#29)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Para comparar tipos em Go, você pode usar os operadores == e != se dois tipos forem comparáveis: booleanos, numerais, strings, ponteiros, canais e estruturas são compostos inteiramente de tipos comparáveis. Caso contrário, você pode usar <code>reflect.DeepEquale</code> pagar o preço da reflexão ou usar implementações e bibliotecas personalizadas.</p>\n</details>\n<p>É essencial entender como usar <code>==</code> e <code>!=</code> para fazer comparações de forma eficaz. Podemos usar esses operadores em operandos comparáveis:</p>\n<ul>\n<li><em>Booleans</em>—Compara se dois booleanos são iguais.</li>\n<li><em>Numerics (int, float, and complex types)</em>—Compare se dois números são iguais.</li>\n<li><em>Strings</em>—Compare se duas strings são iguais.</li>\n<li><em>Channels</em>—Compare se dois canais foram criados pela mesma chamada a ser feita ou se ambos são nulos.</li>\n<li><em>Interfaces</em>—Compare se duas interfaces têm tipos dinâmicos idênticos e valores dinâmicos iguais ou se ambas são nulas.</li>\n<li><em>Pointers</em>—Compare se dois ponteiros apontam para o mesmo valor na memória ou se ambos são nulos.</li>\n<li><em>Structs and arrays</em>—Compare se são compostas de tipos semelhantes.</li>\n</ul>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>Também podemos usar os operadores <code>?</code>, <code>&gt;=</code>, <code>&lt;</code> e <code>&gt;</code> com tipos numéricos para comparar valores e com strings para comparar sua ordem lexical.</p>\n</details>\n<p>Se os operandos não forem comparáveis ​​(por exemplo, slices e mapas), teremos que usar outras opções, como reflexão. A reflexão é uma forma de metaprogramação e se refere à capacidade de um aplicativo de introspectar e modificar sua estrutura e comportamento. Por exemplo, em Go, podemos usar <code>reflect.DeepEqual</code>. Esta função informa se dois elementos são profundamente iguais percorrendo recursivamente dois valores. Os elementos que ele aceita são tipos básicos mais arrays, estruturas, slices, mapas, ponteiros, interfaces e funções. No entanto, o principal problema é a penalidade de desempenho.</p>\n<p>Se o desempenho for crucial em tempo de execução, implementar nosso método customizado pode ser a melhor solução. Uma observação adicional: devemos lembrar que a biblioteca padrão possui alguns métodos de comparação existentes. Por exemplo, podemos usar a função <code>bytes.Compare</code> otimizada para comparar duas slices de bytes. Antes de implementar um método customizado, precisamos ter certeza de não reinventar a roda.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/03-data-types/29-comparing-values/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h2 id=\"estruturas-de-controle\">Estruturas de Controle</h2>\n<h3 id=\"ignorando-que-os-elementos-sao-copiados-em-loops-de-range-30\">Ignorando que os elementos são copiados em loops de <code>range</code> (#30)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>O elemento de valor em um loop de <code>range</code> é uma cópia. Portanto, para modificar uma struct, por exemplo, acesse-a através de seu índice ou através de um loop <code>for</code> clássico (a menos que o elemento ou campo que você deseja modificar seja um ponteiro).</p>\n</details>\n<p>Um range loop permite iterar em diferentes estruturas de dados:</p>\n<ul>\n<li>String</li>\n<li>Array</li>\n<li>Pointer to an array</li>\n<li>Slice</li>\n<li>Map</li>\n<li>Receiving channel</li>\n</ul>\n<p>Comparado a um for <code>loop</code> clássico, um loop <code>range</code> é uma maneira conveniente de iterar todos os elementos de uma dessas estruturas de dados, graças à sua sintaxe concisa.</p>\n<p>Ainda assim, devemos lembrar que o elemento de valor em um range loop é uma cópia. Portanto, se o valor for uma estrutura que precisamos sofrer mutação, atualizaremos apenas a cópia, não o elemento em si, a menos que o valor ou campo que modificamos seja um ponteiro. As opções preferidas são acessar o elemento através do índice usando um range loop ou um loop for clássico.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/30-range-loop-element-copied/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"ignorando-como-os-argumentos-sao-avaliados-em-range-loops-canais-e-arrays-31\">Ignorando como os argumentos são avaliados em range loops (canais e arrays) (#31)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Entender que a expressão passada ao operador <code>range</code> é avaliada apenas uma vez antes do início do loop pode ajudar a evitar erros comuns, como atribuição ineficiente em canal ou iteração de slice.</p>\n</details>\n<p>O range loop avalia a expressão fornecida apenas uma vez, antes do início do loop, fazendo uma cópia (independentemente do tipo). Devemos lembrar deste comportamento para evitar erros comuns que podem, por exemplo, nos levar a acessar o elemento errado. Por exemplo:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-9-1\"><a id=\"__codelineno-9-1\" name=\"__codelineno-9-1\" href=\"#__codelineno-9-1\"></a><span class=\"nx\">a</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">]</span><span class=\"kt\">int</span><span class=\"p\">{</span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"p\">}</span>\n</span><span id=\"__span-9-2\"><a id=\"__codelineno-9-2\" name=\"__codelineno-9-2\" href=\"#__codelineno-9-2\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">a</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-9-3\"><a id=\"__codelineno-9-3\" name=\"__codelineno-9-3\" href=\"#__codelineno-9-3\"></a><span class=\"w\">    </span><span class=\"nx\">a</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">]</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"mi\">10</span>\n</span><span id=\"__span-9-4\"><a id=\"__codelineno-9-4\" name=\"__codelineno-9-4\" href=\"#__codelineno-9-4\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">==</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-9-5\"><a id=\"__codelineno-9-5\" name=\"__codelineno-9-5\" href=\"#__codelineno-9-5\"></a><span class=\"w\">        </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">v</span><span class=\"p\">)</span>\n</span><span id=\"__span-9-6\"><a id=\"__codelineno-9-6\" name=\"__codelineno-9-6\" href=\"#__codelineno-9-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-9-7\"><a id=\"__codelineno-9-7\" name=\"__codelineno-9-7\" href=\"#__codelineno-9-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Este código atualiza o último índice para 10. No entanto, se executarmos este código, ele não imprimirá 10; imprime 2.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/31-range-loop-arg-evaluation/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"ignorando-os-impactos-do-uso-de-elementos-ponteiros-em-range-loops-32\"><img alt=\"⚠\" class=\"twemoji\" src=\"https://cdn.jsdelivr.net/gh/jdecked/twemoji@15.1.0/assets/svg/26a0.svg\" title=\":warning:\"> Ignorando os impactos do uso de elementos ponteiros em <code>range</code> loops (#32)</h3>\n<details class=\"warning\" open=\"open\">\n<summary>Warning</summary>\n<p>Este erro não é mais relevante no Go 1.22 (<a href=\"https://go.dev/blog/loopvar-preview\">detalhes</a>).</p>\n</details>\n<h3 id=\"fazendo-suposicoes-erradas-durante-as-iteracoes-de-maps-ordenacao-e-insercao-do-mapa-durante-a-iteracao-33\">Fazendo suposições erradas durante as iterações de maps (ordenação e inserção do mapa durante a iteração) (#33)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Para garantir resultados previsíveis ao usar maps, lembre-se de que uma estrutura de dados de mapa:</p>\n</details>\n<ul>\n<li>Não ordena os dados por chaves</li>\n<li>Não preserva o pedido de inserção</li>\n<li>Não tem uma ordem de iteração determinística</li>\n<li>Não garante que um elemento adicionado durante uma iteração será produzido durante esta iteração</li>\n</ul>\n<!-- TODO -->\n\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/33-map-iteration/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"ignorando-como-a-declaracao-break-funciona-34\">Ignorando como a declaração <code>break</code> funciona (#34)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Usar <code>break</code> ou <code>continue</code> com um rótulo impõe a quebra de uma instrução específica. Isso pode ser útil com instruções <code>switch</code> ou <code>select</code> dentro de loops.</p>\n</details>\n<p>Uma instrução break é comumente usada para encerrar a execução de um loop. Quando loops são usados ​​em conjunto com switch ou select, os desenvolvedores frequentemente cometem o erro de quebrar a instrução errada. Por exemplo:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-10-1\"><a id=\"__codelineno-10-1\" name=\"__codelineno-10-1\" href=\"#__codelineno-10-1\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">5</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-10-2\"><a id=\"__codelineno-10-2\" name=\"__codelineno-10-2\" href=\"#__codelineno-10-2\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"%d \"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">)</span>\n</span><span id=\"__span-10-3\"><a id=\"__codelineno-10-3\" name=\"__codelineno-10-3\" href=\"#__codelineno-10-3\"></a>\n</span><span id=\"__span-10-4\"><a id=\"__codelineno-10-4\" name=\"__codelineno-10-4\" href=\"#__codelineno-10-4\"></a><span class=\"w\">    </span><span class=\"k\">switch</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-10-5\"><a id=\"__codelineno-10-5\" name=\"__codelineno-10-5\" href=\"#__codelineno-10-5\"></a><span class=\"w\">    </span><span class=\"k\">default</span><span class=\"p\">:</span>\n</span><span id=\"__span-10-6\"><a id=\"__codelineno-10-6\" name=\"__codelineno-10-6\" href=\"#__codelineno-10-6\"></a><span class=\"w\">    </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"p\">:</span>\n</span><span id=\"__span-10-7\"><a id=\"__codelineno-10-7\" name=\"__codelineno-10-7\" href=\"#__codelineno-10-7\"></a><span class=\"w\">        </span><span class=\"k\">break</span>\n</span><span id=\"__span-10-8\"><a id=\"__codelineno-10-8\" name=\"__codelineno-10-8\" href=\"#__codelineno-10-8\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-10-9\"><a id=\"__codelineno-10-9\" name=\"__codelineno-10-9\" href=\"#__codelineno-10-9\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>A instrução break não encerra o loop <code>for</code>: em vez disso, ela encerra a instrução <code>switch</code>. Portanto, em vez de iterar de 0 a 2, este código itera de 0 a 4: <code>0 1 2 3 4</code>.</p>\n<p>Uma regra essencial a ter em mente é que uma instrução <code>break</code> encerra a execução da instrução <code>for</code>, <code>switch</code>, ou mais interna <code>select</code>. No exemplo anterior, ele encerra a instrução <code>switch</code>.</p>\n<p>Para quebrar o loop em vez da instrução <code>switch</code>, a maneira mais idiomática é usar um rótulo:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-11-1\"><a id=\"__codelineno-11-1\" name=\"__codelineno-11-1\" href=\"#__codelineno-11-1\"></a><span class=\"hll\"><span class=\"nx\">loop</span><span class=\"p\">:</span>\n</span></span><span id=\"__span-11-2\"><a id=\"__codelineno-11-2\" name=\"__codelineno-11-2\" href=\"#__codelineno-11-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">5</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-11-3\"><a id=\"__codelineno-11-3\" name=\"__codelineno-11-3\" href=\"#__codelineno-11-3\"></a><span class=\"w\">        </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"%d \"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">)</span>\n</span><span id=\"__span-11-4\"><a id=\"__codelineno-11-4\" name=\"__codelineno-11-4\" href=\"#__codelineno-11-4\"></a>\n</span><span id=\"__span-11-5\"><a id=\"__codelineno-11-5\" name=\"__codelineno-11-5\" href=\"#__codelineno-11-5\"></a><span class=\"w\">        </span><span class=\"k\">switch</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-11-6\"><a id=\"__codelineno-11-6\" name=\"__codelineno-11-6\" href=\"#__codelineno-11-6\"></a><span class=\"w\">        </span><span class=\"k\">default</span><span class=\"p\">:</span>\n</span><span id=\"__span-11-7\"><a id=\"__codelineno-11-7\" name=\"__codelineno-11-7\" href=\"#__codelineno-11-7\"></a><span class=\"w\">        </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"mi\">2</span><span class=\"p\">:</span>\n</span><span id=\"__span-11-8\"><a id=\"__codelineno-11-8\" name=\"__codelineno-11-8\" href=\"#__codelineno-11-8\"></a><span class=\"hll\"><span class=\"w\">            </span><span class=\"k\">break</span><span class=\"w\"> </span><span class=\"nx\">loop</span>\n</span></span><span id=\"__span-11-9\"><a id=\"__codelineno-11-9\" name=\"__codelineno-11-9\" href=\"#__codelineno-11-9\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-11-10\"><a id=\"__codelineno-11-10\" name=\"__codelineno-11-10\" href=\"#__codelineno-11-10\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Aqui, associamos o <code>loop</code>rótulo ao <code>for</code> loop. Então, como fornecemos o <code>loop</code> rótulo para a instrução <code>break</code>, ela interrompe o loop, não a opção. Portanto, esta nova versão será impressa <code>0 1 2</code>, como esperávamos.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/34-break/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"usando-defer-dentro-de-um-loop-35\">Usando <code>defer</code> dentro de um loop (#35)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Extrair a lógica do loop dentro de uma função leva à execução de uma instrução <code>defer</code> no final de cada iteração.</p>\n</details>\n<p>A instrução <code>defer</code> atrasa a execução de uma chamada até que a função circundante retorne. É usado principalmente para reduzir o código padrão. Por exemplo, se um recurso precisar ser fechado eventualmente, podemos usar <code>defer</code> para evitar a repetição das chamadas de fechamento antes de cada <code>return</code>.</p>\n<p>Um erro comum com <code>defer</code> é esquecer que ele agenda uma chamada de função quando a função <em>circundante</em> retorna. Por exemplo:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-12-1\"><a id=\"__codelineno-12-1\" name=\"__codelineno-12-1\" href=\"#__codelineno-12-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">readFiles</span><span class=\"p\">(</span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-12-2\"><a id=\"__codelineno-12-2\" name=\"__codelineno-12-2\" href=\"#__codelineno-12-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">path</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-12-3\"><a id=\"__codelineno-12-3\" name=\"__codelineno-12-3\" href=\"#__codelineno-12-3\"></a><span class=\"w\">        </span><span class=\"nx\">file</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">os</span><span class=\"p\">.</span><span class=\"nx\">Open</span><span class=\"p\">(</span><span class=\"nx\">path</span><span class=\"p\">)</span>\n</span><span id=\"__span-12-4\"><a id=\"__codelineno-12-4\" name=\"__codelineno-12-4\" href=\"#__codelineno-12-4\"></a><span class=\"w\">        </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-12-5\"><a id=\"__codelineno-12-5\" name=\"__codelineno-12-5\" href=\"#__codelineno-12-5\"></a><span class=\"w\">            </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-12-6\"><a id=\"__codelineno-12-6\" name=\"__codelineno-12-6\" href=\"#__codelineno-12-6\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-12-7\"><a id=\"__codelineno-12-7\" name=\"__codelineno-12-7\" href=\"#__codelineno-12-7\"></a>\n</span><span id=\"__span-12-8\"><a id=\"__codelineno-12-8\" name=\"__codelineno-12-8\" href=\"#__codelineno-12-8\"></a><span class=\"w\">        </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">file</span><span class=\"p\">.</span><span class=\"nx\">Close</span><span class=\"p\">()</span>\n</span><span id=\"__span-12-9\"><a id=\"__codelineno-12-9\" name=\"__codelineno-12-9\" href=\"#__codelineno-12-9\"></a>\n</span><span id=\"__span-12-10\"><a id=\"__codelineno-12-10\" name=\"__codelineno-12-10\" href=\"#__codelineno-12-10\"></a><span class=\"w\">        </span><span class=\"c1\">// Do something with file</span>\n</span><span id=\"__span-12-11\"><a id=\"__codelineno-12-11\" name=\"__codelineno-12-11\" href=\"#__codelineno-12-11\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-12-12\"><a id=\"__codelineno-12-12\" name=\"__codelineno-12-12\" href=\"#__codelineno-12-12\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-12-13\"><a id=\"__codelineno-12-13\" name=\"__codelineno-12-13\" href=\"#__codelineno-12-13\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>As chamadas <code>defer</code> não são executadas durante cada iteração do loop, mas quando a função <code>readFiles</code> retorna. Se <code>readFiles</code> não retornar, os descritores de arquivos ficarão abertos para sempre, causando vazamentos.</p>\n<p>Uma opção comum para corrigir esse problema é criar uma função circundante após <code>defer</code>, chamada durante cada iteração:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-13-1\"><a id=\"__codelineno-13-1\" name=\"__codelineno-13-1\" href=\"#__codelineno-13-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">readFiles</span><span class=\"p\">(</span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-2\"><a id=\"__codelineno-13-2\" name=\"__codelineno-13-2\" href=\"#__codelineno-13-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">path</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-3\"><a id=\"__codelineno-13-3\" name=\"__codelineno-13-3\" href=\"#__codelineno-13-3\"></a><span class=\"w\">        </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">readFile</span><span class=\"p\">(</span><span class=\"nx\">path</span><span class=\"p\">);</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-4\"><a id=\"__codelineno-13-4\" name=\"__codelineno-13-4\" href=\"#__codelineno-13-4\"></a><span class=\"w\">            </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-13-5\"><a id=\"__codelineno-13-5\" name=\"__codelineno-13-5\" href=\"#__codelineno-13-5\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-13-6\"><a id=\"__codelineno-13-6\" name=\"__codelineno-13-6\" href=\"#__codelineno-13-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-13-7\"><a id=\"__codelineno-13-7\" name=\"__codelineno-13-7\" href=\"#__codelineno-13-7\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-13-8\"><a id=\"__codelineno-13-8\" name=\"__codelineno-13-8\" href=\"#__codelineno-13-8\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-13-9\"><a id=\"__codelineno-13-9\" name=\"__codelineno-13-9\" href=\"#__codelineno-13-9\"></a>\n</span><span id=\"__span-13-10\"><a id=\"__codelineno-13-10\" name=\"__codelineno-13-10\" href=\"#__codelineno-13-10\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">readFile</span><span class=\"p\">(</span><span class=\"nx\">path</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-11\"><a id=\"__codelineno-13-11\" name=\"__codelineno-13-11\" href=\"#__codelineno-13-11\"></a><span class=\"w\">    </span><span class=\"nx\">file</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">os</span><span class=\"p\">.</span><span class=\"nx\">Open</span><span class=\"p\">(</span><span class=\"nx\">path</span><span class=\"p\">)</span>\n</span><span id=\"__span-13-12\"><a id=\"__codelineno-13-12\" name=\"__codelineno-13-12\" href=\"#__codelineno-13-12\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-13-13\"><a id=\"__codelineno-13-13\" name=\"__codelineno-13-13\" href=\"#__codelineno-13-13\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-13-14\"><a id=\"__codelineno-13-14\" name=\"__codelineno-13-14\" href=\"#__codelineno-13-14\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-13-15\"><a id=\"__codelineno-13-15\" name=\"__codelineno-13-15\" href=\"#__codelineno-13-15\"></a>\n</span><span id=\"__span-13-16\"><a id=\"__codelineno-13-16\" name=\"__codelineno-13-16\" href=\"#__codelineno-13-16\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">file</span><span class=\"p\">.</span><span class=\"nx\">Close</span><span class=\"p\">()</span>\n</span><span id=\"__span-13-17\"><a id=\"__codelineno-13-17\" name=\"__codelineno-13-17\" href=\"#__codelineno-13-17\"></a>\n</span><span id=\"__span-13-18\"><a id=\"__codelineno-13-18\" name=\"__codelineno-13-18\" href=\"#__codelineno-13-18\"></a><span class=\"w\">    </span><span class=\"c1\">// Do something with file</span>\n</span><span id=\"__span-13-19\"><a id=\"__codelineno-13-19\" name=\"__codelineno-13-19\" href=\"#__codelineno-13-19\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-13-20\"><a id=\"__codelineno-13-20\" name=\"__codelineno-13-20\" href=\"#__codelineno-13-20\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Outra solução é tornar a função <code>readFile</code> um encerramento, mas intrinsecamente, esta permanece a mesma solução: adicionar outra função circundante para executar as chamadas <code>defer</code> durante cada iteração.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/04-control-structures/35-defer-loop/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h2 id=\"strings\">Strings</h2>\n<h3 id=\"nao-entendendo-o-conceito-de-rune-36\">Não entendendo o conceito de rune (#36)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Entender que uma runa corresponde ao conceito de um ponto de código Unicode e que pode ser composta de múltiplos bytes deve fazer parte do conhecimento básico do desenvolvedor Go para trabalhar com precisão com strings.</p>\n</details>\n<p>Como as runas estão por toda parte no Go, é importante entender o seguinte:</p>\n<ul>\n<li>Um conjunto de caracteres é um conjunto de caracteres, enquanto uma codificação descreve como traduzir um conjunto de caracteres em binário.</li>\n<li>No Go, uma string faz referência a uma fatia imutável de bytes arbitrários.</li>\n<li>O código-fonte Go é codificado usando UTF-8. Portanto, todos os literais de string são strings UTF-8. Mas como uma string pode conter bytes arbitrários, se for obtida de outro lugar (não do código-fonte), não há garantia de que seja baseada na codificação UTF-8.</li>\n<li>A <code>rune</code> corresponde ao conceito de ponto de código Unicode, significando um item representado por um único valor.</li>\n<li>Usando UTF-8, um ponto de código Unicode pode ser codificado em 1 a 4 bytes.</li>\n<li>Usar <code>len()</code> na string em Go retorna o número de bytes, não o número de runas.</li>\n</ul>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/36-rune/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"iteracao-de-string-imprecisa-37\">Iteração de string imprecisa (#37)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Iterar em uma string com o operador <code>range</code> itera nas runas com o índice correspondente ao índice inicial da sequência de bytes da runa. Para acessar um índice de runa específico (como a terceira runa), converta a string em um arquivo <code>[]rune</code>.</p>\n</details>\n<p>Iterar em uma string é uma operação comum para desenvolvedores. Talvez queiramos realizar uma operação para cada runa na string ou implementar uma função personalizada para procurar uma substring específica. Em ambos os casos, temos que iterar nas diferentes runas de uma string. Mas é fácil ficar confuso sobre como funciona a iteração.</p>\n<p>For example, consider the following example:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-14-1\"><a id=\"__codelineno-14-1\" name=\"__codelineno-14-1\" href=\"#__codelineno-14-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"s\">\"hêllo\"</span>\n</span><span id=\"__span-14-2\"><a id=\"__codelineno-14-2\" name=\"__codelineno-14-2\" href=\"#__codelineno-14-2\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-14-3\"><a id=\"__codelineno-14-3\" name=\"__codelineno-14-3\" href=\"#__codelineno-14-3\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"position %d: %c\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"p\">[</span><span class=\"nx\">i</span><span class=\"p\">])</span>\n</span><span id=\"__span-14-4\"><a id=\"__codelineno-14-4\" name=\"__codelineno-14-4\" href=\"#__codelineno-14-4\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-14-5\"><a id=\"__codelineno-14-5\" name=\"__codelineno-14-5\" href=\"#__codelineno-14-5\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"len=%d\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">))</span>\n</span></code></pre></div>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-15-1\"><a id=\"__codelineno-15-1\" name=\"__codelineno-15-1\" href=\"#__codelineno-15-1\"></a>position 0: h\n</span><span id=\"__span-15-2\"><a id=\"__codelineno-15-2\" name=\"__codelineno-15-2\" href=\"#__codelineno-15-2\"></a>position 1: Ã\n</span><span id=\"__span-15-3\"><a id=\"__codelineno-15-3\" name=\"__codelineno-15-3\" href=\"#__codelineno-15-3\"></a>position 3: l\n</span><span id=\"__span-15-4\"><a id=\"__codelineno-15-4\" name=\"__codelineno-15-4\" href=\"#__codelineno-15-4\"></a>position 4: l\n</span><span id=\"__span-15-5\"><a id=\"__codelineno-15-5\" name=\"__codelineno-15-5\" href=\"#__codelineno-15-5\"></a>position 5: o\n</span><span id=\"__span-15-6\"><a id=\"__codelineno-15-6\" name=\"__codelineno-15-6\" href=\"#__codelineno-15-6\"></a>len=6\n</span></code></pre></div>\n<p>Vamos destacar três pontos que podem ser confusos:</p>\n<ul>\n<li>A segunda runa é Ã na saída em vez de ê.</li>\n<li>Saltamos da posição 1 para a posição 3: o que há na posição 2?</li>\n<li>len retorna uma contagem de 6, enquanto s contém apenas 5 runas.</li>\n</ul>\n<p>Vamos começar com a última observação. Já mencionamos que len retorna o número de bytes em uma string, não o número de runas. Como atribuímos uma string literal a <code>s</code>, <code>s</code> é uma string UTF-8. Enquanto isso, o caractere especial “ê” não é codificado em um único byte; requer 2 bytes. Portanto, chamar <code>len(s)</code> retorna 6.</p>\n<p>Enquanto isso, no exemplo anterior, temos que entender que não repetimos cada runa; em vez disso, iteramos sobre cada índice inicial de uma runa:</p>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/rune.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/rune.png\"></a></p>\n<p>Imprimir <code>s[i]</code> não imprime a i-ésima runa; imprime a representação UTF-8 do byte em index <code>i</code>. Portanto, imprimimos \"hÃllo\" em vez de \"hêllo\".</p>\n<p>Se quisermos imprimir todas as diferentes runas, podemos usar o elemento value do operador <code>range</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-16-1\"><a id=\"__codelineno-16-1\" name=\"__codelineno-16-1\" href=\"#__codelineno-16-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"s\">\"hêllo\"</span>\n</span><span id=\"__span-16-2\"><a id=\"__codelineno-16-2\" name=\"__codelineno-16-2\" href=\"#__codelineno-16-2\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-16-3\"><a id=\"__codelineno-16-3\" name=\"__codelineno-16-3\" href=\"#__codelineno-16-3\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"position %d: %c\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"p\">)</span>\n</span><span id=\"__span-16-4\"><a id=\"__codelineno-16-4\" name=\"__codelineno-16-4\" href=\"#__codelineno-16-4\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Ou podemos converter a string em uma fatia de runas e iterar sobre ela:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-17-1\"><a id=\"__codelineno-17-1\" name=\"__codelineno-17-1\" href=\"#__codelineno-17-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"s\">\"hêllo\"</span>\n</span><span id=\"__span-17-2\"><a id=\"__codelineno-17-2\" name=\"__codelineno-17-2\" href=\"#__codelineno-17-2\"></a><span class=\"hll\"><span class=\"nx\">runes</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"nb\">rune</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-17-3\"><a id=\"__codelineno-17-3\" name=\"__codelineno-17-3\" href=\"#__codelineno-17-3\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">runes</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-17-4\"><a id=\"__codelineno-17-4\" name=\"__codelineno-17-4\" href=\"#__codelineno-17-4\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"position %d: %c\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"p\">)</span>\n</span><span id=\"__span-17-5\"><a id=\"__codelineno-17-5\" name=\"__codelineno-17-5\" href=\"#__codelineno-17-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Observe que esta solução introduz uma sobrecarga de tempo de execução em comparação com a anterior. Na verdade, converter uma string em uma fatia de runas requer a alocação de uma fatia adicional e a conversão dos bytes em runas: uma complexidade de tempo O(n) com n o número de bytes na string. Portanto, se quisermos iterar todas as runas, devemos usar a primeira solução.</p>\n<p>Porém, se quisermos acessar a i-ésima runa de uma string com a primeira opção, não teremos acesso ao índice da runa; em vez disso, conhecemos o índice inicial de uma runa na sequência de bytes.</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-18-1\"><a id=\"__codelineno-18-1\" name=\"__codelineno-18-1\" href=\"#__codelineno-18-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"s\">\"hêllo\"</span>\n</span><span id=\"__span-18-2\"><a id=\"__codelineno-18-2\" name=\"__codelineno-18-2\" href=\"#__codelineno-18-2\"></a><span class=\"nx\">r</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"nb\">rune</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)[</span><span class=\"mi\">4</span><span class=\"p\">]</span>\n</span><span id=\"__span-18-3\"><a id=\"__codelineno-18-3\" name=\"__codelineno-18-3\" href=\"#__codelineno-18-3\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Printf</span><span class=\"p\">(</span><span class=\"s\">\"%c\\n\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"c1\">// o</span>\n</span></code></pre></div>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/37-string-iteration/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"uso-indevido-de-funcoes-de-trim-38\">Uso indevido de funções de trim (#38)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p><code>strings.TrimRight</code>/<code>strings.TrimLeft</code> remove todas as runas finais/iniciais contidas em um determinado conjunto, enquanto <code>strings.TrimSuffix</code>/<code>strings.TrimPrefix</code> retorna uma string sem um sufixo/prefixo fornecido.</p>\n</details>\n<p>Por exemplo:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-19-1\"><a id=\"__codelineno-19-1\" name=\"__codelineno-19-1\" href=\"#__codelineno-19-1\"></a><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">strings</span><span class=\"p\">.</span><span class=\"nx\">TrimRight</span><span class=\"p\">(</span><span class=\"s\">\"123oxo\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s\">\"xo\"</span><span class=\"p\">))</span>\n</span></code></pre></div>\n<p>O exemplo imprime 123:</p>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/trim.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/trim.png\"></a></p>\n<p>Por outro lado, <code>strings.TrimLeft</code> remove todas as runas principais contidas em um conjunto.</p>\n<p>Por outro lado, <code>strings.TrimSuffix</code>/<code>strings.TrimPrefix</code> retorna uma string sem o sufixo/prefixo final fornecido.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/38-trim/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"concatenacao-de-strings-subotimizada-39\">Concatenação de strings subotimizada (#39)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>A concatenação de uma lista de strings deve ser feita com <code>strings.Builder</code> para evitar a alocação de uma nova string durante cada iteração.</p>\n</details>\n<p>Vamos considerar uma função <code>concat</code> que concatena todos os elementos string de uma fatia usando o operador <code>+=</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-20-1\"><a id=\"__codelineno-20-1\" name=\"__codelineno-20-1\" href=\"#__codelineno-20-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">concat</span><span class=\"p\">(</span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-20-2\"><a id=\"__codelineno-20-2\" name=\"__codelineno-20-2\" href=\"#__codelineno-20-2\"></a><span class=\"w\">    </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"s\">\"\"</span>\n</span><span id=\"__span-20-3\"><a id=\"__codelineno-20-3\" name=\"__codelineno-20-3\" href=\"#__codelineno-20-3\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">value</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-20-4\"><a id=\"__codelineno-20-4\" name=\"__codelineno-20-4\" href=\"#__codelineno-20-4\"></a><span class=\"w\">        </span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"nx\">value</span>\n</span><span id=\"__span-20-5\"><a id=\"__codelineno-20-5\" name=\"__codelineno-20-5\" href=\"#__codelineno-20-5\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-20-6\"><a id=\"__codelineno-20-6\" name=\"__codelineno-20-6\" href=\"#__codelineno-20-6\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">s</span>\n</span><span id=\"__span-20-7\"><a id=\"__codelineno-20-7\" name=\"__codelineno-20-7\" href=\"#__codelineno-20-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Durante cada iteração, o operador <code>+=</code> concatena com <code>s</code> a sequência de valores. À primeira vista, esta função pode não parecer errada. Mas com esta implementação, esquecemos uma das principais características de uma string: a sua imutabilidade. Portanto, cada iteração não é atualizada <code>s</code>; ele realoca uma nova string na memória, o que impacta significativamente o desempenho desta função.</p>\n<p>Felizmente, existe uma solução para lidar com esse problema, usando <code>strings.Builder</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-21-1\"><a id=\"__codelineno-21-1\" name=\"__codelineno-21-1\" href=\"#__codelineno-21-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">concat</span><span class=\"p\">(</span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-21-2\"><a id=\"__codelineno-21-2\" name=\"__codelineno-21-2\" href=\"#__codelineno-21-2\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"nx\">sb</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">strings</span><span class=\"p\">.</span><span class=\"nx\">Builder</span><span class=\"p\">{}</span>\n</span></span><span id=\"__span-21-3\"><a id=\"__codelineno-21-3\" name=\"__codelineno-21-3\" href=\"#__codelineno-21-3\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">value</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-21-4\"><a id=\"__codelineno-21-4\" name=\"__codelineno-21-4\" href=\"#__codelineno-21-4\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">sb</span><span class=\"p\">.</span><span class=\"nx\">WriteString</span><span class=\"p\">(</span><span class=\"nx\">value</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-21-5\"><a id=\"__codelineno-21-5\" name=\"__codelineno-21-5\" href=\"#__codelineno-21-5\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-21-6\"><a id=\"__codelineno-21-6\" name=\"__codelineno-21-6\" href=\"#__codelineno-21-6\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">sb</span><span class=\"p\">.</span><span class=\"nx\">String</span><span class=\"p\">()</span>\n</span><span id=\"__span-21-7\"><a id=\"__codelineno-21-7\" name=\"__codelineno-21-7\" href=\"#__codelineno-21-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Durante cada iteração, construímos a string resultante chamando o método <code>WriteString</code> que anexa o conteúdo do valor ao seu buffer interno, minimizando assim a cópia da memória.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p><code>WriteString</code> retorna um erro como segunda saída, mas nós o ignoramos propositalmente. Na verdade, este método nunca retornará um erro diferente de zero. Então, qual é o propósito deste método retornar um erro como parte de sua assinatura? <code>strings.Builder</code> implementa a <code>io.StringWriter</code> interface, que contém um único método: <code>WriteString(s string) (n int, err error)</code>. Portanto, para estar em conformidade com esta interface, <code>WriteString</code> deve retornar um erro.</p>\n</details>\n<p>Internamente, <code>strings.Builder</code> contém uma fatia de bytes. Cada chamada para <code>WriteString</code> resulta em uma chamada para anexar nesta fatia. Existem dois impactos. Primeiro, esta estrutura não deve ser usada simultaneamente, pois as chamadas <code>append</code> levariam a condições de corrida. O segundo impacto é algo que vimos no <a href=\"#inefficient-slice-initialization-21\">mistake #21, \"Inicialização de slice ineficiente\"</a>: se o comprimento futuro de uma slice já for conhecido, devemos pré-alocá-la. Para isso, <code>strings.Builder</code> expõe um método <code>Grow(n int)</code> para garantir espaço para outros <code>n</code> bytes:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-22-1\"><a id=\"__codelineno-22-1\" name=\"__codelineno-22-1\" href=\"#__codelineno-22-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">concat</span><span class=\"p\">(</span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-22-2\"><a id=\"__codelineno-22-2\" name=\"__codelineno-22-2\" href=\"#__codelineno-22-2\"></a><span class=\"w\">    </span><span class=\"nx\">total</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span>\n</span><span id=\"__span-22-3\"><a id=\"__codelineno-22-3\" name=\"__codelineno-22-3\" href=\"#__codelineno-22-3\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">values</span><span class=\"p\">);</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-22-4\"><a id=\"__codelineno-22-4\" name=\"__codelineno-22-4\" href=\"#__codelineno-22-4\"></a><span class=\"w\">        </span><span class=\"nx\">total</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">values</span><span class=\"p\">[</span><span class=\"nx\">i</span><span class=\"p\">])</span>\n</span><span id=\"__span-22-5\"><a id=\"__codelineno-22-5\" name=\"__codelineno-22-5\" href=\"#__codelineno-22-5\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-22-6\"><a id=\"__codelineno-22-6\" name=\"__codelineno-22-6\" href=\"#__codelineno-22-6\"></a>\n</span><span id=\"__span-22-7\"><a id=\"__codelineno-22-7\" name=\"__codelineno-22-7\" href=\"#__codelineno-22-7\"></a><span class=\"w\">    </span><span class=\"nx\">sb</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">strings</span><span class=\"p\">.</span><span class=\"nx\">Builder</span><span class=\"p\">{}</span>\n</span><span id=\"__span-22-8\"><a id=\"__codelineno-22-8\" name=\"__codelineno-22-8\" href=\"#__codelineno-22-8\"></a><span class=\"w\">    </span><span class=\"nx\">sb</span><span class=\"p\">.</span><span class=\"nx\">Grow</span><span class=\"p\">(</span><span class=\"nx\">total</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n</span><span id=\"__span-22-9\"><a id=\"__codelineno-22-9\" name=\"__codelineno-22-9\" href=\"#__codelineno-22-9\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">value</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">values</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-22-10\"><a id=\"__codelineno-22-10\" name=\"__codelineno-22-10\" href=\"#__codelineno-22-10\"></a><span class=\"w\">        </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">sb</span><span class=\"p\">.</span><span class=\"nx\">WriteString</span><span class=\"p\">(</span><span class=\"nx\">value</span><span class=\"p\">)</span>\n</span><span id=\"__span-22-11\"><a id=\"__codelineno-22-11\" name=\"__codelineno-22-11\" href=\"#__codelineno-22-11\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-22-12\"><a id=\"__codelineno-22-12\" name=\"__codelineno-22-12\" href=\"#__codelineno-22-12\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">sb</span><span class=\"p\">.</span><span class=\"nx\">String</span><span class=\"p\">()</span>\n</span><span id=\"__span-22-13\"><a id=\"__codelineno-22-13\" name=\"__codelineno-22-13\" href=\"#__codelineno-22-13\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Vamos executar um benchmark para comparar as três versões (v1 usando <code>+=</code>; v2 usando <code>strings.Builder{}</code> sem pré-alocação; e v3 usando <code>strings.Builder{}</code> com pré-alocação). A slice de entrada contém 1.000 strings e cada string contém 1.000 bytes:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-23-1\"><a id=\"__codelineno-23-1\" name=\"__codelineno-23-1\" href=\"#__codelineno-23-1\"></a>BenchmarkConcatV1-4             16      72291485 ns/op\n</span><span id=\"__span-23-2\"><a id=\"__codelineno-23-2\" name=\"__codelineno-23-2\" href=\"#__codelineno-23-2\"></a>BenchmarkConcatV2-4           1188        878962 ns/op\n</span><span id=\"__span-23-3\"><a id=\"__codelineno-23-3\" name=\"__codelineno-23-3\" href=\"#__codelineno-23-3\"></a>BenchmarkConcatV3-4           5922        190340 ns/op\n</span></code></pre></div>\n<p>Como podemos ver, a versão mais recente é de longe a mais eficiente: 99% mais rápida que a v1 e 78% mais rápida que a v2.</p>\n<p><code>strings.Builder</code> é a solução recomendada para concatenar uma lista de strings. Normalmente, esta solução deve ser usada dentro de um loop. Na verdade, se precisarmos apenas concatenar algumas strings (como um nome e um sobrenome), o uso <code>strings.Builder</code> não é recomendado, pois isso tornará o código um pouco menos legível do que usar o operador <code>+=</code> or <code>fmt.Sprintf</code>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/39-string-concat/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"conversoes-de-string-inuteis-40\">Conversões de string inúteis (#40)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Lembrar que o pacote <code>bytes</code> oferece as mesmas operações que o pacote <code>strings</code> pode ajudar a evitar conversões extras de bytes/string.</p>\n</details>\n<p>Ao optar por trabalhar com uma string ou um <code>[]byte</code>, a maioria dos programadores tende a preferir strings por conveniência. Mas a maior parte da E/S é realmente feita com <code>[]byte</code>. Por exemplo, <code>io.Reader</code>, <code>io.Writer</code> e <code>io.ReadAll</code> trabalham com <code>[]byte</code>, não com strings.</p>\n<p>Quando nos perguntamos se devemos trabalhar com strings ou <code>[]byte</code>, lembremos que trabalhar com <code>[]byte</code>não é necessariamente menos conveniente. Na verdade, todas as funções exportadas do pacote strings também possuem alternativas no pacote <code>bytes</code>: <code>Split</code>, <code>Count</code>, <code>Contains</code>, <code>Index</code> e assim por diante. Portanto, estejamos fazendo I/O ou não, devemos primeiro verificar se poderíamos implementar um fluxo de trabalho completo usando bytes em vez de strings e evitar o preço de conversões adicionais.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/40-string-conversion/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"vazamentos-de-substring-e-memoria-41\">Vazamentos de substring e memória (#41)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Usar cópias em vez de substrings pode evitar vazamentos de memória, pois a string retornada por uma operação de substring será apoiada pela mesma matriz de bytes.</p>\n</details>\n<p>In mistake <a href=\"#slice-and-memory-leaks--26-\">#26, “Slices and memory leaks,”</a> we saw how slicing a slice or array may lead to memory leak situations. This principle also applies to string and substring operations.</p>\n<p>We need to keep two things in mind while using the substring operation in Go. First, the interval provided is based on the number of bytes, not the number of runes. Second, a substring operation may lead to a memory leak as the resulting substring will share the same backing array as the initial string. The solutions to prevent this case from happening are to perform a string copy manually or to use <code>strings.Clone</code> from Go 1.18.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/05-strings/41-substring-memory-leak/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h2 id=\"functions-and-methods\">Functions and Methods</h2>\n<h3 id=\"nao-saber-que-tipo-de-receptor-usar-42\">Não saber que tipo de receptor usar (#42)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>A decisão de usar um valor ou um receptor de ponteiro deve ser tomada com base em fatores como o tipo, se deve sofrer mutação, se contém um campo que não pode ser copiado e o tamanho do objeto. Em caso de dúvida, use um receptor de ponteiro.</p>\n</details>\n<p>Choosing between value and pointer receivers isn’t always straightforward. Let’s discuss some of the conditions to help us choose.</p>\n<p>A receiver <em>must</em> be a pointer</p>\n<ul>\n<li>If the method needs to mutate the receiver. This rule is also valid if the receiver is a slice and a method needs to append elements:</li>\n</ul>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-24-1\"><a id=\"__codelineno-24-1\" name=\"__codelineno-24-1\" href=\"#__codelineno-24-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">slice</span><span class=\"w\"> </span><span class=\"p\">[]</span><span class=\"kt\">int</span>\n</span><span id=\"__span-24-2\"><a id=\"__codelineno-24-2\" name=\"__codelineno-24-2\" href=\"#__codelineno-24-2\"></a>\n</span><span id=\"__span-24-3\"><a id=\"__codelineno-24-3\" name=\"__codelineno-24-3\" href=\"#__codelineno-24-3\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">slice</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">add</span><span class=\"p\">(</span><span class=\"nx\">element</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-24-4\"><a id=\"__codelineno-24-4\" name=\"__codelineno-24-4\" href=\"#__codelineno-24-4\"></a><span class=\"w\">    </span><span class=\"o\">*</span><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">element</span><span class=\"p\">)</span>\n</span><span id=\"__span-24-5\"><a id=\"__codelineno-24-5\" name=\"__codelineno-24-5\" href=\"#__codelineno-24-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<ul>\n<li>If the method receiver contains a field that cannot be copied: for example, a type part of the sync package (see <a href=\"#copying-a-sync-type--74-\">#74, “Copying a sync type”</a>).</li>\n</ul>\n<p>A receiver <em>should</em> be a pointer</p>\n<ul>\n<li>If the receiver is a large object. Using a pointer can make the call more efficient, as doing so prevents making an extensive copy. When in doubt about how large is large, benchmarking can be the solution; it’s pretty much impossible to state a specific size, because it depends on many factors.</li>\n</ul>\n<p>A receiver <em>must</em> be a value</p>\n<ul>\n<li>If we have to enforce a receiver’s immutability.</li>\n<li>If the receiver is a map, function, or channel. Otherwise, a compilation error\n  occurs.</li>\n</ul>\n<p>A receiver <em>should</em> be a value</p>\n<ul>\n<li>If the receiver is a slice that doesn’t have to be mutated.</li>\n<li>If the receiver is a small array or struct that is naturally a value type without mutable fields, such as <code>time.Time</code>.</li>\n<li>If the receiver is a basic type such as <code>int</code>, <code>float64</code>, or <code>string</code>.</li>\n</ul>\n<p>Of course, it’s impossible to be exhaustive, as there will always be edge cases, but this section’s goal was to provide guidance to cover most cases. By default, we can choose to go with a value receiver unless there’s a good reason not to do so. In doubt, we should use a pointer receiver.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/42-receiver/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nunca-usando-parametros-de-resultado-nomeados-43\">Nunca usando parâmetros de resultado nomeados (#43)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Usar parâmetros de resultado nomeados pode ser uma maneira eficiente de melhorar a legibilidade de uma função/método, especialmente se vários parâmetros de resultado tiverem o mesmo tipo. Em alguns casos, esta abordagem também pode ser conveniente porque os parâmetros de resultado nomeados são inicializados com seu valor zero. Mas tenha cuidado com os possíveis efeitos colaterais.</p>\n</details>\n<p>When we return parameters in a function or a method, we can attach names to these parameters and use them as regular variables. When a result parameter is named, it’s initialized to its zero value when the function/method begins. With named result parameters, we can also call a naked return statement (without arguments). In that case, the current values of the result parameters are used as the returned values.</p>\n<p>Here’s an example that uses a named result parameter <code>b</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-25-1\"><a id=\"__codelineno-25-1\" name=\"__codelineno-25-1\" href=\"#__codelineno-25-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">(</span><span class=\"nx\">a</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-25-2\"><a id=\"__codelineno-25-2\" name=\"__codelineno-25-2\" href=\"#__codelineno-25-2\"></a><span class=\"w\">    </span><span class=\"nx\">b</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">a</span>\n</span><span id=\"__span-25-3\"><a id=\"__codelineno-25-3\" name=\"__codelineno-25-3\" href=\"#__codelineno-25-3\"></a><span class=\"w\">    </span><span class=\"k\">return</span>\n</span><span id=\"__span-25-4\"><a id=\"__codelineno-25-4\" name=\"__codelineno-25-4\" href=\"#__codelineno-25-4\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>In this example, we attach a name to the result parameter: <code>b</code>. When we call return without arguments, it returns the current value of <code>b</code>.</p>\n<p>In some cases, named result parameters can also increase readability: for example, if two parameters have the same type. In other cases, they can also be used for convenience. Therefore, we should use named result parameters sparingly when there’s a clear benefit.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/43-named-result-parameters/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"efeitos-colaterais-nao-intencionais-com-parametros-de-resultado-nomeados-44\">Efeitos colaterais não intencionais com parâmetros de resultado nomeados (#44)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Consulte <a href=\"#never-using-named-result-parameters-43\">#43</a>.</p>\n</details>\n<p>We mentioned why named result parameters can be useful in some situations. But as these result parameters are initialized to their zero value, using them can sometimes lead to subtle bugs if we’re not careful enough. For example, can you spot what’s wrong with this code?</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-26-1\"><a id=\"__codelineno-26-1\" name=\"__codelineno-26-1\" href=\"#__codelineno-26-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">l</span><span class=\"w\"> </span><span class=\"nx\">loc</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">getCoordinates</span><span class=\"p\">(</span><span class=\"nx\">ctx</span><span class=\"w\"> </span><span class=\"nx\">context</span><span class=\"p\">.</span><span class=\"nx\">Context</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">address</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span>\n</span><span id=\"__span-26-2\"><a id=\"__codelineno-26-2\" name=\"__codelineno-26-2\" href=\"#__codelineno-26-2\"></a><span class=\"w\">    </span><span class=\"nx\">lat</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">lng</span><span class=\"w\"> </span><span class=\"kt\">float32</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-26-3\"><a id=\"__codelineno-26-3\" name=\"__codelineno-26-3\" href=\"#__codelineno-26-3\"></a><span class=\"w\">    </span><span class=\"nx\">isValid</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">l</span><span class=\"p\">.</span><span class=\"nx\">validateAddress</span><span class=\"p\">(</span><span class=\"nx\">address</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-26-4\"><a id=\"__codelineno-26-4\" name=\"__codelineno-26-4\" href=\"#__codelineno-26-4\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"p\">!</span><span class=\"nx\">isValid</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-26-5\"><a id=\"__codelineno-26-5\" name=\"__codelineno-26-5\" href=\"#__codelineno-26-5\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">errors</span><span class=\"p\">.</span><span class=\"nx\">New</span><span class=\"p\">(</span><span class=\"s\">\"invalid address\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-26-6\"><a id=\"__codelineno-26-6\" name=\"__codelineno-26-6\" href=\"#__codelineno-26-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-26-7\"><a id=\"__codelineno-26-7\" name=\"__codelineno-26-7\" href=\"#__codelineno-26-7\"></a>\n</span><span id=\"__span-26-8\"><a id=\"__codelineno-26-8\" name=\"__codelineno-26-8\" href=\"#__codelineno-26-8\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">ctx</span><span class=\"p\">.</span><span class=\"nx\">Err</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n</span><span id=\"__span-26-9\"><a id=\"__codelineno-26-9\" name=\"__codelineno-26-9\" href=\"#__codelineno-26-9\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-26-10\"><a id=\"__codelineno-26-10\" name=\"__codelineno-26-10\" href=\"#__codelineno-26-10\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-26-11\"><a id=\"__codelineno-26-11\" name=\"__codelineno-26-11\" href=\"#__codelineno-26-11\"></a>\n</span><span id=\"__span-26-12\"><a id=\"__codelineno-26-12\" name=\"__codelineno-26-12\" href=\"#__codelineno-26-12\"></a><span class=\"w\">    </span><span class=\"c1\">// Get and return coordinates</span>\n</span><span id=\"__span-26-13\"><a id=\"__codelineno-26-13\" name=\"__codelineno-26-13\" href=\"#__codelineno-26-13\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>The error might not be obvious at first glance. Here, the error returned in the <code>if ctx.Err() != nil</code> scope is <code>err</code>. But we haven’t assigned any value to the <code>err</code> variable. It’s still assigned to the zero value of an <code>error</code> type: <code>nil</code>. Hence, this code will always return a nil error.</p>\n<p>When using named result parameters, we must recall that each parameter is initialized to its zero value. As we have seen in this section, this can lead to subtle bugs that aren’t always straightforward to spot while reading code. Therefore, let’s remain cautious when using named result parameters, to avoid potential side effects.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/44-side-effects-named-result-parameters/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"retornando-um-receptor-nulo-45\">Retornando um receptor nulo (#45)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Ao retornar uma interface, tenha cuidado para não retornar um ponteiro nulo, mas um valor nulo explícito. Caso contrário, poderão ocorrer consequências não intencionais e o chamador receberá um valor diferente de zero.</p>\n</details>\n<!-- TODO -->\n\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/45-nil-receiver/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"usando-um-nome-de-arquivo-como-entrada-de-funcao-46\">Usando um nome de arquivo como entrada de função (#46)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Projetar funções para receber tipos <code>io.Reader</code> em vez de nomes de arquivos melhora a capacidade de reutilização de uma função e facilita o teste.</p>\n</details>\n<p>Accepting a filename as a function input to read from a file should, in most cases, be considered a code smell (except in specific functions such as <code>os.Open</code>). Indeed, it makes unit tests more complex because we may have to create multiple files. It also reduces the reusability of a function (although not all functions are meant to be reused). Using the <code>io.Reader</code> interface abstracts the data source. Regardless of whether the input is a file, a string, an HTTP request, or a gRPC request, the implementation can be reused and easily tested.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/46-function-input/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"ignorando-como-argumentos-defer-e-receptores-sao-avaliados-avaliacao-de-argumentos-ponteiros-e-receptores-de-valor-47\">Ignorando como argumentos <code>defer</code> e receptores são avaliados (avaliação de argumentos, ponteiros e receptores de valor) (#47)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Passar um ponteiro para uma função <code>defer</code> e agrupar uma chamada dentro de um closure são duas soluções possíveis para superar a avaliação imediata de argumentos e receptores.</p>\n</details>\n<p>In a <code>defer</code> function the arguments are evaluated right away, not once the surrounding function returns. For example, in this code, we always call <code>notify</code> and <code>incrementCounter</code> with the same status: an empty string.</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-27-1\"><a id=\"__codelineno-27-1\" name=\"__codelineno-27-1\" href=\"#__codelineno-27-1\"></a><span class=\"kd\">const</span><span class=\"w\"> </span><span class=\"p\">(</span>\n</span><span id=\"__span-27-2\"><a id=\"__codelineno-27-2\" name=\"__codelineno-27-2\" href=\"#__codelineno-27-2\"></a><span class=\"w\">    </span><span class=\"nx\">StatusSuccess</span><span class=\"w\">  </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"s\">\"success\"</span>\n</span><span id=\"__span-27-3\"><a id=\"__codelineno-27-3\" name=\"__codelineno-27-3\" href=\"#__codelineno-27-3\"></a><span class=\"w\">    </span><span class=\"nx\">StatusErrorFoo</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"s\">\"error_foo\"</span>\n</span><span id=\"__span-27-4\"><a id=\"__codelineno-27-4\" name=\"__codelineno-27-4\" href=\"#__codelineno-27-4\"></a><span class=\"w\">    </span><span class=\"nx\">StatusErrorBar</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"s\">\"error_bar\"</span>\n</span><span id=\"__span-27-5\"><a id=\"__codelineno-27-5\" name=\"__codelineno-27-5\" href=\"#__codelineno-27-5\"></a><span class=\"p\">)</span>\n</span><span id=\"__span-27-6\"><a id=\"__codelineno-27-6\" name=\"__codelineno-27-6\" href=\"#__codelineno-27-6\"></a>\n</span><span id=\"__span-27-7\"><a id=\"__codelineno-27-7\" name=\"__codelineno-27-7\" href=\"#__codelineno-27-7\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-27-8\"><a id=\"__codelineno-27-8\" name=\"__codelineno-27-8\" href=\"#__codelineno-27-8\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"kt\">string</span>\n</span><span id=\"__span-27-9\"><a id=\"__codelineno-27-9\" name=\"__codelineno-27-9\" href=\"#__codelineno-27-9\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">notify</span><span class=\"p\">(</span><span class=\"nx\">status</span><span class=\"p\">)</span>\n</span><span id=\"__span-27-10\"><a id=\"__codelineno-27-10\" name=\"__codelineno-27-10\" href=\"#__codelineno-27-10\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">incrementCounter</span><span class=\"p\">(</span><span class=\"nx\">status</span><span class=\"p\">)</span>\n</span><span id=\"__span-27-11\"><a id=\"__codelineno-27-11\" name=\"__codelineno-27-11\" href=\"#__codelineno-27-11\"></a>\n</span><span id=\"__span-27-12\"><a id=\"__codelineno-27-12\" name=\"__codelineno-27-12\" href=\"#__codelineno-27-12\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">foo</span><span class=\"p\">();</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-27-13\"><a id=\"__codelineno-27-13\" name=\"__codelineno-27-13\" href=\"#__codelineno-27-13\"></a><span class=\"w\">        </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">StatusErrorFoo</span>\n</span><span id=\"__span-27-14\"><a id=\"__codelineno-27-14\" name=\"__codelineno-27-14\" href=\"#__codelineno-27-14\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-27-15\"><a id=\"__codelineno-27-15\" name=\"__codelineno-27-15\" href=\"#__codelineno-27-15\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-27-16\"><a id=\"__codelineno-27-16\" name=\"__codelineno-27-16\" href=\"#__codelineno-27-16\"></a>\n</span><span id=\"__span-27-17\"><a id=\"__codelineno-27-17\" name=\"__codelineno-27-17\" href=\"#__codelineno-27-17\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">bar</span><span class=\"p\">();</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-27-18\"><a id=\"__codelineno-27-18\" name=\"__codelineno-27-18\" href=\"#__codelineno-27-18\"></a><span class=\"w\">        </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">StatusErrorBar</span>\n</span><span id=\"__span-27-19\"><a id=\"__codelineno-27-19\" name=\"__codelineno-27-19\" href=\"#__codelineno-27-19\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">err</span>\n</span><span id=\"__span-27-20\"><a id=\"__codelineno-27-20\" name=\"__codelineno-27-20\" href=\"#__codelineno-27-20\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-27-21\"><a id=\"__codelineno-27-21\" name=\"__codelineno-27-21\" href=\"#__codelineno-27-21\"></a>\n</span><span id=\"__span-27-22\"><a id=\"__codelineno-27-22\" name=\"__codelineno-27-22\" href=\"#__codelineno-27-22\"></a><span class=\"w\">    </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">StatusSuccess</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"mi\">5</span><span class=\"p\">&gt;</span>\n</span><span id=\"__span-27-23\"><a id=\"__codelineno-27-23\" name=\"__codelineno-27-23\" href=\"#__codelineno-27-23\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-27-24\"><a id=\"__codelineno-27-24\" name=\"__codelineno-27-24\" href=\"#__codelineno-27-24\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Indeed, we call <code>notify(status)</code> and <code>incrementCounter(status)</code> as <code>defer</code> functions. Therefore, Go will delay these calls to be executed once <code>f</code> returns with the current value of status at the stage we used defer, hence passing an empty string.</p>\n<p>Two leading options if we want to keep using <code>defer</code>.</p>\n<p>The first solution is to pass a string pointer:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-28-1\"><a id=\"__codelineno-28-1\" name=\"__codelineno-28-1\" href=\"#__codelineno-28-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-28-2\"><a id=\"__codelineno-28-2\" name=\"__codelineno-28-2\" href=\"#__codelineno-28-2\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"kt\">string</span>\n</span><span id=\"__span-28-3\"><a id=\"__codelineno-28-3\" name=\"__codelineno-28-3\" href=\"#__codelineno-28-3\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">notify</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">status</span><span class=\"p\">)</span><span class=\"w\"> </span>\n</span></span><span id=\"__span-28-4\"><a id=\"__codelineno-28-4\" name=\"__codelineno-28-4\" href=\"#__codelineno-28-4\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">incrementCounter</span><span class=\"p\">(</span><span class=\"o\">&amp;</span><span class=\"nx\">status</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-28-5\"><a id=\"__codelineno-28-5\" name=\"__codelineno-28-5\" href=\"#__codelineno-28-5\"></a>\n</span><span id=\"__span-28-6\"><a id=\"__codelineno-28-6\" name=\"__codelineno-28-6\" href=\"#__codelineno-28-6\"></a><span class=\"w\">    </span><span class=\"c1\">// The rest of the function unchanged</span>\n</span><span id=\"__span-28-7\"><a id=\"__codelineno-28-7\" name=\"__codelineno-28-7\" href=\"#__codelineno-28-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Using <code>defer</code> evaluates the arguments right away: here, the address of status. Yes, status itself is modified throughout the function, but its address remains constant, regardless of the assignments. Hence, if <code>notify</code> or <code>incrementCounter</code> uses the value referenced by the string pointer, it will work as expected. But this solution requires changing the signature of the two functions, which may not always be possible.</p>\n<p>There’s another solution: calling a closure (an anonymous function value that references variables from outside its body) as a <code>defer</code> statement:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-29-1\"><a id=\"__codelineno-29-1\" name=\"__codelineno-29-1\" href=\"#__codelineno-29-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-29-2\"><a id=\"__codelineno-29-2\" name=\"__codelineno-29-2\" href=\"#__codelineno-29-2\"></a><span class=\"w\">    </span><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">status</span><span class=\"w\"> </span><span class=\"kt\">string</span>\n</span><span id=\"__span-29-3\"><a id=\"__codelineno-29-3\" name=\"__codelineno-29-3\" href=\"#__codelineno-29-3\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span></span><span id=\"__span-29-4\"><a id=\"__codelineno-29-4\" name=\"__codelineno-29-4\" href=\"#__codelineno-29-4\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"nx\">notify</span><span class=\"p\">(</span><span class=\"nx\">status</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-29-5\"><a id=\"__codelineno-29-5\" name=\"__codelineno-29-5\" href=\"#__codelineno-29-5\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"nx\">incrementCounter</span><span class=\"p\">(</span><span class=\"nx\">status</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-29-6\"><a id=\"__codelineno-29-6\" name=\"__codelineno-29-6\" href=\"#__codelineno-29-6\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span></span><span id=\"__span-29-7\"><a id=\"__codelineno-29-7\" name=\"__codelineno-29-7\" href=\"#__codelineno-29-7\"></a>\n</span><span id=\"__span-29-8\"><a id=\"__codelineno-29-8\" name=\"__codelineno-29-8\" href=\"#__codelineno-29-8\"></a><span class=\"w\">    </span><span class=\"c1\">// The rest of the function unchanged</span>\n</span><span id=\"__span-29-9\"><a id=\"__codelineno-29-9\" name=\"__codelineno-29-9\" href=\"#__codelineno-29-9\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Here, we wrap the calls to both <code>notify</code> and <code>incrementCounter</code> within a closure. This closure references the status variable from outside its body. Therefore, <code>status</code> is evaluated once the closure is executed, not when we call <code>defer</code>. This solution also works and doesn’t require <code>notify</code> and <code>incrementCounter</code> to change their signature.</p>\n<p>Let's also note this behavior applies with method receiver: the receiver is evaluated immediately.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/06-functions-methods/47-defer-evaluation/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h2 id=\"error-management\">Error Management</h2>\n<h3 id=\"panico-48\">Pânico (#48)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Usar <code>panic</code> é uma opção para lidar com erros no Go. No entanto, só deve ser usado com moderação em condições irrecuperáveis: por exemplo, para sinalizar um erro do programador ou quando você não consegue carregar uma dependência obrigatória.</p>\n</details>\n<p>In Go, panic is a built-in function that stops the ordinary flow:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-30-1\"><a id=\"__codelineno-30-1\" name=\"__codelineno-30-1\" href=\"#__codelineno-30-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-30-2\"><a id=\"__codelineno-30-2\" name=\"__codelineno-30-2\" href=\"#__codelineno-30-2\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"s\">\"a\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-30-3\"><a id=\"__codelineno-30-3\" name=\"__codelineno-30-3\" href=\"#__codelineno-30-3\"></a><span class=\"w\">    </span><span class=\"nb\">panic</span><span class=\"p\">(</span><span class=\"s\">\"foo\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-30-4\"><a id=\"__codelineno-30-4\" name=\"__codelineno-30-4\" href=\"#__codelineno-30-4\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"s\">\"b\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-30-5\"><a id=\"__codelineno-30-5\" name=\"__codelineno-30-5\" href=\"#__codelineno-30-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>This code prints a and then stops before printing b:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-31-1\"><a id=\"__codelineno-31-1\" name=\"__codelineno-31-1\" href=\"#__codelineno-31-1\"></a>a\n</span><span id=\"__span-31-2\"><a id=\"__codelineno-31-2\" name=\"__codelineno-31-2\" href=\"#__codelineno-31-2\"></a>panic: foo\n</span><span id=\"__span-31-3\"><a id=\"__codelineno-31-3\" name=\"__codelineno-31-3\" href=\"#__codelineno-31-3\"></a>\n</span><span id=\"__span-31-4\"><a id=\"__codelineno-31-4\" name=\"__codelineno-31-4\" href=\"#__codelineno-31-4\"></a>goroutine 1 [running]:\n</span><span id=\"__span-31-5\"><a id=\"__codelineno-31-5\" name=\"__codelineno-31-5\" href=\"#__codelineno-31-5\"></a>main.main()\n</span><span id=\"__span-31-6\"><a id=\"__codelineno-31-6\" name=\"__codelineno-31-6\" href=\"#__codelineno-31-6\"></a>        main.go:7 +0xb3\n</span></code></pre></div>\n<p>Panicking in Go should be used sparingly. There are two prominent cases, one to signal a programmer error (e.g., <a href=\"https://cs.opensource.google/go/go/+/refs/tags/go1.20.7:src/database/sql/sql.go;l=44\"><code>sql.Register</code></a> that panics if the driver is <code>nil</code> or has already been register) and another where our application fails to create a mandatory dependency. Hence, exceptional conditions that lead us to stop the application. In most other cases, error management should be done with a function that returns a proper error type as the last return argument.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/48-panic/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"ignorando-quando-embrulhar-um-erro-49\">Ignorando quando embrulhar um erro (#49)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Embrulhar um erro permite marcar um erro e/ou fornecer contexto adicional. No entanto, o agrupamento de erros cria um acoplamento potencial, pois disponibiliza o erro de origem para o chamador. Se você quiser evitar isso, não use a agrupamento automático de erros.</p>\n</details>\n<p>Since Go 1.13, the %w directive allows us to wrap errors conveniently. Error wrapping is about wrapping or packing an error inside a wrapper container that also makes the source error available. In general, the two main use cases for error wrapping are the following:</p>\n<ul>\n<li>Adding additional context to an error</li>\n<li>Marking an error as a specific error</li>\n</ul>\n<p>When handling an error, we can decide to wrap it. Wrapping is about adding additional context to an error and/or marking an error as a specific type. If we need to mark an error, we should create a custom error type. However, if we just want to add extra context, we should use fmt.Errorf with the %w directive as it doesn’t require creating a new error type. Yet, error wrapping creates potential coupling as it makes the source error available for the caller. If we want to prevent it, we shouldn’t use error wrapping but error transformation, for example, using fmt.Errorf with the %v directive.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/49-error-wrapping/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"comparando-um-tipo-de-erro-de-forma-imprecisa-50\">Comparando um tipo de erro de forma imprecisa (#50)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Se você usar o agrupamento de erros do Go 1.13 com a diretiva <code>%w</code> e <code>fmt.Errorf</code>, a comparação de um erro com um tipo deverá ser feita usando <code>errors.As</code>. Caso contrário, se o erro retornado que você deseja verificar for embrulhado, as verificações falharão.</p>\n</details>\n<!-- TODO -->\n\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/50-compare-error-type/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"comparando-um-valor-de-erro-incorretamente-51\">Comparando um valor de erro incorretamente (#51)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Se você usar o agrupamento de erros do Go 1.13 com a diretiva <code>%w</code> e <code>fmt.Errorf</code>, a comparação de um erro ou de um valor deverá ser feita usando <code>errors.As</code>. Caso contrário, se o erro retornado que você deseja verificar for embrulhado, as verificações falharão.</p>\n</details>\n<p>A sentinel error is an error defined as a global variable:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-32-1\"><a id=\"__codelineno-32-1\" name=\"__codelineno-32-1\" href=\"#__codelineno-32-1\"></a><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"s\">\"errors\"</span>\n</span><span id=\"__span-32-2\"><a id=\"__codelineno-32-2\" name=\"__codelineno-32-2\" href=\"#__codelineno-32-2\"></a>\n</span><span id=\"__span-32-3\"><a id=\"__codelineno-32-3\" name=\"__codelineno-32-3\" href=\"#__codelineno-32-3\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">ErrFoo</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">errors</span><span class=\"p\">.</span><span class=\"nx\">New</span><span class=\"p\">(</span><span class=\"s\">\"foo\"</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>In general, the convention is to start with <code>Err</code> followed by the error type: here, <code>ErrFoo</code>. A sentinel error conveys an <em>expected</em> error, an error that clients will expect to check. As general guidelines:</p>\n<ul>\n<li>Expected errors should be designed as error values (sentinel errors): <code>var ErrFoo = errors.New(\"foo\")</code>.</li>\n<li>Unexpected errors should be designed as error types: <code>type BarError struct { ... }</code>, with <code>BarError</code> implementing the <code>error</code> interface.</li>\n</ul>\n<p>If we use error wrapping in our application with the <code>%w</code> directive and <code>fmt.Errorf</code>, checking an error against a specific value should be done using <code>errors.Is</code> instead of <code>==</code>. Thus, even if the sentinel error is wrapped, <code>errors.Is</code> can recursively unwrap it and compare each error in the chain against the provided value.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/51-comparing-error-value/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"lidando-com-um-erro-duas-vezes-52\">Lidando com um erro duas vezes (#52)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Na maioria das situações, um erro deve ser tratado apenas uma vez. Registrar um erro é tratar um erro. Portanto, você deve escolher entre registrar ou retornar um erro. Em muitos casos, o embrulho automático de erros é a solução, pois permite fornecer contexto adicional a um erro e retornar o erro de origem.</p>\n</details>\n<p>Handling an error multiple times is a mistake made frequently by developers, not specifically in Go. This can cause situations where the same error is logged multiple times make debugging harder.</p>\n<p>Let's remind us that handling an error should be done only once. Logging an error is handling an error. Hence, we should either log or return an error. By doing this, we simplify our code and gain better insights into the error situation. Using error wrapping is the most convenient approach as it allows us to propagate the source error and add context to an error.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/52-handling-error-twice/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-tratando-de-um-erro-53\">Não tratando de um erro (#53)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Ignorar um erro, seja durante uma chamada de função ou em uma função <code>defer</code>, deve ser feito explicitamente usando o identificador em branco. Caso contrário, os futuros leitores poderão ficar confusos sobre se foi intencional ou um erro.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/53-not-handling-error/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-tratando-erros-de-defer-54\">Não tratando erros de <code>defer</code> (#54)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Em muitos casos, você não deve ignorar um erro retornado por uma função <code>defer</code>. Manipule-o diretamente ou propague-o para o chamador, dependendo do contexto. Se você quiser ignorá-lo, use o identificador em branco.</p>\n</details>\n<p>Consider the following code:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-33-1\"><a id=\"__codelineno-33-1\" name=\"__codelineno-33-1\" href=\"#__codelineno-33-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">f</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-33-2\"><a id=\"__codelineno-33-2\" name=\"__codelineno-33-2\" href=\"#__codelineno-33-2\"></a><span class=\"w\">  </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-33-3\"><a id=\"__codelineno-33-3\" name=\"__codelineno-33-3\" href=\"#__codelineno-33-3\"></a><span class=\"w\">  </span><span class=\"nx\">notify</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// Error handling is omitted</span>\n</span><span id=\"__span-33-4\"><a id=\"__codelineno-33-4\" name=\"__codelineno-33-4\" href=\"#__codelineno-33-4\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-33-5\"><a id=\"__codelineno-33-5\" name=\"__codelineno-33-5\" href=\"#__codelineno-33-5\"></a>\n</span><span id=\"__span-33-6\"><a id=\"__codelineno-33-6\" name=\"__codelineno-33-6\" href=\"#__codelineno-33-6\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">notify</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-33-7\"><a id=\"__codelineno-33-7\" name=\"__codelineno-33-7\" href=\"#__codelineno-33-7\"></a><span class=\"w\">  </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-33-8\"><a id=\"__codelineno-33-8\" name=\"__codelineno-33-8\" href=\"#__codelineno-33-8\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>From a maintainability perspective, the code can lead to some issues. Let’s consider a new reader looking at it. This reader notices that notify returns an error but that the error isn’t handled by the parent function. How can they guess whether or not handling the error was intentional? How can they know whether the previous developer forgot to handle it or did it purposely?</p>\n<p>For these reasons, when we want to ignore an error, there's only one way to do it, using the blank identifier (<code>_</code>):</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-34-1\"><a id=\"__codelineno-34-1\" name=\"__codelineno-34-1\" href=\"#__codelineno-34-1\"></a><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">notify</span>\n</span></code></pre></div>\n<p>In terms of compilation and run time, this approach doesn’t change anything compared to the first piece of code. But this new version makes explicit that we aren’t interested in the error. Also, we can add a comment that indicates the rationale for why an error is ignored:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-35-1\"><a id=\"__codelineno-35-1\" name=\"__codelineno-35-1\" href=\"#__codelineno-35-1\"></a><span class=\"c1\">// At-most once delivery.</span>\n</span><span id=\"__span-35-2\"><a id=\"__codelineno-35-2\" name=\"__codelineno-35-2\" href=\"#__codelineno-35-2\"></a><span class=\"c1\">// Hence, it's accepted to miss some of them in case of errors.</span>\n</span><span id=\"__span-35-3\"><a id=\"__codelineno-35-3\" name=\"__codelineno-35-3\" href=\"#__codelineno-35-3\"></a><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">notify</span><span class=\"p\">()</span>\n</span></code></pre></div>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/07-error-management/54-defer-errors/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h2 id=\"concurrency-foundations\">Concurrency: Foundations</h2>\n<h3 id=\"misturando-simultaneidade-e-paralelismo-55\">Misturando simultaneidade e paralelismo (#55)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Compreender as diferenças fundamentais entre simultaneidade e paralelismo é a base do conhecimento do desenvolvedor Go. A simultaneidade tem a ver com estrutura, enquanto o paralelismo tem a ver com execução.</p>\n</details>\n<p>Concurrency and parallelism are not the same:</p>\n<ul>\n<li>Concurrency is about structure. We can change a sequential implementation into a concurrent one by introducing different steps that separate concurrent goroutines can tackle.</li>\n<li>Meanwhile, parallelism is about execution. We can use parallism at the steps level by adding more parallel goroutines.</li>\n</ul>\n<p>In summary, concurrency provides a structure to solve a problem with parts that may be parallelized. Therefore, <em>concurrency enables parallelism</em>.</p>\n<!-- TODO Include Rob Pike's talk link-->\n\n<h3 id=\"pensar-que-a-simultaneidade-e-sempre-mais-rapida-56\">Pensar que a simultaneidade é sempre mais rápida (#56)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Para ser um desenvolvedor proficiente, você deve reconhecer que a simultaneidade nem sempre é mais rápida. As soluções que envolvem a paralelização de cargas de trabalho mínimas podem não ser necessariamente mais rápidas do que uma implementação sequencial. A avaliação comparativa de soluções sequenciais versus soluções simultâneas deve ser a forma de validar suposições.</p>\n</details>\n<p>Read the full section <a href=\"../56-concurrency-faster/\">here</a>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/56-faster/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"ficar-confuso-sobre-quando-usar-canais-ou-mutexes-57\">Ficar confuso sobre quando usar canais ou mutexes (#57)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Estar ciente das interações goroutine também pode ser útil ao decidir entre canais e mutexes. Em geral, goroutines paralelas requerem sincronização e, portanto, mutexes. Por outro lado, goroutines simultâneas geralmente requerem coordenação e orquestração e, portanto, canais.</p>\n</details>\n<p>Given a concurrency problem, it may not always be clear whether we can implement a\nsolution using channels or mutexes. Because Go promotes sharing memory by communication, one mistake could be to always force the use of channels, regardless of\nthe use case. However, we should see the two options as complementary. </p>\n<p>When should we use channels or mutexes? We will use the example in the next figure as a backbone. Our example has three different goroutines with specific relationships:</p>\n<ul>\n<li>G1 and G2 are parallel goroutines. They may be two goroutines executing the same function that keeps receiving messages from a channel, or perhaps two goroutines executing the same HTTP handler at the same time.</li>\n<li>On the other hand, G1 and G3 are concurrent goroutines, as are G2 and G3. All the goroutines are part of an overall concurrent structure, but G1 and G2 perform the first step, whereas G3 does the next step.</li>\n</ul>\n<!-- TODO Include figure-->\n\n<p>In general, parallel goroutines have to <em>synchronize</em>: for example, when they need to access or mutate a shared resource such as a slice. Synchronization is enforced with mutexes but not with any channel types (not with buffered channels). Hence, in general, synchronization between parallel goroutines should be achieved via mutexes.</p>\n<p>Conversely, in general, concurrent goroutines have to <em>coordinate and orchestrate</em>. For example, if G3 needs to aggregate results from both G1 and G2, G1 and G2 need to signal to G3 that a new intermediate result is available. This coordination falls under the scope of communication—therefore, channels.</p>\n<p>Regarding concurrent goroutines, there’s also the case where we want to transfer the ownership of a resource from one step (G1 and G2) to another (G3); for example, if G1 and G2 are enriching a shared resource and at some point, we consider this job as complete. Here, we should use channels to signal that a specific resource is ready and handle the ownership transfer.</p>\n<p>Mutexes and channels have different semantics. Whenever we want to share a state or access a shared resource, mutexes ensure exclusive access to this resource. Conversely, channels are a mechanic for signaling with or without data (<code>chan struct{}</code> or not). Coordination or ownership transfer should be achieved via channels. It’s important to know whether goroutines are parallel or concurrent because, in general, we need mutexes for parallel goroutines and channels for concurrent ones.</p>\n<h3 id=\"nao-entender-os-problemas-de-corrida-corridas-de-dados-vs-condicoes-de-corrida-e-o-modelo-de-memoria-go-58\">Não entender os problemas de corrida (corridas de dados vs. condições de corrida e o modelo de memória Go) (#58)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Ser proficiente em simultaneidade também significa compreender que corridas de dados e condições de corrida são conceitos diferentes. As corridas de dados ocorrem quando várias goroutines acessam simultaneamente o mesmo local de memória e pelo menos uma delas está gravando. Enquanto isso, estar livre de disputa de dados não significa necessariamente execução determinística. Quando um comportamento depende da sequência ou do tempo de eventos que não podem ser controlados, esta é uma condição de corrida.</p>\n</details>\n<p>Race problems can be among the hardest and most insidious bugs a programmer can face. As Go developers, we must understand crucial aspects such as data races and race conditions, their possible impacts, and how to avoid them.</p>\n<h4 id=\"data-race\">Data Race</h4>\n<p>A data race occurs when two or more goroutines simultaneously access the same memory location and at least one is writing. In this case, the result can be hazardous. Even worse, in some situations, the memory location may end up holding a value containing a meaningless combination of bits.</p>\n<p>We can prevent a data race from happening using different techniques. For example: </p>\n<ul>\n<li>Using the <code>sync/atomic</code> package</li>\n<li>In synchronizing the two goroutines with an ad hoc data structure like a mutex</li>\n<li>Using channels to make the two goroutines communicating to ensure that a variable is updated by only one goroutine at a time</li>\n</ul>\n<h4 id=\"race-condition\">Race Condition</h4>\n<p>Depending on the operation we want to perform, does a data-race-free application necessarily mean a deterministic result? Not necessarily.</p>\n<p>A race condition occurs when the behavior depends on the sequence or the timing of events that can’t be controlled. Here, the timing of events is the goroutines’ execution order.</p>\n<p>In summary, when we work in concurrent applications, it’s essential to understand that a data race is different from a race condition. A data race occurs when multiple goroutines simultaneously access the same memory location and at least one of them is writing. A data race means unexpected behavior. However, a data-race-free application doesn’t necessarily mean deterministic results. An application can be free of data races but still have behavior that depends on uncontrolled events (such as goroutine execution, how fast a message is published to a channel, or how long a call to a database lasts); this is a race condition. Understanding both concepts is crucial to becoming proficient in designing concurrent applications.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/58-races/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-compreender-os-impactos-de-simultaneidade-de-um-tipo-de-carga-de-trabalho-59\">Não compreender os impactos de simultaneidade de um tipo de carga de trabalho (#59)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Ao criar um determinado número de goroutines, considere o tipo de carga de trabalho. Criar goroutines vinculadas à CPU significa limitar esse número próximo à variável <abbr title=\"The variable defines the limit of OS threads in charge of executing user-level code simultaneously\">GOMAXPROCS</abbr> (baseado por padrão no número de núcleos de CPU no host). A criação de goroutines vinculadas a E/S depende de outros fatores, como o sistema externo.</p>\n</details>\n<p>In programming, the execution time of a workload is limited by one of the following:</p>\n<ul>\n<li>The speed of the CPU—For example, running a merge sort algorithm. The workload is called CPU-bound.</li>\n<li>The speed of I/O—For example, making a REST call or a database query. The workload is called I/O-bound.</li>\n<li>The amount of available memory—The workload is called memory-bound.</li>\n</ul>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>The last is the rarest nowadays, given that memory has become very cheap in recent decades. Hence, this section focuses on the two first workload types: CPU- and I/O-bound.</p>\n</details>\n<p>If the workload executed by the workers is I/O-bound, the value mainly depends on the external system. Conversely, if the workload is CPU-bound, the optimal number of goroutines is close to the number of available CPU cores (a best practice can be to use <code>runtime.GOMAXPROCS</code>). Knowing the workload type (I/O or CPU) is crucial when designing concurrent applications.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/59-workload-type/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"incompreensao-dos-contextos-go-60\">Incompreensão dos contextos Go (#60)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Os contextos Go também são um dos pilares da simultaneidade em Go. Um contexto permite que você carregue um prazo, um sinal de cancelamento e/ou uma lista de valores-chave.</p>\n</details>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">https://pkg.go.dev/context</p>\n<p>A Context carries a deadline, a cancellation signal, and other values across API boundaries.</p>\n</div>\n<h4 id=\"deadline\">Deadline</h4>\n<p>A deadline refers to a specific point in time determined with one of the following:</p>\n<ul>\n<li>A <code>time.Duration</code> from now (for example, in 250 ms)</li>\n<li>A <code>time.Time</code> (for example, 2023-02-07 00:00:00 UTC)</li>\n</ul>\n<p>The semantics of a deadline convey that an ongoing activity should be stopped if this deadline is met. An activity is, for example, an I/O request or a goroutine waiting to receive a message from a channel.</p>\n<h4 id=\"cancellation-signals\">Cancellation signals</h4>\n<p>Another use case for Go contexts is to carry a cancellation signal. Let’s imagine that we want to create an application that calls <code>CreateFileWatcher(ctx context.Context, filename string)</code> within another goroutine. This function creates a specific file watcher that keeps reading from a file and catches updates. When the provided context expires or is canceled, this function handles it to close the file descriptor.</p>\n<h4 id=\"context-values\">Context values</h4>\n<p>The last use case for Go contexts is to carry a key-value list. What’s the point of having a context carrying a key-value list? Because Go contexts are generic and mainstream, there are infinite use cases.</p>\n<p>For example, if we use tracing, we may want different subfunctions to share the same correlation ID. Some developers may consider this ID too invasive to be part of the function signature. In this regard, we could also decide to include it as part of the provided context.</p>\n<h4 id=\"catching-a-context-cancellation\">Catching a context cancellation</h4>\n<p>The <code>context.Context</code> type exports a <code>Done</code> method that returns a receive-only notification channel: <code>&lt;-chan struct{}</code>. This channel is closed when the work associated with the context should be canceled. For example,</p>\n<ul>\n<li>The Done channel related to a context created with <code>context.WithCancel</code> is closed when the cancel function is called.</li>\n<li>The Done channel related to a context created with <code>context.WithDeadline</code> is closed when the deadline has expired.</li>\n</ul>\n<p>One thing to note is that the internal channel should be closed when a context is canceled or has met a deadline, instead of when it receives a specific value, because the closure of a channel is the only channel action that all the consumer goroutines will receive. This way, all the consumers will be notified once a context is canceled or a deadline is reached.</p>\n<p>In summary, to be a proficient Go developer, we have to understand what a context is and how to use it. In general, a function that users wait for should take a context, as doing so allows upstream callers to decide when calling this function should be aborted. </p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/08-concurrency-foundations/60-contexts/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h2 id=\"concurrency-practice\">Concurrency: Practice</h2>\n<h3 id=\"propagando-um-contexto-improprio-61\">Propagando um contexto impróprio (#61)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Compreender as condições em que um contexto pode ser cancelado deve ser importante ao propagá-lo: por exemplo, um manipulador HTTP cancelando o contexto quando a resposta for enviada.</p>\n</details>\n<p>In many situations, it is recommended to propagate Go contexts. However, context propagation can sometimes lead to subtle bugs, preventing subfunctions from being correctly executed.</p>\n<p>Let’s consider the following example. We expose an HTTP handler that performs some tasks and returns a response. But just before returning the response, we also want to send it to a Kafka topic. We don’t want to penalize the HTTP consumer latency-wise, so we want the publish action to be handled asynchronously within a new goroutine. We assume that we have at our disposal a <code>publish</code> function that accepts a context so the action of publishing a message can be interrupted if the context is canceled, for example. Here is a possible implementation:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-36-1\"><a id=\"__codelineno-36-1\" name=\"__codelineno-36-1\" href=\"#__codelineno-36-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">handler</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">ResponseWriter</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Request</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-36-2\"><a id=\"__codelineno-36-2\" name=\"__codelineno-36-2\" href=\"#__codelineno-36-2\"></a><span class=\"w\">    </span><span class=\"nx\">response</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">doSomeTask</span><span class=\"p\">(</span><span class=\"nx\">r</span><span class=\"p\">.</span><span class=\"nx\">Context</span><span class=\"p\">(),</span><span class=\"w\"> </span><span class=\"nx\">r</span><span class=\"p\">)</span>\n</span><span id=\"__span-36-3\"><a id=\"__codelineno-36-3\" name=\"__codelineno-36-3\" href=\"#__codelineno-36-3\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-36-4\"><a id=\"__codelineno-36-4\" name=\"__codelineno-36-4\" href=\"#__codelineno-36-4\"></a><span class=\"w\">        </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Error</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">Error</span><span class=\"p\">(),</span><span class=\"w\"> </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">StatusInternalServerError</span><span class=\"p\">)</span>\n</span><span id=\"__span-36-5\"><a id=\"__codelineno-36-5\" name=\"__codelineno-36-5\" href=\"#__codelineno-36-5\"></a><span class=\"w\">    </span><span class=\"k\">return</span>\n</span><span id=\"__span-36-6\"><a id=\"__codelineno-36-6\" name=\"__codelineno-36-6\" href=\"#__codelineno-36-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-36-7\"><a id=\"__codelineno-36-7\" name=\"__codelineno-36-7\" href=\"#__codelineno-36-7\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-36-8\"><a id=\"__codelineno-36-8\" name=\"__codelineno-36-8\" href=\"#__codelineno-36-8\"></a><span class=\"w\">        </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">publish</span><span class=\"p\">(</span><span class=\"nx\">r</span><span class=\"p\">.</span><span class=\"nx\">Context</span><span class=\"p\">(),</span><span class=\"w\"> </span><span class=\"nx\">response</span><span class=\"p\">)</span>\n</span><span id=\"__span-36-9\"><a id=\"__codelineno-36-9\" name=\"__codelineno-36-9\" href=\"#__codelineno-36-9\"></a><span class=\"w\">        </span><span class=\"c1\">// Do something with err</span>\n</span><span id=\"__span-36-10\"><a id=\"__codelineno-36-10\" name=\"__codelineno-36-10\" href=\"#__codelineno-36-10\"></a><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span><span id=\"__span-36-11\"><a id=\"__codelineno-36-11\" name=\"__codelineno-36-11\" href=\"#__codelineno-36-11\"></a><span class=\"w\">    </span><span class=\"nx\">writeResponse</span><span class=\"p\">(</span><span class=\"nx\">response</span><span class=\"p\">)</span>\n</span><span id=\"__span-36-12\"><a id=\"__codelineno-36-12\" name=\"__codelineno-36-12\" href=\"#__codelineno-36-12\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>What’s wrong with this piece of code? We have to know that the context attached to an HTTP request can cancel in different conditions:</p>\n<ul>\n<li>When the client’s connection closes</li>\n<li>In the case of an HTTP/2 request, when the request is canceled</li>\n<li>When the response has been written back to the client</li>\n</ul>\n<p>In the first two cases, we probably handle things correctly. For example, if we get a response from doSomeTask but the client has closed the connection, it’s probably OK to call publish with a context already canceled so the message isn’t published. But what about the last case?</p>\n<p>When the response has been written to the client, the context associated with the request will be canceled. Therefore, we are facing a race condition:</p>\n<ul>\n<li>If the response is written after the Kafka publication, we both return a response and publish a message successfully</li>\n<li>However, if the response is written before or during the Kafka publication, the message shouldn’t be published.</li>\n</ul>\n<p>In the latter case, calling publish will return an error because we returned the HTTP response quickly.</p>\n<details class=\"note\" open=\"open\">\n<summary>Note</summary>\n<p>From Go 1.21, there is a way to create a new context without cancel. <a href=\"https://pkg.go.dev/context#WithoutCancel\"><code>context.WithoutCancel</code></a> returns a copy of parent that is not canceled when parent is canceled.</p>\n</details>\n<p>In summary, propagating a context should be done cautiously.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/61-inappropriate-context/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"iniciando-uma-goroutine-sem-saber-quando-interrompe-la-62\">Iniciando uma goroutine sem saber quando interrompê-la (#62)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Evitar vazamentos significa estar ciente de que sempre que uma goroutine for iniciada, você deve ter um plano para interrompê-la eventualmente.</p>\n</details>\n<p>Goroutines are easy and cheap to start—so easy and cheap that we may not necessarily have a plan for when to stop a new goroutine, which can lead to leaks. Not knowing when to stop a goroutine is a design issue and a common concurrency mistake in Go.</p>\n<p>Let’s discuss a concrete example. We will design an application that needs to watch some external configuration (for example, using a database connection). Here’s a first implementation:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-37-1\"><a id=\"__codelineno-37-1\" name=\"__codelineno-37-1\" href=\"#__codelineno-37-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-37-2\"><a id=\"__codelineno-37-2\" name=\"__codelineno-37-2\" href=\"#__codelineno-37-2\"></a><span class=\"w\">    </span><span class=\"nx\">newWatcher</span><span class=\"p\">()</span>\n</span><span id=\"__span-37-3\"><a id=\"__codelineno-37-3\" name=\"__codelineno-37-3\" href=\"#__codelineno-37-3\"></a><span class=\"w\">    </span><span class=\"c1\">// Run the application</span>\n</span><span id=\"__span-37-4\"><a id=\"__codelineno-37-4\" name=\"__codelineno-37-4\" href=\"#__codelineno-37-4\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-37-5\"><a id=\"__codelineno-37-5\" name=\"__codelineno-37-5\" href=\"#__codelineno-37-5\"></a>\n</span><span id=\"__span-37-6\"><a id=\"__codelineno-37-6\" name=\"__codelineno-37-6\" href=\"#__codelineno-37-6\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"cm\">/* Some resources */</span><span class=\"w\"> </span><span class=\"p\">}</span>\n</span><span id=\"__span-37-7\"><a id=\"__codelineno-37-7\" name=\"__codelineno-37-7\" href=\"#__codelineno-37-7\"></a>\n</span><span id=\"__span-37-8\"><a id=\"__codelineno-37-8\" name=\"__codelineno-37-8\" href=\"#__codelineno-37-8\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">newWatcher</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-37-9\"><a id=\"__codelineno-37-9\" name=\"__codelineno-37-9\" href=\"#__codelineno-37-9\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"p\">{}</span>\n</span><span id=\"__span-37-10\"><a id=\"__codelineno-37-10\" name=\"__codelineno-37-10\" href=\"#__codelineno-37-10\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">watch</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// Creates a goroutine that watches some external configuration</span>\n</span><span id=\"__span-37-11\"><a id=\"__codelineno-37-11\" name=\"__codelineno-37-11\" href=\"#__codelineno-37-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>The problem with this code is that when the main goroutine exits (perhaps because of an OS signal or because it has a finite workload), the application is stopped. Hence, the resources created by watcher aren’t closed gracefully. How can we prevent this from happening?</p>\n<p>One option could be to pass to newWatcher a context that will be canceled when main returns:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-38-1\"><a id=\"__codelineno-38-1\" name=\"__codelineno-38-1\" href=\"#__codelineno-38-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-38-2\"><a id=\"__codelineno-38-2\" name=\"__codelineno-38-2\" href=\"#__codelineno-38-2\"></a><span class=\"w\">    </span><span class=\"nx\">ctx</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">cancel</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">context</span><span class=\"p\">.</span><span class=\"nx\">WithCancel</span><span class=\"p\">(</span><span class=\"nx\">context</span><span class=\"p\">.</span><span class=\"nx\">Background</span><span class=\"p\">())</span>\n</span><span id=\"__span-38-3\"><a id=\"__codelineno-38-3\" name=\"__codelineno-38-3\" href=\"#__codelineno-38-3\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">cancel</span><span class=\"p\">()</span>\n</span><span id=\"__span-38-4\"><a id=\"__codelineno-38-4\" name=\"__codelineno-38-4\" href=\"#__codelineno-38-4\"></a><span class=\"w\">    </span><span class=\"nx\">newWatcher</span><span class=\"p\">(</span><span class=\"nx\">ctx</span><span class=\"p\">)</span>\n</span><span id=\"__span-38-5\"><a id=\"__codelineno-38-5\" name=\"__codelineno-38-5\" href=\"#__codelineno-38-5\"></a><span class=\"w\">    </span><span class=\"c1\">// Run the application</span>\n</span><span id=\"__span-38-6\"><a id=\"__codelineno-38-6\" name=\"__codelineno-38-6\" href=\"#__codelineno-38-6\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-38-7\"><a id=\"__codelineno-38-7\" name=\"__codelineno-38-7\" href=\"#__codelineno-38-7\"></a>\n</span><span id=\"__span-38-8\"><a id=\"__codelineno-38-8\" name=\"__codelineno-38-8\" href=\"#__codelineno-38-8\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">newWatcher</span><span class=\"p\">(</span><span class=\"nx\">ctx</span><span class=\"w\"> </span><span class=\"nx\">context</span><span class=\"p\">.</span><span class=\"nx\">Context</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-38-9\"><a id=\"__codelineno-38-9\" name=\"__codelineno-38-9\" href=\"#__codelineno-38-9\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"p\">{}</span>\n</span><span id=\"__span-38-10\"><a id=\"__codelineno-38-10\" name=\"__codelineno-38-10\" href=\"#__codelineno-38-10\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">watch</span><span class=\"p\">(</span><span class=\"nx\">ctx</span><span class=\"p\">)</span>\n</span><span id=\"__span-38-11\"><a id=\"__codelineno-38-11\" name=\"__codelineno-38-11\" href=\"#__codelineno-38-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>We propagate the context created to the watch method. When the context is canceled, the watcher struct should close its resources. However, can we guarantee that watch will have time to do so? Absolutely not—and that’s a design flaw.</p>\n<p>The problem is that we used signaling to convey that a goroutine had to be stopped. We didn’t block the parent goroutine until the resources had been closed.  Let’s make sure we do:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-39-1\"><a id=\"__codelineno-39-1\" name=\"__codelineno-39-1\" href=\"#__codelineno-39-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-39-2\"><a id=\"__codelineno-39-2\" name=\"__codelineno-39-2\" href=\"#__codelineno-39-2\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">newWatcher</span><span class=\"p\">()</span>\n</span><span id=\"__span-39-3\"><a id=\"__codelineno-39-3\" name=\"__codelineno-39-3\" href=\"#__codelineno-39-3\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nb\">close</span><span class=\"p\">()</span>\n</span><span id=\"__span-39-4\"><a id=\"__codelineno-39-4\" name=\"__codelineno-39-4\" href=\"#__codelineno-39-4\"></a><span class=\"w\">    </span><span class=\"c1\">// Run the application</span>\n</span><span id=\"__span-39-5\"><a id=\"__codelineno-39-5\" name=\"__codelineno-39-5\" href=\"#__codelineno-39-5\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-39-6\"><a id=\"__codelineno-39-6\" name=\"__codelineno-39-6\" href=\"#__codelineno-39-6\"></a>\n</span><span id=\"__span-39-7\"><a id=\"__codelineno-39-7\" name=\"__codelineno-39-7\" href=\"#__codelineno-39-7\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">newWatcher</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-39-8\"><a id=\"__codelineno-39-8\" name=\"__codelineno-39-8\" href=\"#__codelineno-39-8\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"p\">{}</span>\n</span><span id=\"__span-39-9\"><a id=\"__codelineno-39-9\" name=\"__codelineno-39-9\" href=\"#__codelineno-39-9\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">watch</span><span class=\"p\">()</span>\n</span><span id=\"__span-39-10\"><a id=\"__codelineno-39-10\" name=\"__codelineno-39-10\" href=\"#__codelineno-39-10\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">w</span>\n</span><span id=\"__span-39-11\"><a id=\"__codelineno-39-11\" name=\"__codelineno-39-11\" href=\"#__codelineno-39-11\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-39-12\"><a id=\"__codelineno-39-12\" name=\"__codelineno-39-12\" href=\"#__codelineno-39-12\"></a>\n</span><span id=\"__span-39-13\"><a id=\"__codelineno-39-13\" name=\"__codelineno-39-13\" href=\"#__codelineno-39-13\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"nx\">watcher</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nb\">close</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-39-14\"><a id=\"__codelineno-39-14\" name=\"__codelineno-39-14\" href=\"#__codelineno-39-14\"></a><span class=\"w\">    </span><span class=\"c1\">// Close the resources</span>\n</span><span id=\"__span-39-15\"><a id=\"__codelineno-39-15\" name=\"__codelineno-39-15\" href=\"#__codelineno-39-15\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Instead of signaling <code>watcher</code> that it’s time to close its resources, we now call this <code>close</code> method, using <code>defer</code> to guarantee that the resources are closed before the application exits.</p>\n<p>In summary, let’s be mindful that a goroutine is a resource like any other that must eventually be closed to free memory or other resources. Starting a goroutine without knowing when to stop it is a design issue. Whenever a goroutine is started, we should have a clear plan about when it will stop. Last but not least, if a goroutine creates resources and its lifetime is bound to the lifetime of the application, it’s probably safer to wait for this goroutine to complete before exiting the application. This way, we can ensure that the resources can be freed.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/62-starting-goroutine/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-ter-cuidado-com-goroutines-e-variaveis-de-loop-63\"><img alt=\"⚠\" class=\"twemoji\" src=\"https://cdn.jsdelivr.net/gh/jdecked/twemoji@15.1.0/assets/svg/26a0.svg\" title=\":warning:\"> Não ter cuidado com goroutines e variáveis ​​de loop (#63)</h3>\n<details class=\"warning\" open=\"open\">\n<summary>Warning</summary>\n<p>Este erro não é mais relevante no Go 1.22 (<a href=\"https://go.dev/blog/loopvar-preview\">detalhes</a>).</p>\n</details>\n<h3 id=\"esperando-um-comportamento-deterministico-usando-selecao-e-canais-64\">Esperando um comportamento determinístico usando seleção e canais (#64)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Compreender que com <code>select</code> vários canais escolhe o caso aleatoriamente se múltiplas opções forem possíveis evita fazer suposições erradas que podem levar a erros sutis de simultaneidade.</p>\n</details>\n<p>One common mistake made by Go developers while working with channels is to make wrong assumptions about how select behaves with multiple channels.</p>\n<p>For example, let's consider the following case (<code>disconnectCh</code> is a unbuffered channel):</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-40-1\"><a id=\"__codelineno-40-1\" name=\"__codelineno-40-1\" href=\"#__codelineno-40-1\"></a><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-40-2\"><a id=\"__codelineno-40-2\" name=\"__codelineno-40-2\" href=\"#__codelineno-40-2\"></a><span class=\"w\">  </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">10</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-40-3\"><a id=\"__codelineno-40-3\" name=\"__codelineno-40-3\" href=\"#__codelineno-40-3\"></a><span class=\"w\">      </span><span class=\"nx\">messageCh</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"w\"> </span><span class=\"nx\">i</span>\n</span><span id=\"__span-40-4\"><a id=\"__codelineno-40-4\" name=\"__codelineno-40-4\" href=\"#__codelineno-40-4\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-40-5\"><a id=\"__codelineno-40-5\" name=\"__codelineno-40-5\" href=\"#__codelineno-40-5\"></a><span class=\"w\">    </span><span class=\"nx\">disconnectCh</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"p\">{}{}</span>\n</span><span id=\"__span-40-6\"><a id=\"__codelineno-40-6\" name=\"__codelineno-40-6\" href=\"#__codelineno-40-6\"></a><span class=\"p\">}()</span>\n</span><span id=\"__span-40-7\"><a id=\"__codelineno-40-7\" name=\"__codelineno-40-7\" href=\"#__codelineno-40-7\"></a>\n</span><span id=\"__span-40-8\"><a id=\"__codelineno-40-8\" name=\"__codelineno-40-8\" href=\"#__codelineno-40-8\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-40-9\"><a id=\"__codelineno-40-9\" name=\"__codelineno-40-9\" href=\"#__codelineno-40-9\"></a><span class=\"w\">    </span><span class=\"k\">select</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-40-10\"><a id=\"__codelineno-40-10\" name=\"__codelineno-40-10\" href=\"#__codelineno-40-10\"></a><span class=\"w\">    </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">messageCh</span><span class=\"p\">:</span>\n</span><span id=\"__span-40-11\"><a id=\"__codelineno-40-11\" name=\"__codelineno-40-11\" href=\"#__codelineno-40-11\"></a><span class=\"w\">        </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">v</span><span class=\"p\">)</span>\n</span><span id=\"__span-40-12\"><a id=\"__codelineno-40-12\" name=\"__codelineno-40-12\" href=\"#__codelineno-40-12\"></a><span class=\"w\">    </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">disconnectCh</span><span class=\"p\">:</span>\n</span><span id=\"__span-40-13\"><a id=\"__codelineno-40-13\" name=\"__codelineno-40-13\" href=\"#__codelineno-40-13\"></a><span class=\"w\">        </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"s\">\"disconnection, return\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-40-14\"><a id=\"__codelineno-40-14\" name=\"__codelineno-40-14\" href=\"#__codelineno-40-14\"></a><span class=\"w\">        </span><span class=\"k\">return</span>\n</span><span id=\"__span-40-15\"><a id=\"__codelineno-40-15\" name=\"__codelineno-40-15\" href=\"#__codelineno-40-15\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-40-16\"><a id=\"__codelineno-40-16\" name=\"__codelineno-40-16\" href=\"#__codelineno-40-16\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>If we run this example multiple times, the result will be random:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-41-1\"><a id=\"__codelineno-41-1\" name=\"__codelineno-41-1\" href=\"#__codelineno-41-1\"></a>0\n</span><span id=\"__span-41-2\"><a id=\"__codelineno-41-2\" name=\"__codelineno-41-2\" href=\"#__codelineno-41-2\"></a>1\n</span><span id=\"__span-41-3\"><a id=\"__codelineno-41-3\" name=\"__codelineno-41-3\" href=\"#__codelineno-41-3\"></a>2\n</span><span id=\"__span-41-4\"><a id=\"__codelineno-41-4\" name=\"__codelineno-41-4\" href=\"#__codelineno-41-4\"></a>disconnection, return\n</span><span id=\"__span-41-5\"><a id=\"__codelineno-41-5\" name=\"__codelineno-41-5\" href=\"#__codelineno-41-5\"></a>\n</span><span id=\"__span-41-6\"><a id=\"__codelineno-41-6\" name=\"__codelineno-41-6\" href=\"#__codelineno-41-6\"></a>0\n</span><span id=\"__span-41-7\"><a id=\"__codelineno-41-7\" name=\"__codelineno-41-7\" href=\"#__codelineno-41-7\"></a>disconnection, return\n</span></code></pre></div>\n<p>Instead of consuming the 10 messages, we only received a few of them. What’s the reason? It lies in the specification of the select statement with multiple channels (https:// go.dev/ref/spec):</p>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">Quote</p>\n<p>If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection.</p>\n</div>\n<p>Unlike a switch statement, where the first case with a match wins, the select statement selects randomly if multiple options are possible.</p>\n<p>This behavior might look odd at first, but there’s a good reason for it: to prevent possible starvation. Suppose the first possible communication chosen is based on the source order. In that case, we may fall into a situation where, for example, we only receive from one channel because of a fast sender. To prevent this, the language designers decided to use a random selection.</p>\n<p>When using <code>select</code> with multiple channels, we must remember that if multiple options are possible, the first case in the source order does not automatically win. Instead, Go selects randomly, so there’s no guarantee about which option will be chosen. To overcome this behavior, in the case of a single producer goroutine, we can use either unbuffered channels or a single channel.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/64-select-behavior/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-usar-canais-de-notificacao-65\">Não usar canais de notificação (#65)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Envie notificações usando um tipo <code>chan struct{}</code>.</p>\n</details>\n<p>Channels are a mechanism for communicating across goroutines via signaling. A signal can be either with or without data.</p>\n<p>Let’s look at a concrete example. We will create a channel that will notify us whenever a certain disconnection occurs. One idea is to handle it as a <code>chan bool</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-42-1\"><a id=\"__codelineno-42-1\" name=\"__codelineno-42-1\" href=\"#__codelineno-42-1\"></a><span class=\"nx\">disconnectCh</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">bool</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>Now, let’s say we interact with an API that provides us with such a channel. Because it’s a channel of Booleans, we can receive either <code>true</code> or <code>false</code> messages. It’s probably clear what <code>true</code> conveys. But what does <code>false</code> mean? Does it mean we haven’t been disconnected? And in this case, how frequently will we receive such a signal? Does it mean we have reconnected? Should we even expect to receive <code>false</code>? Perhaps we should only expect to receive <code>true</code> messages.</p>\n<p>If that’s the case, meaning we don’t need a specific value to convey some information, we need a channel <em>without</em> data. The idiomatic way to handle it is a channel of empty structs: <code>chan struct{}</code>.</p>\n<h3 id=\"nao-usar-canais-nulos-66\">Não usar canais nulos (#66)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>O uso de canais nulos deve fazer parte do seu conjunto de ferramentas de simultaneidade porque permite remover casos de instruções <code>select</code>, por exemplo.</p>\n</details>\n<p>What should this code do?</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-43-1\"><a id=\"__codelineno-43-1\" name=\"__codelineno-43-1\" href=\"#__codelineno-43-1\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span>\n</span><span id=\"__span-43-2\"><a id=\"__codelineno-43-2\" name=\"__codelineno-43-2\" href=\"#__codelineno-43-2\"></a><span class=\"o\">&lt;-</span><span class=\"nx\">ch</span>\n</span></code></pre></div>\n<p><code>ch</code> is a <code>chan int</code> type. The zero value of a channel being nil, <code>ch</code> is <code>nil</code>. The goroutine won’t panic; however, it will block forever.</p>\n<p>The principle is the same if we send a message to a nil channel. This goroutine blocks forever:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-44-1\"><a id=\"__codelineno-44-1\" name=\"__codelineno-44-1\" href=\"#__codelineno-44-1\"></a><span class=\"kd\">var</span><span class=\"w\"> </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span>\n</span><span id=\"__span-44-2\"><a id=\"__codelineno-44-2\" name=\"__codelineno-44-2\" href=\"#__codelineno-44-2\"></a><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"w\"> </span><span class=\"mi\">0</span>\n</span></code></pre></div>\n<p>Then what’s the purpose of Go allowing messages to be received from or sent to a nil channel? For example, we can use nil channels to implement an idiomatic way to merge two channels:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-45-1\"><a id=\"__codelineno-45-1\" name=\"__codelineno-45-1\" href=\"#__codelineno-45-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">merge</span><span class=\"p\">(</span><span class=\"nx\">ch1</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">ch2</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-45-2\"><a id=\"__codelineno-45-2\" name=\"__codelineno-45-2\" href=\"#__codelineno-45-2\"></a><span class=\"w\">    </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-45-3\"><a id=\"__codelineno-45-3\" name=\"__codelineno-45-3\" href=\"#__codelineno-45-3\"></a>\n</span><span id=\"__span-45-4\"><a id=\"__codelineno-45-4\" name=\"__codelineno-45-4\" href=\"#__codelineno-45-4\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-45-5\"><a id=\"__codelineno-45-5\" name=\"__codelineno-45-5\" href=\"#__codelineno-45-5\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">ch1</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"o\">||</span><span class=\"w\"> </span><span class=\"nx\">ch2</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Continue if at least one channel isn’t nil</span>\n</span></span><span id=\"__span-45-6\"><a id=\"__codelineno-45-6\" name=\"__codelineno-45-6\" href=\"#__codelineno-45-6\"></a><span class=\"w\">            </span><span class=\"k\">select</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-45-7\"><a id=\"__codelineno-45-7\" name=\"__codelineno-45-7\" href=\"#__codelineno-45-7\"></a><span class=\"w\">            </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">open</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">ch1</span><span class=\"p\">:</span>\n</span><span id=\"__span-45-8\"><a id=\"__codelineno-45-8\" name=\"__codelineno-45-8\" href=\"#__codelineno-45-8\"></a><span class=\"w\">                </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"p\">!</span><span class=\"nx\">open</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-45-9\"><a id=\"__codelineno-45-9\" name=\"__codelineno-45-9\" href=\"#__codelineno-45-9\"></a><span class=\"hll\"><span class=\"w\">                    </span><span class=\"nx\">ch1</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"c1\">// Assign ch1 to a nil channel once closed</span>\n</span></span><span id=\"__span-45-10\"><a id=\"__codelineno-45-10\" name=\"__codelineno-45-10\" href=\"#__codelineno-45-10\"></a><span class=\"w\">                    </span><span class=\"k\">break</span>\n</span><span id=\"__span-45-11\"><a id=\"__codelineno-45-11\" name=\"__codelineno-45-11\" href=\"#__codelineno-45-11\"></a><span class=\"w\">                </span><span class=\"p\">}</span>\n</span><span id=\"__span-45-12\"><a id=\"__codelineno-45-12\" name=\"__codelineno-45-12\" href=\"#__codelineno-45-12\"></a><span class=\"w\">                </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"w\"> </span><span class=\"nx\">v</span>\n</span><span id=\"__span-45-13\"><a id=\"__codelineno-45-13\" name=\"__codelineno-45-13\" href=\"#__codelineno-45-13\"></a><span class=\"w\">            </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">open</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">ch2</span><span class=\"p\">:</span>\n</span><span id=\"__span-45-14\"><a id=\"__codelineno-45-14\" name=\"__codelineno-45-14\" href=\"#__codelineno-45-14\"></a><span class=\"w\">                </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"p\">!</span><span class=\"nx\">open</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-45-15\"><a id=\"__codelineno-45-15\" name=\"__codelineno-45-15\" href=\"#__codelineno-45-15\"></a><span class=\"hll\"><span class=\"w\">                    </span><span class=\"nx\">ch2</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"c1\">// Assigns ch2 to a nil channel once closed</span>\n</span></span><span id=\"__span-45-16\"><a id=\"__codelineno-45-16\" name=\"__codelineno-45-16\" href=\"#__codelineno-45-16\"></a><span class=\"w\">                    </span><span class=\"k\">break</span>\n</span><span id=\"__span-45-17\"><a id=\"__codelineno-45-17\" name=\"__codelineno-45-17\" href=\"#__codelineno-45-17\"></a><span class=\"w\">                </span><span class=\"p\">}</span>\n</span><span id=\"__span-45-18\"><a id=\"__codelineno-45-18\" name=\"__codelineno-45-18\" href=\"#__codelineno-45-18\"></a><span class=\"w\">                </span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"w\"> </span><span class=\"nx\">v</span>\n</span><span id=\"__span-45-19\"><a id=\"__codelineno-45-19\" name=\"__codelineno-45-19\" href=\"#__codelineno-45-19\"></a><span class=\"w\">            </span><span class=\"p\">}</span>\n</span><span id=\"__span-45-20\"><a id=\"__codelineno-45-20\" name=\"__codelineno-45-20\" href=\"#__codelineno-45-20\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-45-21\"><a id=\"__codelineno-45-21\" name=\"__codelineno-45-21\" href=\"#__codelineno-45-21\"></a><span class=\"w\">        </span><span class=\"nb\">close</span><span class=\"p\">(</span><span class=\"nx\">ch</span><span class=\"p\">)</span>\n</span><span id=\"__span-45-22\"><a id=\"__codelineno-45-22\" name=\"__codelineno-45-22\" href=\"#__codelineno-45-22\"></a><span class=\"w\">    </span><span class=\"p\">}()</span>\n</span><span id=\"__span-45-23\"><a id=\"__codelineno-45-23\" name=\"__codelineno-45-23\" href=\"#__codelineno-45-23\"></a>\n</span><span id=\"__span-45-24\"><a id=\"__codelineno-45-24\" name=\"__codelineno-45-24\" href=\"#__codelineno-45-24\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">ch</span>\n</span><span id=\"__span-45-25\"><a id=\"__codelineno-45-25\" name=\"__codelineno-45-25\" href=\"#__codelineno-45-25\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>This elegant solution relies on nil channels to somehow <em>remove</em> one case from the <code>select</code> statement.</p>\n<p>Let’s keep this idea in mind: nil channels are useful in some conditions and should be part of the Go developer’s toolset when dealing with concurrent code.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/66-nil-channels/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"ficar-intrigado-com-o-tamanho-do-canal-67\">Ficar intrigado com o tamanho do canal (#67)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Decida cuidadosamente o tipo de canal correto a ser usado, considerando o problema. Somente canais sem buffer oferecem fortes garantias de sincronização. Para canais em buffer, você deve ter um bom motivo para especificar um tamanho de canal diferente de um.</p>\n</details>\n<p>An unbuffered channel is a channel without any capacity. It can be created by either omitting the size or providing a 0 size:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-46-1\"><a id=\"__codelineno-46-1\" name=\"__codelineno-46-1\" href=\"#__codelineno-46-1\"></a><span class=\"nx\">ch1</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span>\n</span><span id=\"__span-46-2\"><a id=\"__codelineno-46-2\" name=\"__codelineno-46-2\" href=\"#__codelineno-46-2\"></a><span class=\"nx\">ch2</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>With an unbuffered channel (sometimes called a synchronous channel), the sender will block until the receiver receives data from the channel.</p>\n<p>Conversely, a buffered channel has a capacity, and it must be created with a size greater than or equal to 1:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-47-1\"><a id=\"__codelineno-47-1\" name=\"__codelineno-47-1\" href=\"#__codelineno-47-1\"></a><span class=\"nx\">ch3</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>With a buffered channel, a sender can send messages while the channel isn’t full. Once the channel is full, it will block until a receiver goroutine receives a message:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-48-1\"><a id=\"__codelineno-48-1\" name=\"__codelineno-48-1\" href=\"#__codelineno-48-1\"></a><span class=\"nx\">ch3</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-48-2\"><a id=\"__codelineno-48-2\" name=\"__codelineno-48-2\" href=\"#__codelineno-48-2\"></a><span class=\"nx\">ch3</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"mi\">1</span><span class=\"w\"> </span><span class=\"c1\">// Non-blocking</span>\n</span><span id=\"__span-48-3\"><a id=\"__codelineno-48-3\" name=\"__codelineno-48-3\" href=\"#__codelineno-48-3\"></a><span class=\"nx\">ch3</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"mi\">2</span><span class=\"w\"> </span><span class=\"c1\">// Blocking</span>\n</span></code></pre></div>\n<p>The first send isn’t blocking, whereas the second one is, as the channel is full at this stage.</p>\n<p>What's the main difference between unbuffered and buffered channels:</p>\n<ul>\n<li>An unbuffered channel enables synchronization. We have the guarantee that two goroutines will be in a known state: one receiving and another sending a message.</li>\n<li>A buffered channel doesn’t provide any strong synchronization. Indeed, a producer goroutine can send a message and then continue its execution if the channel isn’t full. The only guarantee is that a goroutine won’t receive a message before it is sent. But this is only a guarantee because of causality (you don’t drink your coffee before you prepare it).</li>\n</ul>\n<p>If we need a buffered channel, what size should we provide?</p>\n<p>The default value we should use for buffered channels is its minimum: 1. So, we may approach the problem from this standpoint: is there any good reason not to use a value of 1? Here’s a list of possible cases where we should use another size:</p>\n<ul>\n<li>While using a worker pooling-like pattern, meaning spinning a fixed number of goroutines that need to send data to a shared channel. In that case, we can tie the channel size to the number of goroutines created.</li>\n<li>When using channels for rate-limiting problems. For example, if we need to enforce resource utilization by bounding the number of requests, we should set up the channel size according to the limit.</li>\n</ul>\n<p>If we are outside of these cases, using a different channel size should be done cautiously. Let’s bear in mind that deciding about an accurate queue size isn’t an easy problem:</p>\n<div class=\"admonition quote\">\n<p class=\"admonition-title\">Martin Thompson</p>\n<p>Queues are typically always close to full or close to empty due to the differences in pace between consumers and producers. They very rarely operate in a balanced middle ground where the rate of production and consumption is evenly matched.</p>\n</div>\n<h3 id=\"esquecendo-os-possiveis-efeitos-colaterais-da-formatacao-de-strings-68\">Esquecendo os possíveis efeitos colaterais da formatação de strings (#68)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Estar ciente de que a formatação de strings pode levar à chamada de funções existentes significa estar atento a possíveis impasses e outras disputas de dados.</p>\n</details>\n<p>It’s pretty easy to forget the potential side effects of string formatting while working in a concurrent application.</p>\n<h4 id=\"etcd-data-race\"><a href=\"https://github.com/etcd-io/etcd\">etcd</a> data race</h4>\n<p><a href=\"https://github.com/etcd-io/etcd/pull/7816\">github.com/etcd-io/etcd/pull/7816</a> shows an example of an issue where a map's key was formatted based on a mutable values from a context.</p>\n<h4 id=\"deadlock\">Deadlock</h4>\n<p>Can you see what the problem is in this code with a <code>Customer</code> struct exposing an <code>UpdateAge</code> method and implementing the <code>fmt.Stringer</code> interface?</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-49-1\"><a id=\"__codelineno-49-1\" name=\"__codelineno-49-1\" href=\"#__codelineno-49-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Customer</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-49-2\"><a id=\"__codelineno-49-2\" name=\"__codelineno-49-2\" href=\"#__codelineno-49-2\"></a><span class=\"w\">    </span><span class=\"nx\">mutex</span><span class=\"w\"> </span><span class=\"nx\">sync</span><span class=\"p\">.</span><span class=\"nx\">RWMutex</span><span class=\"w\"> </span><span class=\"c1\">// Uses a sync.RWMutex to protect concurrent accesses</span>\n</span><span id=\"__span-49-3\"><a id=\"__codelineno-49-3\" name=\"__codelineno-49-3\" href=\"#__codelineno-49-3\"></a><span class=\"w\">    </span><span class=\"nx\">id</span><span class=\"w\">    </span><span class=\"kt\">string</span>\n</span><span id=\"__span-49-4\"><a id=\"__codelineno-49-4\" name=\"__codelineno-49-4\" href=\"#__codelineno-49-4\"></a><span class=\"w\">    </span><span class=\"nx\">age</span><span class=\"w\">   </span><span class=\"kt\">int</span>\n</span><span id=\"__span-49-5\"><a id=\"__codelineno-49-5\" name=\"__codelineno-49-5\" href=\"#__codelineno-49-5\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-49-6\"><a id=\"__codelineno-49-6\" name=\"__codelineno-49-6\" href=\"#__codelineno-49-6\"></a>\n</span><span id=\"__span-49-7\"><a id=\"__codelineno-49-7\" name=\"__codelineno-49-7\" href=\"#__codelineno-49-7\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Customer</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">UpdateAge</span><span class=\"p\">(</span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-49-8\"><a id=\"__codelineno-49-8\" name=\"__codelineno-49-8\" href=\"#__codelineno-49-8\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">Lock</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// Locks and defers unlock as we update Customer</span>\n</span><span id=\"__span-49-9\"><a id=\"__codelineno-49-9\" name=\"__codelineno-49-9\" href=\"#__codelineno-49-9\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">Unlock</span><span class=\"p\">()</span>\n</span><span id=\"__span-49-10\"><a id=\"__codelineno-49-10\" name=\"__codelineno-49-10\" href=\"#__codelineno-49-10\"></a>\n</span><span id=\"__span-49-11\"><a id=\"__codelineno-49-11\" name=\"__codelineno-49-11\" href=\"#__codelineno-49-11\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Returns an error if age is negative</span>\n</span><span id=\"__span-49-12\"><a id=\"__codelineno-49-12\" name=\"__codelineno-49-12\" href=\"#__codelineno-49-12\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Errorf</span><span class=\"p\">(</span><span class=\"s\">\"age should be positive for customer %v\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">)</span>\n</span><span id=\"__span-49-13\"><a id=\"__codelineno-49-13\" name=\"__codelineno-49-13\" href=\"#__codelineno-49-13\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-49-14\"><a id=\"__codelineno-49-14\" name=\"__codelineno-49-14\" href=\"#__codelineno-49-14\"></a>\n</span><span id=\"__span-49-15\"><a id=\"__codelineno-49-15\" name=\"__codelineno-49-15\" href=\"#__codelineno-49-15\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">age</span>\n</span><span id=\"__span-49-16\"><a id=\"__codelineno-49-16\" name=\"__codelineno-49-16\" href=\"#__codelineno-49-16\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-49-17\"><a id=\"__codelineno-49-17\" name=\"__codelineno-49-17\" href=\"#__codelineno-49-17\"></a><span class=\"p\">}</span>\n</span><span id=\"__span-49-18\"><a id=\"__codelineno-49-18\" name=\"__codelineno-49-18\" href=\"#__codelineno-49-18\"></a>\n</span><span id=\"__span-49-19\"><a id=\"__codelineno-49-19\" name=\"__codelineno-49-19\" href=\"#__codelineno-49-19\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Customer</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">String</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-49-20\"><a id=\"__codelineno-49-20\" name=\"__codelineno-49-20\" href=\"#__codelineno-49-20\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">RLock</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// Locks and defers unlock as we read Customer</span>\n</span><span id=\"__span-49-21\"><a id=\"__codelineno-49-21\" name=\"__codelineno-49-21\" href=\"#__codelineno-49-21\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">RUnlock</span><span class=\"p\">()</span>\n</span><span id=\"__span-49-22\"><a id=\"__codelineno-49-22\" name=\"__codelineno-49-22\" href=\"#__codelineno-49-22\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Sprintf</span><span class=\"p\">(</span><span class=\"s\">\"id %s, age %d\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">age</span><span class=\"p\">)</span>\n</span><span id=\"__span-49-23\"><a id=\"__codelineno-49-23\" name=\"__codelineno-49-23\" href=\"#__codelineno-49-23\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>The problem here may not be straightforward. If the provided age is negative, we return an error. Because the error is formatted, using the <code>%s</code> directive on the receiver, it will call the <code>String</code> method to format <code>Customer</code>. But because <code>UpdateAge</code> already acquires the mutex lock, the <code>String</code> method won’t be able to acquire it. Hence, this leads to a deadlock situation. If all goroutines are also asleep, it leads to a panic.</p>\n<p>One possible solution is to restrict the scope of the mutex lock:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-50-1\"><a id=\"__codelineno-50-1\" name=\"__codelineno-50-1\" href=\"#__codelineno-50-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Customer</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">UpdateAge</span><span class=\"p\">(</span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-50-2\"><a id=\"__codelineno-50-2\" name=\"__codelineno-50-2\" href=\"#__codelineno-50-2\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span></span><span id=\"__span-50-3\"><a id=\"__codelineno-50-3\" name=\"__codelineno-50-3\" href=\"#__codelineno-50-3\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Errorf</span><span class=\"p\">(</span><span class=\"s\">\"age should be positive for customer %v\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-50-4\"><a id=\"__codelineno-50-4\" name=\"__codelineno-50-4\" href=\"#__codelineno-50-4\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"p\">}</span>\n</span></span><span id=\"__span-50-5\"><a id=\"__codelineno-50-5\" name=\"__codelineno-50-5\" href=\"#__codelineno-50-5\"></a>\n</span><span id=\"__span-50-6\"><a id=\"__codelineno-50-6\" name=\"__codelineno-50-6\" href=\"#__codelineno-50-6\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">Lock</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"mi\">1</span><span class=\"p\">&gt;</span>\n</span><span id=\"__span-50-7\"><a id=\"__codelineno-50-7\" name=\"__codelineno-50-7\" href=\"#__codelineno-50-7\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">Unlock</span><span class=\"p\">()</span>\n</span><span id=\"__span-50-8\"><a id=\"__codelineno-50-8\" name=\"__codelineno-50-8\" href=\"#__codelineno-50-8\"></a>\n</span><span id=\"__span-50-9\"><a id=\"__codelineno-50-9\" name=\"__codelineno-50-9\" href=\"#__codelineno-50-9\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">age</span>\n</span><span id=\"__span-50-10\"><a id=\"__codelineno-50-10\" name=\"__codelineno-50-10\" href=\"#__codelineno-50-10\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-50-11\"><a id=\"__codelineno-50-11\" name=\"__codelineno-50-11\" href=\"#__codelineno-50-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Yet, such an approach isn't always possible. In these conditions, we have to be extremely careful with string formatting.</p>\n<p>Another approach is to access the <code>id</code> field directly:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-51-1\"><a id=\"__codelineno-51-1\" name=\"__codelineno-51-1\" href=\"#__codelineno-51-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Customer</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">UpdateAge</span><span class=\"p\">(</span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"kt\">int</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"kt\">error</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-51-2\"><a id=\"__codelineno-51-2\" name=\"__codelineno-51-2\" href=\"#__codelineno-51-2\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">Lock</span><span class=\"p\">()</span>\n</span><span id=\"__span-51-3\"><a id=\"__codelineno-51-3\" name=\"__codelineno-51-3\" href=\"#__codelineno-51-3\"></a><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mutex</span><span class=\"p\">.</span><span class=\"nx\">Unlock</span><span class=\"p\">()</span>\n</span><span id=\"__span-51-4\"><a id=\"__codelineno-51-4\" name=\"__codelineno-51-4\" href=\"#__codelineno-51-4\"></a>\n</span><span id=\"__span-51-5\"><a id=\"__codelineno-51-5\" name=\"__codelineno-51-5\" href=\"#__codelineno-51-5\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"p\">&lt;</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-51-6\"><a id=\"__codelineno-51-6\" name=\"__codelineno-51-6\" href=\"#__codelineno-51-6\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Errorf</span><span class=\"p\">(</span><span class=\"s\">\"age should be positive for customer id %s\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-51-7\"><a id=\"__codelineno-51-7\" name=\"__codelineno-51-7\" href=\"#__codelineno-51-7\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-51-8\"><a id=\"__codelineno-51-8\" name=\"__codelineno-51-8\" href=\"#__codelineno-51-8\"></a>\n</span><span id=\"__span-51-9\"><a id=\"__codelineno-51-9\" name=\"__codelineno-51-9\" href=\"#__codelineno-51-9\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">age</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">age</span>\n</span><span id=\"__span-51-10\"><a id=\"__codelineno-51-10\" name=\"__codelineno-51-10\" href=\"#__codelineno-51-10\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"kc\">nil</span>\n</span><span id=\"__span-51-11\"><a id=\"__codelineno-51-11\" name=\"__codelineno-51-11\" href=\"#__codelineno-51-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>In concurrent applications, we should remain cautious about the possible side effects of string formatting.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/68-string-formatting/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"criando-corridas-de-dados-com-acrescimo-69\">Criando corridas de dados com acréscimo (#69)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>As chamadas <code>append</code> nem sempre são isentas de disputa de dados; portanto, não deve ser usado simultaneamente em uma slice compartilhada.</p>\n</details>\n<p>Should adding an element to a slice using <code>append</code> is data-race-free? Spoiler: it depends.</p>\n<p>Do you believe this example has a data race? </p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-52-1\"><a id=\"__codelineno-52-1\" name=\"__codelineno-52-1\" href=\"#__codelineno-52-1\"></a><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">([]</span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-52-2\"><a id=\"__codelineno-52-2\" name=\"__codelineno-52-2\" href=\"#__codelineno-52-2\"></a>\n</span><span id=\"__span-52-3\"><a id=\"__codelineno-52-3\" name=\"__codelineno-52-3\" href=\"#__codelineno-52-3\"></a><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// In a new goroutine, appends a new element on s</span>\n</span><span id=\"__span-52-4\"><a id=\"__codelineno-52-4\" name=\"__codelineno-52-4\" href=\"#__codelineno-52-4\"></a><span class=\"w\">    </span><span class=\"nx\">s1</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-52-5\"><a id=\"__codelineno-52-5\" name=\"__codelineno-52-5\" href=\"#__codelineno-52-5\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">s1</span><span class=\"p\">)</span>\n</span><span id=\"__span-52-6\"><a id=\"__codelineno-52-6\" name=\"__codelineno-52-6\" href=\"#__codelineno-52-6\"></a><span class=\"p\">}()</span>\n</span><span id=\"__span-52-7\"><a id=\"__codelineno-52-7\" name=\"__codelineno-52-7\" href=\"#__codelineno-52-7\"></a>\n</span><span id=\"__span-52-8\"><a id=\"__codelineno-52-8\" name=\"__codelineno-52-8\" href=\"#__codelineno-52-8\"></a><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Same</span>\n</span><span id=\"__span-52-9\"><a id=\"__codelineno-52-9\" name=\"__codelineno-52-9\" href=\"#__codelineno-52-9\"></a><span class=\"w\">    </span><span class=\"nx\">s2</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-52-10\"><a id=\"__codelineno-52-10\" name=\"__codelineno-52-10\" href=\"#__codelineno-52-10\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">s2</span><span class=\"p\">)</span>\n</span><span id=\"__span-52-11\"><a id=\"__codelineno-52-11\" name=\"__codelineno-52-11\" href=\"#__codelineno-52-11\"></a><span class=\"p\">}()</span>\n</span></code></pre></div>\n<p>The answer is no.</p>\n<p>In this example, we create a slice with <code>make([]int, 1)</code>. The code creates a one-length, one-capacity slice. Thus, because the slice is full, using append in each goroutine returns a slice backed by a new array. It doesn’t mutate the existing array; hence, it doesn’t lead to a data race.</p>\n<p>Now, let’s run the same example with a slight change in how we initialize <code>s</code>. Instead of creating a slice with a length of 1, we create it with a length of 0 but a capacity of 1. How about this new example? Does it contain a data race?</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-53-1\"><a id=\"__codelineno-53-1\" name=\"__codelineno-53-1\" href=\"#__codelineno-53-1\"></a><span class=\"hll\"><span class=\"nx\">s</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">([]</span><span class=\"kt\">int</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span></span><span id=\"__span-53-2\"><a id=\"__codelineno-53-2\" name=\"__codelineno-53-2\" href=\"#__codelineno-53-2\"></a>\n</span><span id=\"__span-53-3\"><a id=\"__codelineno-53-3\" name=\"__codelineno-53-3\" href=\"#__codelineno-53-3\"></a><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span>\n</span><span id=\"__span-53-4\"><a id=\"__codelineno-53-4\" name=\"__codelineno-53-4\" href=\"#__codelineno-53-4\"></a><span class=\"w\">    </span><span class=\"nx\">s1</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-53-5\"><a id=\"__codelineno-53-5\" name=\"__codelineno-53-5\" href=\"#__codelineno-53-5\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">s1</span><span class=\"p\">)</span>\n</span><span id=\"__span-53-6\"><a id=\"__codelineno-53-6\" name=\"__codelineno-53-6\" href=\"#__codelineno-53-6\"></a><span class=\"p\">}()</span>\n</span><span id=\"__span-53-7\"><a id=\"__codelineno-53-7\" name=\"__codelineno-53-7\" href=\"#__codelineno-53-7\"></a>\n</span><span id=\"__span-53-8\"><a id=\"__codelineno-53-8\" name=\"__codelineno-53-8\" href=\"#__codelineno-53-8\"></a><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-53-9\"><a id=\"__codelineno-53-9\" name=\"__codelineno-53-9\" href=\"#__codelineno-53-9\"></a><span class=\"w\">    </span><span class=\"nx\">s2</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">append</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</span><span id=\"__span-53-10\"><a id=\"__codelineno-53-10\" name=\"__codelineno-53-10\" href=\"#__codelineno-53-10\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">s2</span><span class=\"p\">)</span>\n</span><span id=\"__span-53-11\"><a id=\"__codelineno-53-11\" name=\"__codelineno-53-11\" href=\"#__codelineno-53-11\"></a><span class=\"p\">}()</span>\n</span></code></pre></div>\n<p>The answer is yes. We create a slice with <code>make([]int, 0, 1)</code>. Therefore, the array isn’t full. Both goroutines attempt to update the same index of the backing array (index 1), which is a data race.</p>\n<p>How can we prevent the data race if we want both goroutines to work on a slice containing the initial elements of <code>s</code> plus an extra element? One solution is to create a copy of <code>s</code>.</p>\n<p>We should remember that using append on a shared slice in concurrent applications can lead to a data race. Hence, it should be avoided.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/69-data-race-append/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"usando-mutexes-imprecisamente-com-slices-e-maps-70\">Usando mutexes imprecisamente com slices e maps (#70)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Lembrar que slices e maps são ponteiros pode evitar corridas comuns de dados.</p>\n</details>\n<p>Let's implement a <code>Cache</code> struct used to handle caching for customer balances. This struct will contain a map of balances per customer ID and a mutex to protect concurrent accesses:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-54-1\"><a id=\"__codelineno-54-1\" name=\"__codelineno-54-1\" href=\"#__codelineno-54-1\"></a><span class=\"kd\">type</span><span class=\"w\"> </span><span class=\"nx\">Cache</span><span class=\"w\"> </span><span class=\"kd\">struct</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-54-2\"><a id=\"__codelineno-54-2\" name=\"__codelineno-54-2\" href=\"#__codelineno-54-2\"></a><span class=\"w\">    </span><span class=\"nx\">mu</span><span class=\"w\">       </span><span class=\"nx\">sync</span><span class=\"p\">.</span><span class=\"nx\">RWMutex</span>\n</span><span id=\"__span-54-3\"><a id=\"__codelineno-54-3\" name=\"__codelineno-54-3\" href=\"#__codelineno-54-3\"></a><span class=\"w\">    </span><span class=\"nx\">balances</span><span class=\"w\"> </span><span class=\"kd\">map</span><span class=\"p\">[</span><span class=\"kt\">string</span><span class=\"p\">]</span><span class=\"kt\">float64</span>\n</span><span id=\"__span-54-4\"><a id=\"__codelineno-54-4\" name=\"__codelineno-54-4\" href=\"#__codelineno-54-4\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Next, we add an <code>AddBalance</code> method that mutates the <code>balances</code> map. The mutation is done in a critical section (within a mutex lock and a mutex unlock):</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-55-1\"><a id=\"__codelineno-55-1\" name=\"__codelineno-55-1\" href=\"#__codelineno-55-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Cache</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">AddBalance</span><span class=\"p\">(</span><span class=\"nx\">id</span><span class=\"w\"> </span><span class=\"kt\">string</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">balance</span><span class=\"w\"> </span><span class=\"kt\">float64</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-55-2\"><a id=\"__codelineno-55-2\" name=\"__codelineno-55-2\" href=\"#__codelineno-55-2\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">Lock</span><span class=\"p\">()</span>\n</span><span id=\"__span-55-3\"><a id=\"__codelineno-55-3\" name=\"__codelineno-55-3\" href=\"#__codelineno-55-3\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">balances</span><span class=\"p\">[</span><span class=\"nx\">id</span><span class=\"p\">]</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">balance</span>\n</span><span id=\"__span-55-4\"><a id=\"__codelineno-55-4\" name=\"__codelineno-55-4\" href=\"#__codelineno-55-4\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">Unlock</span><span class=\"p\">()</span>\n</span><span id=\"__span-55-5\"><a id=\"__codelineno-55-5\" name=\"__codelineno-55-5\" href=\"#__codelineno-55-5\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Meanwhile, we have to implement a method to calculate the average balance for all the customers. One idea is to handle a minimal critical section this way:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-56-1\"><a id=\"__codelineno-56-1\" name=\"__codelineno-56-1\" href=\"#__codelineno-56-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Cache</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">AverageBalance</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">float64</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-56-2\"><a id=\"__codelineno-56-2\" name=\"__codelineno-56-2\" href=\"#__codelineno-56-2\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">RLock</span><span class=\"p\">()</span>\n</span><span id=\"__span-56-3\"><a id=\"__codelineno-56-3\" name=\"__codelineno-56-3\" href=\"#__codelineno-56-3\"></a><span class=\"w\">    </span><span class=\"nx\">balances</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">balances</span><span class=\"w\"> </span><span class=\"c1\">// Creates a copy of the balances map</span>\n</span><span id=\"__span-56-4\"><a id=\"__codelineno-56-4\" name=\"__codelineno-56-4\" href=\"#__codelineno-56-4\"></a><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">RUnlock</span><span class=\"p\">()</span>\n</span><span id=\"__span-56-5\"><a id=\"__codelineno-56-5\" name=\"__codelineno-56-5\" href=\"#__codelineno-56-5\"></a>\n</span><span id=\"__span-56-6\"><a id=\"__codelineno-56-6\" name=\"__codelineno-56-6\" href=\"#__codelineno-56-6\"></a><span class=\"w\">    </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mf\">0.</span>\n</span><span id=\"__span-56-7\"><a id=\"__codelineno-56-7\" name=\"__codelineno-56-7\" href=\"#__codelineno-56-7\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">balance</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">balances</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"c1\">// Iterates over the copy, outside of the critical section</span>\n</span><span id=\"__span-56-8\"><a id=\"__codelineno-56-8\" name=\"__codelineno-56-8\" href=\"#__codelineno-56-8\"></a><span class=\"w\">        </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"nx\">balance</span>\n</span><span id=\"__span-56-9\"><a id=\"__codelineno-56-9\" name=\"__codelineno-56-9\" href=\"#__codelineno-56-9\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-56-10\"><a id=\"__codelineno-56-10\" name=\"__codelineno-56-10\" href=\"#__codelineno-56-10\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">/</span><span class=\"w\"> </span><span class=\"nb\">float64</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">balances</span><span class=\"p\">))</span>\n</span><span id=\"__span-56-11\"><a id=\"__codelineno-56-11\" name=\"__codelineno-56-11\" href=\"#__codelineno-56-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>What's the problem with this code?</p>\n<p>If we run a test using the <code>-race</code> flag with two concurrent goroutines, one calling <code>AddBalance</code> (hence mutating balances) and another calling <code>AverageBalance</code>, a data race occurs. What’s the problem here?</p>\n<p>Internally, a map is a <code>runtime.hmap</code> struct containing mostly metadata (for example, a counter) and a pointer referencing data buckets. So, <code>balances := c.balances</code> doesn’t copy the actual data. Therefore, the two goroutines perform operations on the same data set, and one mutates it. Hence, it's a data race.</p>\n<p>One possible solution is to protect the whole <code>AverageBalance</code> function:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-57-1\"><a id=\"__codelineno-57-1\" name=\"__codelineno-57-1\" href=\"#__codelineno-57-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Cache</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">AverageBalance</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">float64</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-57-2\"><a id=\"__codelineno-57-2\" name=\"__codelineno-57-2\" href=\"#__codelineno-57-2\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">RLock</span><span class=\"p\">()</span>\n</span></span><span id=\"__span-57-3\"><a id=\"__codelineno-57-3\" name=\"__codelineno-57-3\" href=\"#__codelineno-57-3\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"k\">defer</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">RUnlock</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"c1\">// Unlocks when the function returns</span>\n</span></span><span id=\"__span-57-4\"><a id=\"__codelineno-57-4\" name=\"__codelineno-57-4\" href=\"#__codelineno-57-4\"></a>\n</span><span id=\"__span-57-5\"><a id=\"__codelineno-57-5\" name=\"__codelineno-57-5\" href=\"#__codelineno-57-5\"></a><span class=\"w\">    </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mf\">0.</span>\n</span><span id=\"__span-57-6\"><a id=\"__codelineno-57-6\" name=\"__codelineno-57-6\" href=\"#__codelineno-57-6\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">balance</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">balances</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-57-7\"><a id=\"__codelineno-57-7\" name=\"__codelineno-57-7\" href=\"#__codelineno-57-7\"></a><span class=\"w\">        </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"nx\">balance</span>\n</span><span id=\"__span-57-8\"><a id=\"__codelineno-57-8\" name=\"__codelineno-57-8\" href=\"#__codelineno-57-8\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-57-9\"><a id=\"__codelineno-57-9\" name=\"__codelineno-57-9\" href=\"#__codelineno-57-9\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">/</span><span class=\"w\"> </span><span class=\"nb\">float64</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">balances</span><span class=\"p\">))</span>\n</span><span id=\"__span-57-10\"><a id=\"__codelineno-57-10\" name=\"__codelineno-57-10\" href=\"#__codelineno-57-10\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Another option, if the iteration operation isn’t lightweight, is to work on an actual copy of the data and protect only the copy:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-58-1\"><a id=\"__codelineno-58-1\" name=\"__codelineno-58-1\" href=\"#__codelineno-58-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">Cache</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"nx\">AverageBalance</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"kt\">float64</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-58-2\"><a id=\"__codelineno-58-2\" name=\"__codelineno-58-2\" href=\"#__codelineno-58-2\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">RLock</span><span class=\"p\">()</span>\n</span></span><span id=\"__span-58-3\"><a id=\"__codelineno-58-3\" name=\"__codelineno-58-3\" href=\"#__codelineno-58-3\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"nx\">m</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nb\">make</span><span class=\"p\">(</span><span class=\"kd\">map</span><span class=\"p\">[</span><span class=\"kt\">string</span><span class=\"p\">]</span><span class=\"kt\">float64</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">balances</span><span class=\"p\">))</span><span class=\"w\"> </span><span class=\"c1\">// Copies the map</span>\n</span></span><span id=\"__span-58-4\"><a id=\"__codelineno-58-4\" name=\"__codelineno-58-4\" href=\"#__codelineno-58-4\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">k</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">v</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">balances</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span></span><span id=\"__span-58-5\"><a id=\"__codelineno-58-5\" name=\"__codelineno-58-5\" href=\"#__codelineno-58-5\"></a><span class=\"hll\"><span class=\"w\">        </span><span class=\"nx\">m</span><span class=\"p\">[</span><span class=\"nx\">k</span><span class=\"p\">]</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">v</span>\n</span></span><span id=\"__span-58-6\"><a id=\"__codelineno-58-6\" name=\"__codelineno-58-6\" href=\"#__codelineno-58-6\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"p\">}</span>\n</span></span><span id=\"__span-58-7\"><a id=\"__codelineno-58-7\" name=\"__codelineno-58-7\" href=\"#__codelineno-58-7\"></a><span class=\"hll\"><span class=\"w\">    </span><span class=\"nx\">c</span><span class=\"p\">.</span><span class=\"nx\">mu</span><span class=\"p\">.</span><span class=\"nx\">RUnlock</span><span class=\"p\">()</span>\n</span></span><span id=\"__span-58-8\"><a id=\"__codelineno-58-8\" name=\"__codelineno-58-8\" href=\"#__codelineno-58-8\"></a>\n</span><span id=\"__span-58-9\"><a id=\"__codelineno-58-9\" name=\"__codelineno-58-9\" href=\"#__codelineno-58-9\"></a><span class=\"w\">    </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mf\">0.</span>\n</span><span id=\"__span-58-10\"><a id=\"__codelineno-58-10\" name=\"__codelineno-58-10\" href=\"#__codelineno-58-10\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">balance</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"k\">range</span><span class=\"w\"> </span><span class=\"nx\">m</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-58-11\"><a id=\"__codelineno-58-11\" name=\"__codelineno-58-11\" href=\"#__codelineno-58-11\"></a><span class=\"w\">        </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"nx\">balance</span>\n</span><span id=\"__span-58-12\"><a id=\"__codelineno-58-12\" name=\"__codelineno-58-12\" href=\"#__codelineno-58-12\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-58-13\"><a id=\"__codelineno-58-13\" name=\"__codelineno-58-13\" href=\"#__codelineno-58-13\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">sum</span><span class=\"w\"> </span><span class=\"o\">/</span><span class=\"w\"> </span><span class=\"nb\">float64</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"nx\">m</span><span class=\"p\">))</span>\n</span><span id=\"__span-58-14\"><a id=\"__codelineno-58-14\" name=\"__codelineno-58-14\" href=\"#__codelineno-58-14\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Once we have made a deep copy, we release the mutex. The iterations are done on the copy outside of the critical section.</p>\n<p>In summary, we have to be careful with the boundaries of a mutex lock. In this section, we have seen why assigning an existing map (or an existing slice) to a map isn’t enough to protect against data races. The new variable, whether a map or a slice, is backed by the same data set. There are two leading solutions to prevent this: protect the whole function, or work on a copy of the actual data. In all cases, let’s be cautious when designing critical sections and make sure the boundaries are accurately defined.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/70-mutex-slices-maps/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"uso-indevido-syncwaitgroup-71\">Uso indevido <code>sync.WaitGroup</code> (#71)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Para usar com precisão <code>sync.WaitGroup</code>, chame o método <code>Add</code> antes de ativar goroutines.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/71-wait-group/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"esquecendo-synccond-72\">Esquecendo <code>sync.Cond</code> (#72)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Você pode enviar notificações repetidas para vários goroutines com <code>sync.Cond</code>.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/72-cond/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-usando-errgroup-73\">Não usando <code>errgroup</code> (#73)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Você pode sincronizar um grupo de goroutines e lidar com erros e contextos com o pacote <code>errgroup</code>.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/73-errgroup/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"copiando-um-tipo-sync-74\">Copiando um tipo <code>sync</code> (#74)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Tipos <code>sync</code> não devem ser copiados.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/09-concurrency-practice/74-copying-sync/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h2 id=\"standard-library\">Standard Library</h2>\n<h3 id=\"fornecendo-uma-duracao-de-tempo-errada-75\">Fornecendo uma duração de tempo errada (#75)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Seja cauteloso com funções que aceitam um arquivo <code>time.Duration</code>. Mesmo que a passagem de um número inteiro seja permitida, tente usar a API time para evitar qualquer possível confusão.</p>\n</details>\n<p>Many common functions in the standard library accept a <code>time.Duration</code>, which is an alias for the <code>int64</code> type. However, one <code>time.Duration</code> unit represents one nanosecond, instead of one millisecond, as commonly seen in other programming languages. As a result, passing numeric types instead of using the <code>time.Duration</code> API can lead to unexpected behavior.</p>\n<p>A developer with experience in other languages might assume that the following code creates a new <code>time.Ticker</code> that delivers ticks every second, given the value <code>1000</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-59-1\"><a id=\"__codelineno-59-1\" name=\"__codelineno-59-1\" href=\"#__codelineno-59-1\"></a><span class=\"nx\">ticker</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">NewTicker</span><span class=\"p\">(</span><span class=\"mi\">1000</span><span class=\"p\">)</span>\n</span><span id=\"__span-59-2\"><a id=\"__codelineno-59-2\" name=\"__codelineno-59-2\" href=\"#__codelineno-59-2\"></a><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-59-3\"><a id=\"__codelineno-59-3\" name=\"__codelineno-59-3\" href=\"#__codelineno-59-3\"></a><span class=\"w\">    </span><span class=\"k\">select</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-59-4\"><a id=\"__codelineno-59-4\" name=\"__codelineno-59-4\" href=\"#__codelineno-59-4\"></a><span class=\"w\">    </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">ticker</span><span class=\"p\">.</span><span class=\"nx\">C</span><span class=\"p\">:</span>\n</span><span id=\"__span-59-5\"><a id=\"__codelineno-59-5\" name=\"__codelineno-59-5\" href=\"#__codelineno-59-5\"></a><span class=\"w\">        </span><span class=\"c1\">// Do something</span>\n</span><span id=\"__span-59-6\"><a id=\"__codelineno-59-6\" name=\"__codelineno-59-6\" href=\"#__codelineno-59-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-59-7\"><a id=\"__codelineno-59-7\" name=\"__codelineno-59-7\" href=\"#__codelineno-59-7\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>However, because 1,000 <code>time.Duration</code> units = 1,000 nanoseconds, ticks are delivered every 1,000 nanoseconds = 1 microsecond, not every second as assumed.</p>\n<p>We should always use the <code>time.Duration</code> API to avoid confusion and unexpected behavior:\n</p><div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-60-1\"><a id=\"__codelineno-60-1\" name=\"__codelineno-60-1\" href=\"#__codelineno-60-1\"></a><span class=\"nx\">ticker</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">NewTicker</span><span class=\"p\">(</span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">Microsecond</span><span class=\"p\">)</span>\n</span><span id=\"__span-60-2\"><a id=\"__codelineno-60-2\" name=\"__codelineno-60-2\" href=\"#__codelineno-60-2\"></a><span class=\"c1\">// Or</span>\n</span><span id=\"__span-60-3\"><a id=\"__codelineno-60-3\" name=\"__codelineno-60-3\" href=\"#__codelineno-60-3\"></a><span class=\"nx\">ticker</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">NewTicker</span><span class=\"p\">(</span><span class=\"mi\">1000</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"w\"> </span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">Nanosecond</span><span class=\"p\">)</span>\n</span></code></pre></div><p></p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/75-wrong-time-duration/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"timeafter-e-vazamentos-de-memoria-76\"><code>time.After</code> e vazamentos de memória (#76)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Evitar chamadas para funções <code>time.After</code> repetidas (como loops ou manipuladores HTTP) pode evitar pico de consumo de memória. Os recursos criados por <code>time.After</code> são liberados somente quando o cronômetro expira.</p>\n</details>\n<p>Developers often use <code>time.After</code> in loops or HTTP handlers repeatedly to implement the timing function. But it can lead to unintended peak memory consumption due to the delayed release of resources, just like the following code:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-61-1\"><a id=\"__codelineno-61-1\" name=\"__codelineno-61-1\" href=\"#__codelineno-61-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">consumer</span><span class=\"p\">(</span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"nx\">Event</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-61-2\"><a id=\"__codelineno-61-2\" name=\"__codelineno-61-2\" href=\"#__codelineno-61-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-61-3\"><a id=\"__codelineno-61-3\" name=\"__codelineno-61-3\" href=\"#__codelineno-61-3\"></a><span class=\"w\">        </span><span class=\"k\">select</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-61-4\"><a id=\"__codelineno-61-4\" name=\"__codelineno-61-4\" href=\"#__codelineno-61-4\"></a><span class=\"w\">        </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"nx\">event</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">ch</span><span class=\"p\">:</span>\n</span><span id=\"__span-61-5\"><a id=\"__codelineno-61-5\" name=\"__codelineno-61-5\" href=\"#__codelineno-61-5\"></a><span class=\"w\">            </span><span class=\"nx\">handle</span><span class=\"p\">(</span><span class=\"nx\">event</span><span class=\"p\">)</span>\n</span><span id=\"__span-61-6\"><a id=\"__codelineno-61-6\" name=\"__codelineno-61-6\" href=\"#__codelineno-61-6\"></a><span class=\"w\">        </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">After</span><span class=\"p\">(</span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">Hour</span><span class=\"p\">):</span>\n</span><span id=\"__span-61-7\"><a id=\"__codelineno-61-7\" name=\"__codelineno-61-7\" href=\"#__codelineno-61-7\"></a><span class=\"w\">            </span><span class=\"nx\">log</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"s\">\"warning: no messages received\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-61-8\"><a id=\"__codelineno-61-8\" name=\"__codelineno-61-8\" href=\"#__codelineno-61-8\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-61-9\"><a id=\"__codelineno-61-9\" name=\"__codelineno-61-9\" href=\"#__codelineno-61-9\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-61-10\"><a id=\"__codelineno-61-10\" name=\"__codelineno-61-10\" href=\"#__codelineno-61-10\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>The source code of the function time.After is as follows:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-62-1\"><a id=\"__codelineno-62-1\" name=\"__codelineno-62-1\" href=\"#__codelineno-62-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">After</span><span class=\"p\">(</span><span class=\"nx\">d</span><span class=\"w\"> </span><span class=\"nx\">Duration</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"nx\">Time</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-62-2\"><a id=\"__codelineno-62-2\" name=\"__codelineno-62-2\" href=\"#__codelineno-62-2\"></a><span class=\"w\">    </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"nx\">NewTimer</span><span class=\"p\">(</span><span class=\"nx\">d</span><span class=\"p\">).</span><span class=\"nx\">C</span>\n</span><span id=\"__span-62-3\"><a id=\"__codelineno-62-3\" name=\"__codelineno-62-3\" href=\"#__codelineno-62-3\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>As we see, it returns receive-only channel.</p>\n<p>When <code>time.After</code> is used in a loop or repeated context, a new channel is created in each iteration. If these channels are not properly closed or if their associated timers are not stopped, they can accumulate and consume memory. The resources associated with each timer and channel are only released when the timer expires or the channel is closed.</p>\n<p>To avoid this happening, We can use context's timeout setting instead of <code>time.After</code>, like below:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-63-1\"><a id=\"__codelineno-63-1\" name=\"__codelineno-63-1\" href=\"#__codelineno-63-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">consumer</span><span class=\"p\">(</span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"nx\">Event</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-63-2\"><a id=\"__codelineno-63-2\" name=\"__codelineno-63-2\" href=\"#__codelineno-63-2\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-63-3\"><a id=\"__codelineno-63-3\" name=\"__codelineno-63-3\" href=\"#__codelineno-63-3\"></a><span class=\"w\">        </span><span class=\"nx\">ctx</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">cancel</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">context</span><span class=\"p\">.</span><span class=\"nx\">WithTimeout</span><span class=\"p\">(</span><span class=\"nx\">context</span><span class=\"p\">.</span><span class=\"nx\">Background</span><span class=\"p\">(),</span><span class=\"w\"> </span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">Hour</span><span class=\"p\">)</span>\n</span><span id=\"__span-63-4\"><a id=\"__codelineno-63-4\" name=\"__codelineno-63-4\" href=\"#__codelineno-63-4\"></a><span class=\"w\">        </span><span class=\"k\">select</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-63-5\"><a id=\"__codelineno-63-5\" name=\"__codelineno-63-5\" href=\"#__codelineno-63-5\"></a><span class=\"w\">        </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"nx\">event</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">ch</span><span class=\"p\">:</span>\n</span><span id=\"__span-63-6\"><a id=\"__codelineno-63-6\" name=\"__codelineno-63-6\" href=\"#__codelineno-63-6\"></a><span class=\"w\">            </span><span class=\"nx\">cancel</span><span class=\"p\">()</span>\n</span><span id=\"__span-63-7\"><a id=\"__codelineno-63-7\" name=\"__codelineno-63-7\" href=\"#__codelineno-63-7\"></a><span class=\"w\">            </span><span class=\"nx\">handle</span><span class=\"p\">(</span><span class=\"nx\">event</span><span class=\"p\">)</span>\n</span><span id=\"__span-63-8\"><a id=\"__codelineno-63-8\" name=\"__codelineno-63-8\" href=\"#__codelineno-63-8\"></a><span class=\"w\">        </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">ctx</span><span class=\"p\">.</span><span class=\"nx\">Done</span><span class=\"p\">():</span>\n</span><span id=\"__span-63-9\"><a id=\"__codelineno-63-9\" name=\"__codelineno-63-9\" href=\"#__codelineno-63-9\"></a><span class=\"w\">            </span><span class=\"nx\">log</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"s\">\"warning: no messages received\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-63-10\"><a id=\"__codelineno-63-10\" name=\"__codelineno-63-10\" href=\"#__codelineno-63-10\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-63-11\"><a id=\"__codelineno-63-11\" name=\"__codelineno-63-11\" href=\"#__codelineno-63-11\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-63-12\"><a id=\"__codelineno-63-12\" name=\"__codelineno-63-12\" href=\"#__codelineno-63-12\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>We can also use <code>time.NewTimer</code> like so:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-64-1\"><a id=\"__codelineno-64-1\" name=\"__codelineno-64-1\" href=\"#__codelineno-64-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">consumer</span><span class=\"p\">(</span><span class=\"nx\">ch</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"kd\">chan</span><span class=\"w\"> </span><span class=\"nx\">Event</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-64-2\"><a id=\"__codelineno-64-2\" name=\"__codelineno-64-2\" href=\"#__codelineno-64-2\"></a><span class=\"w\">    </span><span class=\"nx\">timerDuration</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"w\"> </span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">Hour</span>\n</span><span id=\"__span-64-3\"><a id=\"__codelineno-64-3\" name=\"__codelineno-64-3\" href=\"#__codelineno-64-3\"></a><span class=\"w\">    </span><span class=\"nx\">timer</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">time</span><span class=\"p\">.</span><span class=\"nx\">NewTimer</span><span class=\"p\">(</span><span class=\"nx\">timerDuration</span><span class=\"p\">)</span>\n</span><span id=\"__span-64-4\"><a id=\"__codelineno-64-4\" name=\"__codelineno-64-4\" href=\"#__codelineno-64-4\"></a>\n</span><span id=\"__span-64-5\"><a id=\"__codelineno-64-5\" name=\"__codelineno-64-5\" href=\"#__codelineno-64-5\"></a><span class=\"w\">    </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-64-6\"><a id=\"__codelineno-64-6\" name=\"__codelineno-64-6\" href=\"#__codelineno-64-6\"></a><span class=\"w\">        </span><span class=\"nx\">timer</span><span class=\"p\">.</span><span class=\"nx\">Reset</span><span class=\"p\">(</span><span class=\"nx\">timerDuration</span><span class=\"p\">)</span>\n</span><span id=\"__span-64-7\"><a id=\"__codelineno-64-7\" name=\"__codelineno-64-7\" href=\"#__codelineno-64-7\"></a><span class=\"w\">        </span><span class=\"k\">select</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-64-8\"><a id=\"__codelineno-64-8\" name=\"__codelineno-64-8\" href=\"#__codelineno-64-8\"></a><span class=\"w\">        </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"nx\">event</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">ch</span><span class=\"p\">:</span>\n</span><span id=\"__span-64-9\"><a id=\"__codelineno-64-9\" name=\"__codelineno-64-9\" href=\"#__codelineno-64-9\"></a><span class=\"w\">            </span><span class=\"nx\">handle</span><span class=\"p\">(</span><span class=\"nx\">event</span><span class=\"p\">)</span>\n</span><span id=\"__span-64-10\"><a id=\"__codelineno-64-10\" name=\"__codelineno-64-10\" href=\"#__codelineno-64-10\"></a><span class=\"w\">        </span><span class=\"k\">case</span><span class=\"w\"> </span><span class=\"o\">&lt;-</span><span class=\"nx\">timer</span><span class=\"p\">.</span><span class=\"nx\">C</span><span class=\"p\">:</span>\n</span><span id=\"__span-64-11\"><a id=\"__codelineno-64-11\" name=\"__codelineno-64-11\" href=\"#__codelineno-64-11\"></a><span class=\"w\">            </span><span class=\"nx\">log</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"s\">\"warning: no messages received\"</span><span class=\"p\">)</span>\n</span><span id=\"__span-64-12\"><a id=\"__codelineno-64-12\" name=\"__codelineno-64-12\" href=\"#__codelineno-64-12\"></a><span class=\"w\">        </span><span class=\"p\">}</span>\n</span><span id=\"__span-64-13\"><a id=\"__codelineno-64-13\" name=\"__codelineno-64-13\" href=\"#__codelineno-64-13\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-64-14\"><a id=\"__codelineno-64-14\" name=\"__codelineno-64-14\" href=\"#__codelineno-64-14\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/76-time-after/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"lidando-com-erros-comuns-json-77\">Lidando com erros comuns JSON (#77)</h3>\n<ul>\n<li>Comportamento inesperado devido à incorporação de tipo</li>\n</ul>\n<p>Tenha cuidado ao usar campos incorporados em estruturas Go. Fazer isso pode levar a bugs sorrateiros, como um campo time.Time incorporado que implementa a interface <code>json.Marshaler</code>, substituindo assim o comportamento de empacotamento padrão.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/type-embedding/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<ul>\n<li>JSON e o relógio monotônico</li>\n</ul>\n<p>Ao comparar duas estruturas <code>time.Time</code>, lembre-se de que <code>time.Time</code> contém um relógio de parede e um relógio monotônico, e a comparação usando o operador == é feita em ambos os relógios.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/monotonic-clock/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<ul>\n<li>Map de <code>any</code></li>\n</ul>\n<p>Para evitar suposições erradas ao fornecer um map ao desempacotar (unmarshaling) dados JSON, lembre-se de que os valores numéricos são convertidos para <code>float64</code> por padrão.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/77-json-handling/map-any/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"erros-comuns-de-sql-78\">Erros comuns de SQL (#78)</h3>\n<ul>\n<li>Esquecer <code>sql.Open</code> não necessariamente estabelece conexões com um banco de dados</li>\n</ul>\n<p>Esquecer <code>sql.Open</code> não necessariamente estabelece conexões com um banco de dados\n  Chame o método <code>Ping</code> ou <code>PingContext</code> se precisar testar sua configuração e garantir que um banco de dados esteja acessível.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/sql-open\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<ul>\n<li>Esquecendo o pool de conexões</li>\n</ul>\n<p>Configure os parâmetros de conexão do banco de dados para aplicativos de nível de produção.</p>\n<ul>\n<li>Não usar declarações preparadas</li>\n</ul>\n<p>O uso de instruções preparadas em SQL torna as consultas mais eficientes e seguras.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/prepared-statements\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<ul>\n<li>Tratamento incorreto de valores nulos</li>\n</ul>\n<p>Lide com colunas anuláveis ​​em tabelas usando ponteiros ou tipos <code>sql.NullXXX</code>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/null-values/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<ul>\n<li>Não tratando de erros de iteração de linhas</li>\n</ul>\n<p>Chame o método <code>Err</code> de <code>sql.Rows</code> iterações posteriores à linha para garantir que você não perdeu nenhum erro ao preparar a próxima linha.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/78-sql/rows-iterations-errors\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-fechando-recursos-transitorios-body-http-sqlrows-e-osfile-79\">Não fechando recursos transitórios (body HTTP, <code>sql.Rows</code> e <code>os.File</code>) (#79)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Eventualmente feche todas as estruturas implementadas <code>io.Closer</code> para evitar possíveis vazamentos.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/79-closing-resources/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"esquecendo-a-instrucao-return-apos-responder-a-uma-solicitacao-http-80\">Esquecendo a instrução return após responder a uma solicitação HTTP (#80)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Para evitar comportamentos inesperados nas implementações do manipulador HTTP, certifique-se de não perder a instrução <code>return</code> se quiser que um manipulador pare após <code>http.Error</code>.</p>\n</details>\n<p>Consider the following HTTP handler that handles an error from <code>foo</code> using <code>http.Error</code>:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-65-1\"><a id=\"__codelineno-65-1\" name=\"__codelineno-65-1\" href=\"#__codelineno-65-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">handler</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">ResponseWriter</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">req</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Request</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-65-2\"><a id=\"__codelineno-65-2\" name=\"__codelineno-65-2\" href=\"#__codelineno-65-2\"></a><span class=\"w\">    </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">foo</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">)</span>\n</span><span id=\"__span-65-3\"><a id=\"__codelineno-65-3\" name=\"__codelineno-65-3\" href=\"#__codelineno-65-3\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-65-4\"><a id=\"__codelineno-65-4\" name=\"__codelineno-65-4\" href=\"#__codelineno-65-4\"></a><span class=\"w\">        </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Error</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s\">\"foo\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">StatusInternalServerError</span><span class=\"p\">)</span>\n</span><span id=\"__span-65-5\"><a id=\"__codelineno-65-5\" name=\"__codelineno-65-5\" href=\"#__codelineno-65-5\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-65-6\"><a id=\"__codelineno-65-6\" name=\"__codelineno-65-6\" href=\"#__codelineno-65-6\"></a>\n</span><span id=\"__span-65-7\"><a id=\"__codelineno-65-7\" name=\"__codelineno-65-7\" href=\"#__codelineno-65-7\"></a><span class=\"w\">    </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">Write</span><span class=\"p\">([]</span><span class=\"nb\">byte</span><span class=\"p\">(</span><span class=\"s\">\"all good\"</span><span class=\"p\">))</span>\n</span><span id=\"__span-65-8\"><a id=\"__codelineno-65-8\" name=\"__codelineno-65-8\" href=\"#__codelineno-65-8\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">WriteHeader</span><span class=\"p\">(</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">StatusCreated</span><span class=\"p\">)</span>\n</span><span id=\"__span-65-9\"><a id=\"__codelineno-65-9\" name=\"__codelineno-65-9\" href=\"#__codelineno-65-9\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>If we run this code and <code>err != nil</code>, the HTTP response would be:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-66-1\"><a id=\"__codelineno-66-1\" name=\"__codelineno-66-1\" href=\"#__codelineno-66-1\"></a>foo\n</span><span id=\"__span-66-2\"><a id=\"__codelineno-66-2\" name=\"__codelineno-66-2\" href=\"#__codelineno-66-2\"></a>all good\n</span></code></pre></div>\n<p>The response contains both the error and success messages, and also the first HTTP status code, 500. There would also be a warning log indicating that we attempted to write the status code multiple times:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-67-1\"><a id=\"__codelineno-67-1\" name=\"__codelineno-67-1\" href=\"#__codelineno-67-1\"></a>2023/10/10 16:45:33 http: superfluous response.WriteHeader call from main.handler (main.go:20)\n</span></code></pre></div>\n<p>The mistake in this code is that <code>http.Error</code> does not stop the handler's execution, which means the success message and status code get written in addition to the error. Beyond an incorrect response, failing to return after writing an error can lead to the unwanted execution of code and unexpected side-effects. The following code adds the <code>return</code> statement following the <code>http.Error</code> and exhibits the desired behavior when ran:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-68-1\"><a id=\"__codelineno-68-1\" name=\"__codelineno-68-1\" href=\"#__codelineno-68-1\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">handler</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"w\"> </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">ResponseWriter</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">req</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Request</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-68-2\"><a id=\"__codelineno-68-2\" name=\"__codelineno-68-2\" href=\"#__codelineno-68-2\"></a><span class=\"w\">    </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"nx\">foo</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">)</span>\n</span><span id=\"__span-68-3\"><a id=\"__codelineno-68-3\" name=\"__codelineno-68-3\" href=\"#__codelineno-68-3\"></a><span class=\"w\">    </span><span class=\"k\">if</span><span class=\"w\"> </span><span class=\"nx\">err</span><span class=\"w\"> </span><span class=\"o\">!=</span><span class=\"w\"> </span><span class=\"kc\">nil</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-68-4\"><a id=\"__codelineno-68-4\" name=\"__codelineno-68-4\" href=\"#__codelineno-68-4\"></a><span class=\"w\">        </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">Error</span><span class=\"p\">(</span><span class=\"nx\">w</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s\">\"foo\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">StatusInternalServerError</span><span class=\"p\">)</span>\n</span><span id=\"__span-68-5\"><a id=\"__codelineno-68-5\" name=\"__codelineno-68-5\" href=\"#__codelineno-68-5\"></a><span class=\"w\">        </span><span class=\"k\">return</span><span class=\"w\"> </span><span class=\"c1\">// Adds the return statement</span>\n</span><span id=\"__span-68-6\"><a id=\"__codelineno-68-6\" name=\"__codelineno-68-6\" href=\"#__codelineno-68-6\"></a><span class=\"w\">    </span><span class=\"p\">}</span>\n</span><span id=\"__span-68-7\"><a id=\"__codelineno-68-7\" name=\"__codelineno-68-7\" href=\"#__codelineno-68-7\"></a>\n</span><span id=\"__span-68-8\"><a id=\"__codelineno-68-8\" name=\"__codelineno-68-8\" href=\"#__codelineno-68-8\"></a><span class=\"w\">    </span><span class=\"nx\">_</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"nx\">_</span><span class=\"w\"> </span><span class=\"p\">=</span><span class=\"w\"> </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">Write</span><span class=\"p\">([]</span><span class=\"nb\">byte</span><span class=\"p\">(</span><span class=\"s\">\"all good\"</span><span class=\"p\">))</span>\n</span><span id=\"__span-68-9\"><a id=\"__codelineno-68-9\" name=\"__codelineno-68-9\" href=\"#__codelineno-68-9\"></a><span class=\"w\">    </span><span class=\"nx\">w</span><span class=\"p\">.</span><span class=\"nx\">WriteHeader</span><span class=\"p\">(</span><span class=\"nx\">http</span><span class=\"p\">.</span><span class=\"nx\">StatusCreated</span><span class=\"p\">)</span>\n</span><span id=\"__span-68-10\"><a id=\"__codelineno-68-10\" name=\"__codelineno-68-10\" href=\"#__codelineno-68-10\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/80-http-return/main.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"usando-o-cliente-e-servidor-http-padrao-81\">Usando o cliente e servidor HTTP padrão (#81)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Para aplicativos de nível de produção, não use as implementações de cliente e servidor HTTP padrão. Essas implementações não possuem tempos limite e comportamentos que deveriam ser obrigatórios na produção.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/10-standard-lib/81-default-http-client-server/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h2 id=\"teste\">Teste</h2>\n<h3 id=\"nao-categorizar-testes-tags-de-construcao-variaveis-de-ambiente-e-modo-abreviado-82\">Não categorizar testes (tags de construção, variáveis ​​de ambiente e modo abreviado) (#82)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Categorizar testes usando sinalizadores de construção, variáveis ​​de ambiente ou modo curto torna o processo de teste mais eficiente. Você pode criar categorias de teste usando sinalizadores de construção ou variáveis ​​de ambiente (por exemplo, testes de unidade versus testes de integração) e diferenciar testes curtos de testes de longa duração para decidir quais tipos de testes executar.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/82-categorizing-tests/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-habilitando-a-bandeira-de-corrida-83\">Não habilitando a bandeira de corrida (#83)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>A ativação do sinalizador <code>-race</code> é altamente recomendada ao escrever aplicativos simultâneos. Isso permite que você detecte possíveis corridas de dados que podem levar a bugs de software.</p>\n</details>\n<p>In Go, the race detector isn’t a static analysis tool used during compilation; instead, it’s a tool to find data races that occur at runtime. To enable it, we have to enable the -race flag while compiling or running a test. For example:</p>\n<div class=\"language-bash highlight\"><pre><span></span><code><span id=\"__span-69-1\"><a id=\"__codelineno-69-1\" name=\"__codelineno-69-1\" href=\"#__codelineno-69-1\"></a>go<span class=\"w\"> </span><span class=\"nb\">test</span><span class=\"w\"> </span>-race<span class=\"w\"> </span>./...\n</span></code></pre></div>\n<p>Once the race detector is enabled, the compiler instruments the code to detect data races. Instrumentation refers to a compiler adding extra instructions: here, tracking all memory accesses and recording when and how they occur.</p>\n<p>Enabling the race detector adds an overhead in terms of memory and execution time; hence, it's generally recommended to enable it only during local testing or continuous integration, not production.</p>\n<p>If a race is detected, Go raises a warning. For example:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-70-1\"><a id=\"__codelineno-70-1\" name=\"__codelineno-70-1\" href=\"#__codelineno-70-1\"></a><span class=\"kn\">package</span><span class=\"w\"> </span><span class=\"nx\">main</span>\n</span><span id=\"__span-70-2\"><a id=\"__codelineno-70-2\" name=\"__codelineno-70-2\" href=\"#__codelineno-70-2\"></a>\n</span><span id=\"__span-70-3\"><a id=\"__codelineno-70-3\" name=\"__codelineno-70-3\" href=\"#__codelineno-70-3\"></a><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"p\">(</span>\n</span><span id=\"__span-70-4\"><a id=\"__codelineno-70-4\" name=\"__codelineno-70-4\" href=\"#__codelineno-70-4\"></a><span class=\"w\">    </span><span class=\"s\">\"fmt\"</span>\n</span><span id=\"__span-70-5\"><a id=\"__codelineno-70-5\" name=\"__codelineno-70-5\" href=\"#__codelineno-70-5\"></a><span class=\"p\">)</span>\n</span><span id=\"__span-70-6\"><a id=\"__codelineno-70-6\" name=\"__codelineno-70-6\" href=\"#__codelineno-70-6\"></a>\n</span><span id=\"__span-70-7\"><a id=\"__codelineno-70-7\" name=\"__codelineno-70-7\" href=\"#__codelineno-70-7\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">main</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-70-8\"><a id=\"__codelineno-70-8\" name=\"__codelineno-70-8\" href=\"#__codelineno-70-8\"></a><span class=\"w\">    </span><span class=\"nx\">i</span><span class=\"w\"> </span><span class=\"o\">:=</span><span class=\"w\"> </span><span class=\"mi\">0</span>\n</span><span id=\"__span-70-9\"><a id=\"__codelineno-70-9\" name=\"__codelineno-70-9\" href=\"#__codelineno-70-9\"></a><span class=\"w\">    </span><span class=\"k\">go</span><span class=\"w\"> </span><span class=\"kd\">func</span><span class=\"p\">()</span><span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"> </span><span class=\"nx\">i</span><span class=\"o\">++</span><span class=\"w\"> </span><span class=\"p\">}()</span>\n</span><span id=\"__span-70-10\"><a id=\"__codelineno-70-10\" name=\"__codelineno-70-10\" href=\"#__codelineno-70-10\"></a><span class=\"w\">    </span><span class=\"nx\">fmt</span><span class=\"p\">.</span><span class=\"nx\">Println</span><span class=\"p\">(</span><span class=\"nx\">i</span><span class=\"p\">)</span>\n</span><span id=\"__span-70-11\"><a id=\"__codelineno-70-11\" name=\"__codelineno-70-11\" href=\"#__codelineno-70-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<p>Runnig this code with the <code>-race</code> logs the following warning:</p>\n<div class=\"language-bash highlight\"><pre><span></span><code><span id=\"__span-71-1\"><a id=\"__codelineno-71-1\" name=\"__codelineno-71-1\" href=\"#__codelineno-71-1\"></a><span class=\"o\">==================</span>\n</span><span id=\"__span-71-2\"><a id=\"__codelineno-71-2\" name=\"__codelineno-71-2\" href=\"#__codelineno-71-2\"></a>WARNING:<span class=\"w\"> </span>DATA<span class=\"w\"> </span>RACE\n</span><span id=\"__span-71-3\"><a id=\"__codelineno-71-3\" name=\"__codelineno-71-3\" href=\"#__codelineno-71-3\"></a><span class=\"hll\">Write<span class=\"w\"> </span>at<span class=\"w\"> </span>0x00c000026078<span class=\"w\"> </span>by<span class=\"w\"> </span>goroutine<span class=\"w\"> </span><span class=\"m\">7</span>:<span class=\"w\"> </span><span class=\"c1\"># (1)</span>\n</span></span><span id=\"__span-71-4\"><a id=\"__codelineno-71-4\" name=\"__codelineno-71-4\" href=\"#__codelineno-71-4\"></a><span class=\"w\">  </span>main.main.func1<span class=\"o\">()</span>\n</span><span id=\"__span-71-5\"><a id=\"__codelineno-71-5\" name=\"__codelineno-71-5\" href=\"#__codelineno-71-5\"></a><span class=\"w\">      </span>/tmp/app/main.go:9<span class=\"w\"> </span>+0x4e\n</span><span id=\"__span-71-6\"><a id=\"__codelineno-71-6\" name=\"__codelineno-71-6\" href=\"#__codelineno-71-6\"></a>\n</span><span id=\"__span-71-7\"><a id=\"__codelineno-71-7\" name=\"__codelineno-71-7\" href=\"#__codelineno-71-7\"></a><span class=\"hll\">Previous<span class=\"w\"> </span><span class=\"nb\">read</span><span class=\"w\"> </span>at<span class=\"w\"> </span>0x00c000026078<span class=\"w\"> </span>by<span class=\"w\"> </span>main<span class=\"w\"> </span>goroutine:<span class=\"w\"> </span><span class=\"c1\"># (2)</span>\n</span></span><span id=\"__span-71-8\"><a id=\"__codelineno-71-8\" name=\"__codelineno-71-8\" href=\"#__codelineno-71-8\"></a><span class=\"w\">  </span>main.main<span class=\"o\">()</span>\n</span><span id=\"__span-71-9\"><a id=\"__codelineno-71-9\" name=\"__codelineno-71-9\" href=\"#__codelineno-71-9\"></a><span class=\"w\">      </span>/tmp/app/main.go:10<span class=\"w\"> </span>+0x88\n</span><span id=\"__span-71-10\"><a id=\"__codelineno-71-10\" name=\"__codelineno-71-10\" href=\"#__codelineno-71-10\"></a>\n</span><span id=\"__span-71-11\"><a id=\"__codelineno-71-11\" name=\"__codelineno-71-11\" href=\"#__codelineno-71-11\"></a><span class=\"hll\">Goroutine<span class=\"w\"> </span><span class=\"m\">7</span><span class=\"w\"> </span><span class=\"o\">(</span>running<span class=\"o\">)</span><span class=\"w\"> </span>created<span class=\"w\"> </span>at:<span class=\"w\"> </span><span class=\"c1\"># (3)</span>\n</span></span><span id=\"__span-71-12\"><a id=\"__codelineno-71-12\" name=\"__codelineno-71-12\" href=\"#__codelineno-71-12\"></a><span class=\"w\">  </span>main.main<span class=\"o\">()</span>\n</span><span id=\"__span-71-13\"><a id=\"__codelineno-71-13\" name=\"__codelineno-71-13\" href=\"#__codelineno-71-13\"></a><span class=\"w\">      </span>/tmp/app/main.go:9<span class=\"w\"> </span>+0x7a\n</span><span id=\"__span-71-14\"><a id=\"__codelineno-71-14\" name=\"__codelineno-71-14\" href=\"#__codelineno-71-14\"></a><span class=\"o\">==================</span>\n</span></code></pre></div>\n<ol>\n<li>Indicates that goroutine 7 was writing</li>\n<li>Indicates that the main goroutine was reading</li>\n<li>Indicates when the goroutine 7 was created</li>\n</ol>\n<p>Let’s make sure we are comfortable reading these messages. Go always logs the following:</p>\n<ul>\n<li>The concurrent goroutines that are incriminated: here, the main goroutine and goroutine 7.</li>\n<li>Where accesses occur in the code: in this case, lines 9 and 10.</li>\n<li>When these goroutines were created: goroutine 7 was created in main().</li>\n</ul>\n<p>In addition, if a specific file contains tests that lead to data races, we can exclude it <span class=\"twemoji\" title=\"temporarily! 😉\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M11 9h2V7h-2m1 13c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8m0-18A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m-1 15h2v-6h-2z\"></path></svg></span> from race detection using the <code>!race</code> build tag:</p>\n<div class=\"language-go highlight\"><pre><span></span><code><span id=\"__span-72-1\"><a id=\"__codelineno-72-1\" name=\"__codelineno-72-1\" href=\"#__codelineno-72-1\"></a><span class=\"c1\">//go:build !race</span>\n</span><span id=\"__span-72-2\"><a id=\"__codelineno-72-2\" name=\"__codelineno-72-2\" href=\"#__codelineno-72-2\"></a>\n</span><span id=\"__span-72-3\"><a id=\"__codelineno-72-3\" name=\"__codelineno-72-3\" href=\"#__codelineno-72-3\"></a><span class=\"kn\">package</span><span class=\"w\"> </span><span class=\"nx\">main</span>\n</span><span id=\"__span-72-4\"><a id=\"__codelineno-72-4\" name=\"__codelineno-72-4\" href=\"#__codelineno-72-4\"></a>\n</span><span id=\"__span-72-5\"><a id=\"__codelineno-72-5\" name=\"__codelineno-72-5\" href=\"#__codelineno-72-5\"></a><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"p\">(</span>\n</span><span id=\"__span-72-6\"><a id=\"__codelineno-72-6\" name=\"__codelineno-72-6\" href=\"#__codelineno-72-6\"></a><span class=\"w\">    </span><span class=\"s\">\"testing\"</span>\n</span><span id=\"__span-72-7\"><a id=\"__codelineno-72-7\" name=\"__codelineno-72-7\" href=\"#__codelineno-72-7\"></a><span class=\"p\">)</span>\n</span><span id=\"__span-72-8\"><a id=\"__codelineno-72-8\" name=\"__codelineno-72-8\" href=\"#__codelineno-72-8\"></a>\n</span><span id=\"__span-72-9\"><a id=\"__codelineno-72-9\" name=\"__codelineno-72-9\" href=\"#__codelineno-72-9\"></a><span class=\"kd\">func</span><span class=\"w\"> </span><span class=\"nx\">TestFoo</span><span class=\"p\">(</span><span class=\"nx\">t</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"nx\">testing</span><span class=\"p\">.</span><span class=\"nx\">T</span><span class=\"p\">)</span><span class=\"w\"> </span><span class=\"p\">{</span>\n</span><span id=\"__span-72-10\"><a id=\"__codelineno-72-10\" name=\"__codelineno-72-10\" href=\"#__codelineno-72-10\"></a><span class=\"w\">    </span><span class=\"c1\">// ...</span>\n</span><span id=\"__span-72-11\"><a id=\"__codelineno-72-11\" name=\"__codelineno-72-11\" href=\"#__codelineno-72-11\"></a><span class=\"p\">}</span>\n</span></code></pre></div>\n<h3 id=\"nao-usar-modos-de-execucao-de-teste-paralelo-e-aleatorio-84\">Não usar modos de execução de teste (paralelo e aleatório) (#84)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Usar o sinalizador <code>-parallel</code> é uma forma eficiente de acelerar testes, especialmente os de longa duração. Use o sinalizador <code>-shuffle</code> para ajudar a garantir que um conjunto de testes não se baseie em suposições erradas que possam ocultar bugs.</p>\n</details>\n<h3 id=\"nao-usar-testes-baseados-em-tabela-85\">Não usar testes baseados em tabela (#85)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Os testes baseados em tabelas são uma maneira eficiente de agrupar um conjunto de testes semelhantes para evitar a duplicação de código e facilitar o manuseio de atualizações futuras.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/85-table-driven-tests/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"dormindo-em-testes-unitarios-86\">Dormindo em testes unitários (#86)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Evite interrupções usando a sincronização para tornar o teste menos instável e mais robusto. Se a sincronização não for possível, considere uma abordagem de nova tentativa.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/86-sleeping/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-lidar-com-a-api-de-tempo-de-forma-eficiente-87\">Não lidar com a API de tempo de forma eficiente (#87)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Entender como lidar com funções usando a API time é outra maneira de tornar um teste menos complicado. Você pode usar técnicas padrão, como lidar com o tempo como parte de uma dependência oculta ou solicitar que os clientes o forneçam.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/87-time-api/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-usar-pacotes-de-utilitarios-de-teste-httptest-e-iotest-88\">Não usar pacotes de utilitários de teste ( <code>httptest</code> e <code>iotest</code>) (#88)</h3>\n<ul>\n<li>O pacote <code>httptest</code> é útil para lidar com aplicativos HTTP. Ele fornece um conjunto de utilitários para testar clientes e servidores.</li>\n</ul>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/88-utility-package/httptest/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<ul>\n<li>O pacote <code>iotest</code> ajuda a escrever io.Reader e testar se um aplicativo é tolerante a erros.</li>\n</ul>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/88-utility-package/iotest/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"escrevendo-benchmarks-imprecisos-89\">Escrevendo benchmarks imprecisos (#89)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Regarding benchmarks:</p>\n<ul>\n<li>Use métodos de tempo para preservar a precisão de um benchmark.</li>\n<li>Aumentar o tempo de teste ou usar ferramentas como o benchstat pode ser útil ao lidar com micro-benchmarks.</li>\n<li>Tenha cuidado com os resultados de um micro-benchmark se o sistema que executa o aplicativo for diferente daquele que executa o micro-benchmark.</li>\n<li>Certifique-se de que a função em teste cause um efeito colateral, para evitar que as otimizações do compilador enganem você sobre os resultados do benchmark.</li>\n<li>Para evitar o efeito observador, force um benchmark a recriar os dados usados ​​por uma função vinculada à CPU.</li>\n</ul>\n</details>\n<p>Leia a seção completa <a href=\"../89-benchmarks/\">aqui</a>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/89-benchmark/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-explorando-todos-os-recursos-de-teste-do-go-90\">Não explorando todos os recursos de teste do Go (#90)</h3>\n<ul>\n<li>Cobertura de código</li>\n</ul>\n<p>Use a cobertura de código com o sinalizador <code>-coverprofile</code> para ver rapidamente qual parte do código precisa de mais atenção.</p>\n<ul>\n<li>Testando de um pacote diferente</li>\n</ul>\n<p>Coloque os testes unitários em um pacote diferente para impor testes de escrita que se concentrem em um comportamento exposto, não em internos.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/different-package/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<ul>\n<li>Funções utilitárias</li>\n</ul>\n<p>O tratamento de erros usando a variável <code>*testing.T</code> em vez do clássico <code>if err != nil</code> torna o código mais curto e fácil de ler.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/utility-function/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<ul>\n<li>Configuração e desmontagem</li>\n</ul>\n<p>Você pode usar funções de setup e teardown para configurar um ambiente complexo, como no caso de testes de integração.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/11-testing/90-testing-features/setup-teardown/main_test.go\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-usar-fuzzing-erro-da-comunidade\">Não usar fuzzing (erro da comunidade)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Fuzzing é uma estratégia eficiente para detectar entradas aleatórias, inesperadas ou malformadas em funções e métodos complexos, a fim de descobrir vulnerabilidades, bugs ou até mesmo travamentos potenciais.</p>\n</details>\n<p>Credits: <a href=\"https://github.com/jeromedoucet\">@jeromedoucet</a></p>\n<h2 id=\"otimizacoes\">Otimizações</h2>\n<h3 id=\"nao-entendendo-os-caches-da-cpu-91\">Não entendendo os caches da CPU (#91)</h3>\n<ul>\n<li>Arquitetura da CPU</li>\n</ul>\n<p>Compreender como usar caches de CPU é importante para otimizar aplicativos vinculados à CPU porque o cache L1 é cerca de 50 a 100 vezes mais rápido que a memória principal.</p>\n<ul>\n<li>Linha de cache</li>\n</ul>\n<p>Estar consciente do conceito de linha de cache é fundamental para entender como organizar dados em aplicativos com uso intensivo de dados. Uma CPU não busca memória palavra por palavra; em vez disso, geralmente copia um bloco de memória para uma linha de cache de 64 bytes. Para aproveitar ao máximo cada linha de cache individual, imponha a localidade espacial.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/cache-line/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<ul>\n<li>Slice de estruturas vs. estrutura de slices</li>\n</ul>\n<!-- TODO -->\n\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/slice-structs/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<ul>\n<li>Previsibilidade</li>\n</ul>\n<p>Tornar o código previsível para a CPU também pode ser uma forma eficiente de otimizar certas funções. Por exemplo, uma passada unitária ou constante é previsível para a CPU, mas uma passada não unitária (por exemplo, uma lista vinculada) não é previsível.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/91-cpu-caches/predictability/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<ul>\n<li>Política de posicionamento de cache</li>\n</ul>\n<p>Para evitar um avanço crítico e, portanto, utilizar apenas uma pequena parte do cache, esteja ciente de que os caches são particionados.</p>\n<h3 id=\"escrevendo-codigo-simultaneo-que-leva-a-compartilhamento-falso-92\">Escrevendo código simultâneo que leva a compartilhamento falso (#92)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Saber que níveis mais baixos de caches de CPU não são compartilhados entre todos os núcleos ajuda a evitar padrões que degradam o desempenho, como compartilhamento falso ao escrever código de simultaneidade. Compartilhar memória é uma ilusão.</p>\n</details>\n<p>Leia a seção completa <a href=\"../92-false-sharing/\">aqui</a>.</p>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/92-false-sharing/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-levando-em-consideracao-o-paralelismo-no-nivel-de-instrucao-93\">Não levando em consideração o paralelismo no nível de instrução (#93)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Use o <abbr title=\"Instruction-Level Parallelism\">ILP</abbr> para otimizar partes específicas do seu código para permitir que uma CPU execute tantas instruções paralelas quanto possível. Identificar perigos nos dados é uma das etapas principais.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/93-instruction-level-parallelism/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-estar-ciente-do-alinhamento-dos-dados-94\">Não estar ciente do alinhamento dos dados (#94)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Você pode evitar erros comuns lembrando que no Go os tipos básicos são alinhados com seu próprio tamanho. Por exemplo, tenha em mente que reorganizar os campos de uma estrutura por tamanho em ordem decrescente pode levar a estruturas mais compactas (menos alocação de memória e potencialmente uma melhor localidade espacial).</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/94-data-alignment/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-entendendo-stack-vs-heap-95\">Não entendendo stack vs. heap (#95)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Compreender as diferenças fundamentais entre heap e pilha também deve fazer parte do seu conhecimento básico ao otimizar um aplicativo Go. As alocações de pilha são quase gratuitas, enquanto as alocações de heap são mais lentas e dependem do <abbr title=\"Garbage Collector\">GC</abbr> para limpar a memória.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/95-stack-heap/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-saber-como-reduzir-alocacoes-mudanca-de-api-otimizacoes-de-compilador-e-syncpool-96\">Não saber como reduzir alocações (mudança de API, otimizações de compilador e <code>sync.Pool</code>) (#96)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>A redução das alocações também é um aspecto essencial da otimização de um aplicativo Go. Isso pode ser feito de diferentes maneiras, como projetar a API cuidadosamente para evitar compartilhamento, compreender as otimizações comuns do compilador Go e usar <code>sync.Pool</code>.</p>\n</details>\n<p><a href=\"https://github.com/teivah/100-go-mistakes/tree/master/src/12-optimizations/96-reduce-allocations/\"><span class=\"twemoji\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"></path></svg></span> Código fonte</a></p>\n<h3 id=\"nao-dependendo-do-inlining-97\">Não dependendo do inlining (#97)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Use a técnica de inlining de caminho rápido para reduzir com eficiência o tempo amortizado para chamar uma função.</p>\n</details>\n<h3 id=\"nao-usar-ferramentas-de-diagnostico-go-98\">Não usar ferramentas de diagnóstico Go (#98)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Confie na criação de perfil e no rastreador de execução para entender o desempenho de um aplicativo e as partes a serem otimizadas.</p>\n</details>\n<p>Leia a seção completa <a href=\"../98-profiling-execution-tracing/\">aqui</a>.</p>\n<h3 id=\"nao-entendendo-como-funciona-o-gc-99\">Não entendendo como funciona o <abbr title=\"Garbage Collector\">GC</abbr> (#99)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Compreender como ajustar o <abbr title=\"Garbage Collector\">GC</abbr> pode levar a vários benefícios, como lidar com aumentos repentinos de carga com mais eficiência.</p>\n</details>\n<h3 id=\"nao-entendendo-os-impactos-da-execucao-do-go-no-docker-e-kubernetes-100\">Não entendendo os impactos da execução do Go no Docker e Kubernetes (#100)</h3>\n<details class=\"info\" open=\"open\">\n<summary>TL;DR</summary>\n<p>Para ajudar a evitar a limitação da CPU quando implantado no Docker e no Kubernetes, lembre-se de que Go não reconhece <abbr title=\"Completely Fair Scheduler\">CFS</abbr>.</p>\n</details>\n<p>By default, <abbr title=\"The variable defines the limit of OS threads in charge of executing user-level code simultaneously\">GOMAXPROCS</abbr> is set to the number of OS-apparent logical CPU cores.</p>\n<p>When running some Go code inside Docker and Kubernetes, we must know that Go isn't <abbr title=\"Completely Fair Scheduler\">CFS</abbr>-aware (<a href=\"https://github.com/golang/go/issues/33803\">github.com/golang/go/issues/33803</a>). Therefore, <abbr title=\"The variable defines the limit of OS threads in charge of executing user-level code simultaneously\">GOMAXPROCS</abbr> isn't automatically set to the value of <code>spec.containers.resources.limits.cpu</code> (see <a href=\"https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\">Kubernetes Resource Management for Pods and Containers</a>); instead, it's set to the number of logical cores on the host machine. The main implication is that it can lead to an increased tail latency in some specific situations.</p>\n<p>One solution is to rely on <a href=\"https://github.com/uber-go/automaxprocs\">uber-go/automaxprocs</a> that automatically set <code>GOMAXPROCS</code> to match the Linux container CPU quota.</p>\n<h2 id=\"community\">Community</h2>\n<p>Thanks to all the contributors:</p>\n<p><a href=\"https://contrib.rocks/image?repo=teivah/100-go-mistakes\">\n    <img src=\"https://contrib.rocks/image?repo=teivah/100-go-mistakes\" alt=\"Description of the image\">\n</a></p>\n\n\n\n\n\n\n\n  \n  \n\n\n\n  \n\n\n\n\n<h2 id=\"__comments\">Comments</h2>\n<!-- Insert generated snippet here -->\n<script src=\"https://giscus.app/client.js\" data-repo=\"teivah/100-go-mistakes\" data-repo-id=\"MDEwOlJlcG9zaXRvcnkzMjA4MTg5NjI=\" data-category=\"Discussions\" data-category-id=\"DIC_kwDOEx9PEs4CZQUm\" data-mapping=\"pathname\" data-strict=\"0\" data-reactions-enabled=\"1\" data-emit-metadata=\"0\" data-input-position=\"bottom\" data-theme=\"preferred_color_scheme\" data-lang=\"en\" crossorigin=\"anonymous\" async>\n</script>\n<!-- Synchronize Giscus theme with palette -->\n<script>\n  var giscus = document.querySelector(\"script[src*=giscus]\")\n\n  // Set palette on initial load\n  var palette = __md_get(\"__palette\")\n  if (palette && typeof palette.color === \"object\") {\n    var theme = palette.color.scheme === \"slate\"\n        ? \"transparent_dark\"\n        : \"light\"\n\n    // Instruct Giscus to set theme\n    giscus.setAttribute(\"data-theme\", theme)\n  }\n\n  // Register event handlers after documented loaded\n  document.addEventListener(\"DOMContentLoaded\", function() {\n    var ref = document.querySelector(\"[data-md-component=palette]\")\n    ref.addEventListener(\"change\", function() {\n      var palette = __md_get(\"__palette\")\n      if (palette && typeof palette.color === \"object\") {\n        var theme = palette.color.scheme === \"slate\"\n            ? \"transparent_dark\"\n            : \"light\"\n\n        // Instruct Giscus to change theme\n        var frame = document.querySelector(\".giscus-frame\")\n        frame.contentWindow.postMessage(\n            { giscus: { setConfig: { theme } } },\n            \"https://giscus.app\"\n        )\n      }\n    })\n  })\n</script>\n\n                \n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright © 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"></path></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \"..\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"../assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"../assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  \n<script id=\"init-glightbox\">const lightbox = GLightbox({\"touchNavigation\": true, \"loop\": false, \"zoomable\": true, \"draggable\": true, \"openEffect\": \"zoom\", \"closeEffect\": \"zoom\", \"slideEffect\": \"slide\"});\ndocument$.subscribe(()=>{ lightbox.reload(); });\n</script></body></html>"
  },
  {
    "path": "site/search/search_index.json",
    "content": "{\"config\":{\"lang\":[\"en\"],\"separator\":\"[\\\\s\\\\-]+\",\"pipeline\":[\"stopWordFilter\"]},\"docs\":[{\"location\":\"\",\"title\":\"Common Go Mistakes\",\"text\":\"\"},{\"location\":\"#common-go-mistakes\",\"title\":\"Common Go Mistakes\",\"text\":\"The Coder Cafe <p>If you enjoyed my book, you may be interested in my latest project: The Coder Cafe, a newsletter for coders.</p> <p>Feeling overwhelmed by the endless stream of tech content? At The Coder Cafe, we serve timeless concepts with your coffee. Written by a Google SWE and published author, we help you grow as an engineer, one coffee at a time.</p> <p></p><p></p> <p>This page is a summary of the mistakes in the 100 Go Mistakes and How to Avoid Them book. Meanwhile, it's also open to the community. If you believe that a common Go mistake should be added, please create an issue.</p> <p></p> Beta <p>You're viewing a beta version enriched with significantly more content. However, this version is not yet complete, and I'm looking for volunteers to help me summarize the remaining mistakes (GitHub issue #43).</p> <p>Progress: </p>\"},{\"location\":\"#code-and-project-organization\",\"title\":\"Code and Project Organization\",\"text\":\"\"},{\"location\":\"#unintended-variable-shadowing-1\",\"title\":\"Unintended variable shadowing (#1)\",\"text\":\"TL;DR <p>Avoiding shadowed variables can help prevent mistakes like referencing the wrong variable or confusing readers.</p> <p>Variable shadowing occurs when a variable name is redeclared in an inner block, but this practice is prone to mistakes. Imposing a rule to forbid shadowed variables depends on personal taste. For example, sometimes it can be convenient to reuse an existing variable name like <code>err</code> for errors. Yet, in general, we should remain cautious because we now know that we can face a scenario where the code compiles, but the variable that receives the value is not the one expected.</p> <p> Source code</p>\"},{\"location\":\"#unnecessary-nested-code-2\",\"title\":\"Unnecessary nested code (#2)\",\"text\":\"TL;DR <p>Avoiding nested levels and keeping the happy path aligned on the left makes building a mental code model easier.</p> <p>In general, the more nested levels a function requires, the more complex it is to read and understand. Let\\u2019s see some different applications of this rule to optimize our code for readability:</p> <ul> <li>When an <code>if</code> block returns, we should omit the <code>else</code> block in all cases. For example, we shouldn\\u2019t write:</li> </ul> <pre><code>if foo() {\\n    // ...\\n    return true\\n} else {\\n    // ...\\n}\\n</code></pre> <p>Instead, we omit the <code>else</code> block like this:</p> <pre><code>if foo() {\\n    // ...\\n    return true\\n}\\n// ...\\n</code></pre> <ul> <li>We can also follow this logic with a non-happy path:</li> </ul> <pre><code>if s != \\\"\\\" {\\n    // ...\\n} else {\\n    return errors.New(\\\"empty string\\\")\\n}\\n</code></pre> <p>Here, an empty <code>s</code> represents the non-happy path. Hence, we should flip the   condition like so:</p> <pre><code>if s == \\\"\\\" {\\n    return errors.New(\\\"empty string\\\")\\n}\\n// ...\\n</code></pre> <p>Writing readable code is an important challenge for every developer. Striving to reduce the number of nested blocks, aligning the happy path on the left, and returning as early as possible are concrete means to improve our code\\u2019s readability.</p> <p> Source code</p>\"},{\"location\":\"#misusing-init-functions-3\",\"title\":\"Misusing init functions (#3)\",\"text\":\"TL;DR <p>When initializing variables, remember that init functions have limited error handling and make state handling and testing more complex. In most cases, initializations should be handled as specific functions.</p> <p>An init function is a function used to initialize the state of an application. It takes no arguments and returns no result (a <code>func()</code> function). When a package is initialized, all the constant and variable declarations in the package are evaluated. Then, the init functions are executed.</p> <p>Init functions can lead to some issues:</p> <ul> <li>They can limit error management.</li> <li>They can complicate how to implement tests (for example, an external dependency must be set up, which may not be necessary for the scope of unit tests).</li> <li>If the initialization requires us to set a state, that has to be done through global variables.</li> </ul> <p>We should be cautious with init functions. They can be helpful in some situations, however, such as defining static configuration. Otherwise, and in most cases, we should handle initializations through ad hoc functions.</p> <p> Source code</p>\"},{\"location\":\"#overusing-getters-and-setters-4\",\"title\":\"Overusing getters and setters (#4)\",\"text\":\"TL;DR <p>Forcing the use of getters and setters isn\\u2019t idiomatic in Go. Being pragmatic and finding the right balance between efficiency and blindly following certain idioms should be the way to go.</p> <p>Data encapsulation refers to hiding the values or state of an object. Getters and setters are means to enable encapsulation by providing exported methods on top of unexported object fields.</p> <p>In Go, there is no automatic support for getters and setters as we see in some languages. It is also considered neither mandatory nor idiomatic to use getters and setters to access struct fields. We shouldn\\u2019t overwhelm our code with getters and setters on structs if they don\\u2019t bring any value. We should be pragmatic and strive to find the right balance between efficiency and following idioms that are sometimes considered indisputable in other programming paradigms.</p> <p>Remember that Go is a unique language designed for many characteristics, including simplicity. However, if we find a need for getters and setters or, as mentioned, foresee a future need while guaranteeing forward compatibility, there\\u2019s nothing wrong with using them.</p>\"},{\"location\":\"#interface-pollution-5\",\"title\":\"Interface pollution (#5)\",\"text\":\"TL;DR <p>Abstractions should be discovered, not created. To prevent unnecessary complexity, create an interface when you need it and not when you foresee needing it, or if you can at least prove the abstraction to be a valid one.</p> <p>Read the full section here.</p> <p> Source code</p>\"},{\"location\":\"#interface-on-the-producer-side-6\",\"title\":\"Interface on the producer side (#6)\",\"text\":\"TL;DR <p>Keeping interfaces on the client side avoids unnecessary abstractions.</p> <p>Interfaces are satisfied implicitly in Go, which tends to be a gamechanger compared to languages with an explicit implementation. In most cases, the approach to follow is similar to what we described in the previous section: abstractions should be discovered, not created. This means that it\\u2019s not up to the producer to force a given abstraction for all the clients. Instead, it\\u2019s up to the client to decide whether it needs some form of abstraction and then determine the best abstraction level for its needs.</p> <p>An interface should live on the consumer side in most cases. However, in particular contexts (for example, when we know\\u2014not foresee\\u2014that an abstraction will be helpful for consumers), we may want to have it on the producer side. If we do, we should strive to keep it as minimal as possible, increasing its reusability potential and making it more easily composable.</p> <p> Source code</p>\"},{\"location\":\"#returning-interfaces-7\",\"title\":\"Returning interfaces (#7)\",\"text\":\"TL;DR <p>To prevent being restricted in terms of flexibility, a function shouldn\\u2019t return interfaces but concrete implementations in most cases. Conversely, a function should accept interfaces whenever possible.</p> <p>In most cases, we shouldn\\u2019t return interfaces but concrete implementations. Otherwise, it can make our design more complex due to package dependencies and can restrict flexibility because all the clients would have to rely on the same abstraction. Again, the conclusion is similar to the previous sections: if we know (not foresee) that an abstraction will be helpful for clients, we can consider returning an interface. Otherwise, we shouldn\\u2019t force abstractions; they should be discovered by clients. If a client needs to abstract an implementation for whatever reason, it can still do that on the client\\u2019s side.</p>\"},{\"location\":\"#any-says-nothing-8\",\"title\":\"<code>any</code> says nothing (#8)\",\"text\":\"TL;DR <p>Only use <code>any</code> if you need to accept or return any possible type, such as <code>json.Marshal</code>. Otherwise, <code>any</code> doesn\\u2019t provide meaningful information and can lead to compile-time issues by allowing a caller to call methods with any data type.</p> <p>The <code>any</code> type can be helpful if there is a genuine need for accepting or returning any possible type (for instance, when it comes to marshaling or formatting). In general, we should avoid overgeneralizing the code we write at all costs. Perhaps a little bit of duplicated code might occasionally be better if it improves other aspects such as code expressiveness.</p> <p> Source code</p>\"},{\"location\":\"#being-confused-about-when-to-use-generics-9\",\"title\":\"Being confused about when to use generics (#9)\",\"text\":\"TL;DR <p>Relying on generics and type parameters can prevent writing boilerplate code to factor out elements or behaviors. However, do not use type parameters prematurely, but only when you see a concrete need for them. Otherwise, they introduce unnecessary abstractions and complexity.</p> <p>Read the full section here.</p> <p> Source code</p>\"},{\"location\":\"#not-being-aware-of-the-possible-problems-with-type-embedding-10\",\"title\":\"Not being aware of the possible problems with type embedding (#10)\",\"text\":\"TL;DR <p>Using type embedding can also help avoid boilerplate code; however, ensure that doing so doesn\\u2019t lead to visibility issues where some fields should have remained hidden.</p> <p>When creating a struct, Go offers the option to embed types. But this can sometimes lead to unexpected behaviors if we don\\u2019t understand all the implications of type embedding. Throughout this section, we look at how to embed types, what these bring, and the possible issues.</p> <p>In Go, a struct field is called embedded if it\\u2019s declared without a name. For example,</p> <pre><code>type Foo struct {\\n    Bar // Embedded field\\n}\\n\\ntype Bar struct {\\n    Baz int\\n}\\n</code></pre> <p>In the <code>Foo</code> struct, the <code>Bar</code> type is declared without an associated name; hence, it\\u2019s an embedded field.</p> <p>We use embedding to promote the fields and methods of an embedded type. Because <code>Bar</code> contains a <code>Baz</code> field, this field is promoted to <code>Foo</code>. Therefore, <code>Baz</code> becomes available from <code>Foo</code>.</p> <p>What can we say about type embedding? First, let\\u2019s note that it\\u2019s rarely a necessity, and it means that whatever the use case, we can probably solve it as well without type embedding. Type embedding is mainly used for convenience: in most cases, to promote behaviors.</p> <p>If we decide to use type embedding, we need to keep two main constraints in mind:</p> <ul> <li>It shouldn\\u2019t be used solely as some syntactic sugar to simplify accessing a field (such as <code>Foo.Baz()</code> instead of <code>Foo.Bar.Baz()</code>). If this is the only rationale, let\\u2019s not embed the inner type and use a field instead.</li> <li>It shouldn\\u2019t promote data (fields) or a behavior (methods) we want to hide from the outside: for example, if it allows clients to access a locking behavior that should remain private to the struct.</li> </ul> <p>Using type embedding consciously by keeping these constraints in mind can help avoid boilerplate code with additional forwarding methods. However, let\\u2019s make sure we don\\u2019t do it solely for cosmetics and not promote elements that should remain hidden.</p> <p> Source code</p>\"},{\"location\":\"#not-using-the-functional-options-pattern-11\",\"title\":\"Not using the functional options pattern (#11)\",\"text\":\"TL;DR <p>To handle options conveniently and in an API-friendly manner, use the functional options pattern.</p> <p>Although there are different implementations with minor variations, the main idea is as follows:</p> <ul> <li>An unexported struct holds the configuration: options.</li> <li>Each option is a function that returns the same type: <code>type Option func(options *options) error</code>. For example, <code>WithPort</code> accepts an <code>int</code> argument that represents the port and returns an <code>Option</code> type that represents how to update the <code>options</code> struct.</li> </ul> <p></p> <pre><code>type options struct {\\n  port *int\\n}\\n\\ntype Option func(options *options) error\\n\\nfunc WithPort(port int) Option {\\n  return func(options *options) error {\\n    if port &lt; 0 {\\n      return errors.New(\\\"port should be positive\\\")\\n    }\\n    options.port = &amp;port\\n    return nil\\n  }\\n}\\n\\nfunc NewServer(addr string, opts ...Option) ( *http.Server, error) {\\n  var options options\\n  for _, opt := range opts {\\n    err := opt(&amp;options)\\n    if err != nil {\\n      return nil, err\\n    }\\n  }\\n\\n  // At this stage, the options struct is built and contains the config\\n  // Therefore, we can implement our logic related to port configuration\\n  var port int\\n  if options.port == nil {\\n    port = defaultHTTPPort\\n  } else {\\n    if *options.port == 0 {\\n      port = randomPort()\\n    } else {\\n      port = *options.port\\n    }\\n  }\\n\\n  // ...\\n}\\n</code></pre> <p>The functional options pattern provides a handy and API-friendly way to handle options. Although the builder pattern can be a valid option, it has some minor downsides (having to pass a config struct that can be empty or a less handy way to handle error management) that tend to make the functional options pattern the idiomatic way to deal with these kind of problems in Go.</p> <p> Source code</p>\"},{\"location\":\"#project-misorganization-project-structure-and-package-organization-12\",\"title\":\"Project misorganization (project structure and package organization) (#12)\",\"text\":\"<p>Regarding the overall organization, there are different schools of thought. For example, should we organize our application by context or by layer? It depends on our preferences. We may favor grouping code per context (such as the customer context, the contract context, etc.), or we may favor following hexagonal architecture principles and group per technical layer. If the decision we make fits our use case, it cannot be a wrong decision, as long as we remain consistent with it.</p> <p>Regarding packages, there are multiple best practices that we should follow. First, we should avoid premature packaging because it might cause us to overcomplicate a project. Sometimes, it\\u2019s better to use a simple organization and have our project evolve when we understand what it contains rather than forcing ourselves to make the perfect structure up front. Granularity is another essential thing to consider. We should avoid having dozens of nano packages containing only one or two files. If we do, it\\u2019s because we have probably missed some logical connections across these packages, making our project harder for readers to understand. Conversely, we should also avoid huge packages that dilute the meaning of a package name.</p> <p>Package naming should also be considered with care. As we all know (as developers), naming is hard. To help clients understand a Go project, we should name our packages after what they provide, not what they contain. Also, naming should be meaningful. Therefore, a package name should be short, concise, expressive, and, by convention, a single lowercase word.</p> <p>Regarding what to export, the rule is pretty straightforward. We should minimize what should be exported as much as possible to reduce the coupling between packages and keep unnecessary exported elements hidden. If we are unsure whether to export an element or not, we should default to not exporting it. Later, if we discover that we need to export it, we can adjust our code. Let\\u2019s also keep in mind some exceptions, such as making fields exported so that a struct can be unmarshaled with encoding/json.</p> <p>Organizing a project isn\\u2019t straightforward, but following these rules should help make it easier to maintain. However, remember that consistency is also vital to ease maintainability. Therefore, let\\u2019s make sure that we keep things as consistent as possible within a codebase.</p> Note <p>In 2023, the Go team has published an official guideline for organizing / structuring a Go project: go.dev/doc/modules/layout</p>\"},{\"location\":\"#creating-utility-packages-13\",\"title\":\"Creating utility packages (#13)\",\"text\":\"TL;DR <p>Naming is a critical piece of application design. Creating packages such as <code>common</code>, <code>util</code>, and <code>shared</code> doesn\\u2019t bring much value for the reader. Refactor such packages into meaningful and specific package names.</p> <p>Also, bear in mind that naming a package after what it provides and not what it contains can be an efficient way to increase its expressiveness.</p> <p> Source code</p>\"},{\"location\":\"#ignoring-package-name-collisions-14\",\"title\":\"Ignoring package name collisions (#14)\",\"text\":\"TL;DR <p>To avoid naming collisions between variables and packages, leading to confusion or perhaps even bugs, use unique names for each one. If this isn\\u2019t feasible, use an import alias to change the qualifier to differentiate the package name from the variable name, or think of a better name.</p> <p>Package collisions occur when a variable name collides with an existing package name, preventing the package from being reused. We should prevent variable name collisions to avoid ambiguity. If we face a collision, we should either find another meaningful name or use an import alias.</p>\"},{\"location\":\"#missing-code-documentation-15\",\"title\":\"Missing code documentation (#15)\",\"text\":\"TL;DR <p>To help clients and maintainers understand your code\\u2019s purpose, document exported elements.</p> <p>Documentation is an important aspect of coding. It simplifies how clients can consume an API but can also help in maintaining a project. In Go, we should follow some rules to make our code idiomatic:</p> <p>First, every exported element must be documented. Whether it is a structure, an interface, a function, or something else, if it\\u2019s exported, it must be documented. The convention is to add comments, starting with the name of the exported element.</p> <p>As a convention, each comment should be a complete sentence that ends with punctuation. Also bear in mind that when we document a function (or a method), we should highlight what the function intends to do, not how it does it; this belongs to the core of a function and comments, not documentation. Furthermore, the documentation should ideally provide enough information that the consumer does not have to look at our code to understand how to use an exported element.</p> <p>When it comes to documenting a variable or a constant, we might be interested in conveying two aspects: its purpose and its content. The former should live as code documentation to be useful for external clients. The latter, though, shouldn\\u2019t necessarily be public.</p> <p>To help clients and maintainers understand a package\\u2019s scope, we should also document each package. The convention is to start the comment with <code>// Package</code> followed by the package name. The first line of a package comment should be concise. That\\u2019s because it will appear in the package. Then, we can provide all the information we need in the following lines.</p> <p>Documenting our code shouldn\\u2019t be a constraint. We should take the opportunity to make sure it helps clients and maintainers to understand the purpose of our code.</p>\"},{\"location\":\"#not-using-linters-16\",\"title\":\"Not using linters (#16)\",\"text\":\"TL;DR <p>To improve code quality and consistency, use linters and formatters.</p> <p>A linter is an automatic tool to analyze code and catch errors. The scope of this section isn\\u2019t to give an exhaustive list of the existing linters; otherwise, it will become deprecated pretty quickly. But we should understand and remember why linters are essential for most Go projects.</p> <p>However, if you\\u2019re not a regular user of linters, here is a list that you may want to use daily:</p> <ul> <li>https://golang.org/cmd/vet\\u2014A standard Go analyzer</li> <li>https://github.com/kisielk/errcheck\\u2014An error checker</li> <li>https://github.com/fzipp/gocyclo\\u2014A cyclomatic complexity analyzer</li> <li>https://github.com/jgautheron/goconst\\u2014A repeated string constants analyzer</li> </ul> <p>Besides linters, we should also use code formatters to fix code style. Here is a list of some code formatters for you to try:</p> <ul> <li>https://golang.org/cmd/gofmt\\u2014A standard Go code formatter</li> <li>https://godoc.org/golang.org/x/tools/cmd/goimports\\u2014A standard Go imports formatter</li> </ul> <p>Meanwhile, we should also look at golangci-lint (https://github.com/golangci/golangci-lint). It\\u2019s a linting tool that provides a facade on top of many useful linters and formatters. Also, it allows running the linters in parallel to improve analysis speed, which is quite handy.</p> <p>Linters and formatters are a powerful way to improve the quality and consistency of our codebase. Let\\u2019s take the time to understand which one we should use and make sure we automate their execution (such as a CI or Git precommit hook).</p>\"},{\"location\":\"#data-types\",\"title\":\"Data Types\",\"text\":\"\"},{\"location\":\"#creating-confusion-with-octal-literals-17\",\"title\":\"Creating confusion with octal literals (#17)\",\"text\":\"TL;DR <p>When reading existing code, bear in mind that integer literals starting with <code>0</code> are octal numbers. Also, to improve readability, make octal integers explicit by prefixing them with <code>0o</code>.</p> <p>Octal numbers start with a 0 (e.g., <code>010</code> is equal to 8 in base 10). To improve readability and avoid potential mistakes for future code readers, we should make octal numbers explicit using the <code>0o</code> prefix (e.g., <code>0o10</code>).</p> <p>We should also note the other integer literal representations:</p> <ul> <li>Binary\\u2014Uses a <code>0b</code> or <code>0B</code> prefix (for example, <code>0b100</code> is equal to 4 in base 10)</li> <li>Hexadecimal\\u2014Uses an <code>0x</code> or <code>0X</code> prefix (for example, <code>0xF</code> is equal to 15 in base 10)</li> <li>Imaginary\\u2014Uses an <code>i</code> suffix (for example, <code>3i</code>)</li> </ul> <p>We can also use an underscore character (_) as a separator for readability. For example, we can write 1 billion this way: <code>1_000_000_000</code>. We can also use the underscore character with other representations (for example, <code>0b00_00_01</code>).</p> <p> Source code</p>\"},{\"location\":\"#neglecting-integer-overflows-18\",\"title\":\"Neglecting integer overflows (#18)\",\"text\":\"TL;DR <p>Because integer overflows and underflows are handled silently in Go, you can implement your own functions to catch them.</p> <p>In Go, an integer overflow that can be detected at compile time generates a compilation error. For example,</p> <pre><code>var counter int32 = math.MaxInt32 + 1\\n</code></pre> <pre><code>constant 2147483648 overflows int32\\n</code></pre> <p>However, at run time, an integer overflow or underflow is silent; this does not lead to an application panic. It is essential to keep this behavior in mind, because it can lead to sneaky bugs (for example, an integer increment or addition of positive integers that leads to a negative result).</p> <p> Source code</p>\"},{\"location\":\"#not-understanding-floating-points-19\",\"title\":\"Not understanding floating-points (#19)\",\"text\":\"TL;DR <p>Making floating-point comparisons within a given delta can ensure that your code is portable. When performing addition or subtraction, group the operations with a similar order of magnitude to favor accuracy. Also, perform multiplication and division before addition and subtraction.</p> <p>In Go, there are two floating-point types (if we omit imaginary numbers): float32 and float64. The concept of a floating point was invented to solve the major problem with integers: their inability to represent fractional values. To avoid bad surprises, we need to know that floating-point arithmetic is an approximation of real arithmetic.</p> <p>For that, we\\u2019ll look at a multiplication example:</p> <pre><code>var n float32 = 1.0001\\nfmt.Println(n * n)\\n</code></pre> <p>We may expect this code to print the result of 1.0001 * 1.0001 = 1.00020001, right? However, running it on most x86 processors prints 1.0002, instead.</p> <p>Because Go\\u2019s <code>float32</code> and <code>float64</code> types are approximations, we have to bear a few rules in mind:</p> <ul> <li>When comparing two floating-point numbers, check that their difference is within an acceptable range.</li> <li>When performing additions or subtractions, group operations with a similar order of magnitude for better accuracy.</li> <li>To favor accuracy, if a sequence of operations requires addition, subtraction, multiplication, or division, perform the multiplication and division operations first.</li> </ul> <p> Source code</p>\"},{\"location\":\"#not-understanding-slice-length-and-capacity-20\",\"title\":\"Not understanding slice length and capacity (#20)\",\"text\":\"TL;DR <p>Understanding the difference between slice length and capacity should be part of a Go developer\\u2019s core knowledge. The slice length is the number of available elements in the slice, whereas the slice capacity is the number of elements in the backing array.</p> <p>Read the full section here.</p> <p> Source code</p>\"},{\"location\":\"#inefficient-slice-initialization-21\",\"title\":\"Inefficient slice initialization (#21)\",\"text\":\"TL;DR <p>When creating a slice, initialize it with a given length or capacity if its length is already known. This reduces the number of allocations and improves performance.</p> <p>While initializing a slice using <code>make</code>, we can provide a length and an optional capacity. Forgetting to pass an appropriate value for both of these parameters when it makes sense is a widespread mistake. Indeed, it can lead to multiple copies and additional effort for the GC to clean the temporary backing arrays. Performance-wise, there\\u2019s no good reason not to give the Go runtime a helping hand.</p> <p>Our options are to allocate a slice with either a given capacity or a given length. Of these two solutions, we have seen that the second tends to be slightly faster. But using a given capacity and append can be easier to implement and read in some contexts.</p> <p> Source code</p>\"},{\"location\":\"#being-confused-about-nil-vs-empty-slice-22\",\"title\":\"Being confused about nil vs. empty slice (#22)\",\"text\":\"TL;DR <p>To prevent common confusions such as when using the <code>encoding/json</code> or the <code>reflect</code> package, you need to understand the difference between nil and empty slices. Both are zero-length, zero-capacity slices, but only a nil slice doesn\\u2019t require allocation.</p> <p>In Go, there is a distinction between nil and empty slices. A nil slice is equals to <code>nil</code>, whereas an empty slice has a length of zero. A nil slice is empty, but an empty slice isn\\u2019t necessarily <code>nil</code>. Meanwhile, a nil slice doesn\\u2019t require any allocation. We have seen throughout this section how to initialize a slice depending on the context by using</p> <ul> <li><code>var s []string</code> if we aren\\u2019t sure about the final length and the slice can be empty</li> <li><code>[]string(nil)</code> as syntactic sugar to create a nil and empty slice</li> <li><code>make([]string, length)</code> if the future length is known</li> </ul> <p>The last option, <code>[]string{}</code>, should be avoided if we initialize the slice without elements. Finally, let\\u2019s check whether the libraries we use make the distinctions between nil and empty slices to prevent unexpected behaviors.</p> <p> Source code</p>\"},{\"location\":\"#not-properly-checking-if-a-slice-is-empty-23\",\"title\":\"Not properly checking if a slice is empty (#23)\",\"text\":\"TL;DR <p>To check if a slice doesn\\u2019t contain any element, check its length. This check works regardless of whether the slice is <code>nil</code> or empty. The same goes for maps. To design unambiguous APIs, you shouldn\\u2019t distinguish between nil and empty slices.</p> <p>To determine whether a slice has elements, we can either do it by checking if the slice is nil or if its length is equal to 0. Checking the length is the best option to follow as it will cover both if the slice is empty or if the slice is nil.</p> <p>Meanwhile, when designing interfaces, we should avoid distinguishing nil and empty slices, which leads to subtle programming errors. When returning slices, it should make neither a semantic nor a technical difference if we return a nil or empty slice. Both should mean the same thing for the callers. This principle is the same with maps. To check if a map is empty, check its length, not whether it\\u2019s nil.</p> <p> Source code</p>\"},{\"location\":\"#not-making-slice-copies-correctly-24\",\"title\":\"Not making slice copies correctly (#24)\",\"text\":\"TL;DR <p>To copy one slice to another using the <code>copy</code> built-in function, remember that the number of copied elements corresponds to the minimum between the two slice\\u2019s lengths.</p> <p>Copying elements from one slice to another is a reasonably frequent operation. When using copy, we must recall that the number of elements copied to the destination corresponds to the minimum between the two slices\\u2019 lengths. Also bear in mind that other alternatives exist to copy a slice, so we shouldn\\u2019t be surprised if we find them in a codebase.</p> <p> Source code</p>\"},{\"location\":\"#unexpected-side-effects-using-slice-append-25\",\"title\":\"Unexpected side effects using slice append (#25)\",\"text\":\"TL;DR <p>Using copy or the full slice expression is a way to prevent <code>append</code> from creating conflicts if two different functions use slices backed by the same array. However, only a slice copy prevents memory leaks if you want to shrink a large slice.</p> <p>When using slicing, we must remember that we can face a situation leading to unintended side effects. If the resulting slice has a length smaller than its capacity, append can mutate the original slice. If we want to restrict the range of possible side effects, we can use either a slice copy or the full slice expression, which prevents us from doing a copy.</p> Note <p><code>s[low:high:max]</code> (full slice expression): This statement creates a slice similar to the one created with <code>s[low:high]</code>, except that the resulting slice\\u2019s capacity is equal to <code>max - low</code>.</p> <p> Source code</p>\"},{\"location\":\"#slices-and-memory-leaks-26\",\"title\":\"Slices and memory leaks (#26)\",\"text\":\"TL;DR <p>Working with a slice of pointers or structs with pointer fields, you can avoid memory leaks by marking as nil the elements excluded by a slicing operation.</p>\"},{\"location\":\"#leaking-capacity\",\"title\":\"Leaking capacity\",\"text\":\"<p>Remember that slicing a large slice or array can lead to potential high memory consumption. The remaining space won\\u2019t be reclaimed by the GC, and we can keep a large backing array despite using only a few elements. Using a slice copy is the solution to prevent such a case.</p> <p> Source code</p>\"},{\"location\":\"#slice-and-pointers\",\"title\":\"Slice and pointers\",\"text\":\"<p>When we use the slicing operation with pointers or structs with pointer fields, we need to know that the GC won\\u2019t reclaim these elements. In that case, the two options are to either perform a copy or explicitly mark the remaining elements or their fields to <code>nil</code>.</p> <p> Source code</p>\"},{\"location\":\"#inefficient-map-initialization-27\",\"title\":\"Inefficient map initialization (#27)\",\"text\":\"TL;DR <p>When creating a map, initialize it with a given length if its length is already known. This reduces the number of allocations and improves performance.</p> <p>A map provides an unordered collection of key-value pairs in which all the keys are distinct. In Go, a map is based on the hash table data structure. Internally, a hash table is an array of buckets, and each bucket is a pointer to an array of key-value pairs.</p> <p>If we know up front the number of elements a map will contain, we should create it by providing an initial size. Doing this avoids potential map growth, which is quite heavy computation-wise because it requires reallocating enough space and rebalancing all the elements.</p> <p> Source code</p>\"},{\"location\":\"#maps-and-memory-leaks-28\",\"title\":\"Maps and memory leaks (#28)\",\"text\":\"TL;DR <p>A map can always grow in memory, but it never shrinks. Hence, if it leads to some memory issues, you can try different options, such as forcing Go to recreate the map or using pointers.</p> <p>Read the full section here.</p> <p> Source code</p>\"},{\"location\":\"#comparing-values-incorrectly-29\",\"title\":\"Comparing values incorrectly (#29)\",\"text\":\"TL;DR <p>To compare types in Go, you can use the == and != operators if two types are comparable: Booleans, numerals, strings, pointers, channels, and structs are composed entirely of comparable types. Otherwise, you can either use <code>reflect.DeepEqual</code> and pay the price of reflection or use custom implementations and libraries.</p> <p>It\\u2019s essential to understand how to use <code>==</code> and <code>!=</code> to make comparisons effectively. We can use these operators on operands that are comparable:</p> <ul> <li>Booleans\\u2014Compare whether two Booleans are equal.</li> <li>Numerics (int, float, and complex types)\\u2014Compare whether two numerics are equal.</li> <li>Strings\\u2014Compare whether two strings are equal.</li> <li>Channels\\u2014Compare whether two channels were created by the same call to make or if both are nil.</li> <li>Interfaces\\u2014Compare whether two interfaces have identical dynamic types and equal dynamic values or if both are nil.</li> <li>Pointers\\u2014Compare whether two pointers point to the same value in memory or if both are nil.</li> <li>Structs and arrays\\u2014Compare whether they are composed of similar types.</li> </ul> Note <p>We can also use the <code>?</code>, <code>&gt;=</code>, <code>&lt;</code>, and <code>&gt;</code> operators with numeric types to compare values and with strings to compare their lexical order.</p> <p>If operands are not comparable (e.g., slices and maps), we have to use other options such as reflection. Reflection is a form of metaprogramming, and it refers to the ability of an application to introspect and modify its structure and behavior. For example, in Go, we can use <code>reflect.DeepEqual</code>. This function reports whether two elements are deeply equal by recursively traversing two values. The elements it accepts are basic types plus arrays, structs, slices, maps, pointers, interfaces, and functions. Yet, the main catch is the performance penalty.</p> <p>If performance is crucial at run time, implementing our custom method might be the best solution. One additional note: we must remember that the standard library has some existing comparison methods. For example, we can use the optimized <code>bytes.Compare</code> function to compare two slices of bytes. Before implementing a custom method, we need to make sure we don\\u2019t reinvent the wheel.</p> <p> Source code</p>\"},{\"location\":\"#control-structures\",\"title\":\"Control Structures\",\"text\":\"\"},{\"location\":\"#ignoring-that-elements-are-copied-in-range-loops-30\",\"title\":\"Ignoring that elements are copied in <code>range</code> loops (#30)\",\"text\":\"TL;DR <p>The value element in a <code>range</code> loop is a copy. Therefore, to mutate a struct, for example, access it via its index or via a classic <code>for</code> loop (unless the element or the field you want to modify is a pointer).</p> <p>A range loop allows iterating over different data structures:</p> <ul> <li>String</li> <li>Array</li> <li>Pointer to an array</li> <li>Slice</li> <li>Map</li> <li>Receiving channel</li> </ul> <p>Compared to a classic for <code>loop</code>, a <code>range</code> loop is a convenient way to iterate over all the elements of one of these data structures, thanks to its concise syntax.</p> <p>Yet, we should remember that the value element in a range loop is a copy. Therefore, if the value is a struct we need to mutate, we will only update the copy, not the element itself, unless the value or field we modify is a pointer. The favored options are to access the element via the index using a range loop or a classic for loop.</p> <p> Source code</p>\"},{\"location\":\"#ignoring-how-arguments-are-evaluated-in-range-loops-channels-and-arrays-31\",\"title\":\"Ignoring how arguments are evaluated in <code>range</code> loops (channels and arrays) (#31)\",\"text\":\"TL;DR <p>Understanding that the expression passed to the <code>range</code> operator is evaluated only once before the beginning of the loop can help you avoid common mistakes such as inefficient assignment in channel or slice iteration.</p> <p>The range loop evaluates the provided expression only once, before the beginning of the loop, by doing a copy (regardless of the type). We should remember this behavior to avoid common mistakes that might, for example, lead us to access the wrong element. For example:</p> <pre><code>a := [3]int{0, 1, 2}\\nfor i, v := range a {\\n    a[2] = 10\\n    if i == 2 {\\n        fmt.Println(v)\\n    }\\n}\\n</code></pre> <p>This code updates the last index to 10. However, if we run this code, it does not print 10; it prints 2.</p> <p> Source code</p>\"},{\"location\":\"#ignoring-the-impacts-of-using-pointer-elements-in-range-loops-32\",\"title\":\"Ignoring the impacts of using pointer elements in <code>range</code> loops (#32)\",\"text\":\"Warning <p>This mistake isn't relevant anymore from Go 1.22 (details).</p>\"},{\"location\":\"#making-wrong-assumptions-during-map-iterations-ordering-and-map-insert-during-iteration-33\",\"title\":\"Making wrong assumptions during map iterations (ordering and map insert during iteration) (#33)\",\"text\":\"TL;DR <p>To ensure predictable outputs when using maps, remember that a map data structure:</p> <ul> <li>Doesn\\u2019t order the data by keys</li> <li>Doesn\\u2019t preserve the insertion order</li> <li>Doesn\\u2019t have a deterministic iteration order</li> <li>Doesn\\u2019t guarantee that an element added during an iteration will be produced during this iteration</li> </ul> <p> Source code</p>\"},{\"location\":\"#ignoring-how-the-break-statement-works-34\",\"title\":\"Ignoring how the <code>break</code> statement works (#34)\",\"text\":\"TL;DR <p>Using <code>break</code> or <code>continue</code> with a label enforces breaking a specific statement. This can be helpful with <code>switch</code> or <code>select</code> statements inside loops.</p> <p>A break statement is commonly used to terminate the execution of a loop. When loops are used in conjunction with switch or select, developers frequently make the mistake of breaking the wrong statement. For example:</p> <pre><code>for i := 0; i &lt; 5; i++ {\\n    fmt.Printf(\\\"%d \\\", i)\\n\\n    switch i {\\n    default:\\n    case 2:\\n        break\\n    }\\n}\\n</code></pre> <p>The break statement doesn\\u2019t terminate the <code>for</code> loop: it terminates the <code>switch</code> statement, instead. Hence, instead of iterating from 0 to 2, this code iterates from 0 to 4: <code>0 1 2 3 4</code>.</p> <p>One essential rule to keep in mind is that a <code>break</code> statement terminates the execution of the innermost <code>for</code>, <code>switch</code>, or <code>select</code> statement. In the previous example, it terminates the <code>switch</code> statement.</p> <p>To break the loop instead of the <code>switch</code> statement, the most idiomatic way is to use a label:</p> <pre><code>loop:\\n    for i := 0; i &lt; 5; i++ {\\n        fmt.Printf(\\\"%d \\\", i)\\n\\n        switch i {\\n        default:\\n        case 2:\\n            break loop\\n        }\\n    }\\n</code></pre> <p>Here, we associate the <code>loop</code> label with the <code>for</code> loop. Then, because we provide the <code>loop</code> label to the <code>break</code> statement, it breaks the loop, not the switch. Therefore, this new version will print <code>0 1 2</code>, as we expected.</p> <p> Source code</p>\"},{\"location\":\"#using-defer-inside-a-loop-35\",\"title\":\"Using <code>defer</code> inside a loop (#35)\",\"text\":\"TL;DR <p>Extracting loop logic inside a function leads to executing a <code>defer</code> statement at the end of each iteration.</p> <p>The <code>defer</code> statement delays a call\\u2019s execution until the surrounding function returns. It\\u2019s mainly used to reduce boilerplate code. For example, if a resource has to be closed eventually, we can use <code>defer</code> to avoid repeating the closure calls before every single <code>return</code>.</p> <p>One common mistake with <code>defer</code> is to forget that it schedules a function call when the surrounding function returns. For example:</p> <pre><code>func readFiles(ch &lt;-chan string) error {\\n    for path := range ch {\\n        file, err := os.Open(path)\\n        if err != nil {\\n            return err\\n        }\\n\\n        defer file.Close()\\n\\n        // Do something with file\\n    }\\n    return nil\\n}\\n</code></pre> <p>The <code>defer</code> calls are executed not during each loop iteration but when the <code>readFiles</code> function returns. If <code>readFiles</code> doesn\\u2019t return, the file descriptors will be kept open forever, causing leaks.</p> <p>One common option to fix this problem is to create a surrounding function after <code>defer</code>, called during each iteration:</p> <pre><code>func readFiles(ch &lt;-chan string) error {\\n    for path := range ch {\\n        if err := readFile(path); err != nil {\\n            return err\\n        }\\n    }\\n    return nil\\n}\\n\\nfunc readFile(path string) error {\\n    file, err := os.Open(path)\\n    if err != nil {\\n        return err\\n    }\\n\\n    defer file.Close()\\n\\n    // Do something with file\\n    return nil\\n}\\n</code></pre> <p>Another solution is to make the <code>readFile</code> function a closure but intrinsically, this remains the same solution: adding another surrounding function to execute the <code>defer</code> calls during each iteration.</p> <p> Source code</p>\"},{\"location\":\"#strings\",\"title\":\"Strings\",\"text\":\"\"},{\"location\":\"#not-understanding-the-concept-of-rune-36\",\"title\":\"Not understanding the concept of rune (#36)\",\"text\":\"TL;DR <p>Understanding that a rune corresponds to the concept of a Unicode code point and that it can be composed of multiple bytes should be part of the Go developer\\u2019s core knowledge to work accurately with strings.</p> <p>As runes are everywhere in Go, it's important to understand the following:</p> <ul> <li>A charset is a set of characters, whereas an encoding describes how to translate a charset into binary.</li> <li>In Go, a string references an immutable slice of arbitrary bytes.</li> <li>Go source code is encoded using UTF-8. Hence, all string literals are UTF-8 strings. But because a string can contain arbitrary bytes, if it\\u2019s obtained from somewhere else (not the source code), it isn\\u2019t guaranteed to be based on the UTF-8 encoding.</li> <li>A <code>rune</code> corresponds to the concept of a Unicode code point, meaning an item represented by a single value.</li> <li>Using UTF-8, a Unicode code point can be encoded into 1 to 4 bytes.</li> <li>Using <code>len()</code> on a string in Go returns the number of bytes, not the number of runes.</li> </ul> <p> Source code</p>\"},{\"location\":\"#inaccurate-string-iteration-37\",\"title\":\"Inaccurate string iteration (#37)\",\"text\":\"TL;DR <p>Iterating on a string with the <code>range</code> operator iterates on the runes with the index corresponding to the starting index of the rune\\u2019s byte sequence. To access a specific rune index (such as the third rune), convert the string into a <code>[]rune</code>.</p> <p>Iterating on a string is a common operation for developers. Perhaps we want to perform an operation for each rune in the string or implement a custom function to search for a specific substring. In both cases, we have to iterate on the different runes of a string. But it\\u2019s easy to get confused about how iteration works.</p> <p>For example, consider the following example:</p> <pre><code>s := \\\"h\\u00eallo\\\"\\nfor i := range s {\\n    fmt.Printf(\\\"position %d: %c\\\\n\\\", i, s[i])\\n}\\nfmt.Printf(\\\"len=%d\\\\n\\\", len(s))\\n</code></pre> <pre><code>position 0: h\\nposition 1: \\u00c3\\nposition 3: l\\nposition 4: l\\nposition 5: o\\nlen=6\\n</code></pre> <p>Let's highlight three points that might be confusing:</p> <ul> <li>The second rune is \\u00c3 in the output instead of \\u00ea.</li> <li>We jumped from position 1 to position 3: what is at position 2?</li> <li>len returns a count of 6, whereas s contains only 5 runes.</li> </ul> <p>Let\\u2019s start with the last observation. We already mentioned that len returns the number of bytes in a string, not the number of runes. Because we assigned a string literal to <code>s</code>, <code>s</code> is a UTF-8 string. Meanwhile, the special character \\\"\\u00ea\\\" isn\\u2019t encoded in a single byte; it requires 2 bytes. Therefore, calling <code>len(s)</code> returns 6.</p> <p>Meanwhile, in the previous example, we have to understand that we don't iterate over each rune; instead, we iterate over each starting index of a rune:</p> <p></p> <p>Printing <code>s[i]</code> doesn\\u2019t print the ith rune; it prints the UTF-8 representation of the byte at index <code>i</code>. Hence, we printed \\\"h\\u00c3llo\\\" instead of \\\"h\\u00eallo\\\".</p> <p>If we want to print all the different runes, we can either use the value element of the <code>range</code> operator:</p> <pre><code>s := \\\"h\\u00eallo\\\"\\nfor i, r := range s {\\n    fmt.Printf(\\\"position %d: %c\\\\n\\\", i, r)\\n}\\n</code></pre> <p>Or, we can convert the string into a slice of runes and iterate over it:</p> <pre><code>s := \\\"h\\u00eallo\\\"\\nrunes := []rune(s)\\nfor i, r := range runes {\\n    fmt.Printf(\\\"position %d: %c\\\\n\\\", i, r)\\n}\\n</code></pre> <p>Note that this solution introduces a run-time overhead compared to the previous one. Indeed, converting a string into a slice of runes requires allocating an additional slice and converting the bytes into runes: an O(n) time complexity with n the number of bytes in the string. Therefore, if we want to iterate over all the runes, we should use the first solution.</p> <p>However, if we want to access the ith rune of a string with the first option, we don\\u2019t have access to the rune index; rather, we know the starting index of a rune in the byte sequence.</p> <pre><code>s := \\\"h\\u00eallo\\\"\\nr := []rune(s)[4]\\nfmt.Printf(\\\"%c\\\\n\\\", r) // o\\n</code></pre> <p> Source code</p>\"},{\"location\":\"#misusing-trim-functions-38\",\"title\":\"Misusing trim functions (#38)\",\"text\":\"TL;DR <p><code>strings.TrimRight</code>/<code>strings.TrimLeft</code> removes all the trailing/leading runes contained in a given set, whereas <code>strings.TrimSuffix</code>/<code>strings.TrimPrefix</code> returns a string without a provided suffix/prefix.</p> <p>For example:</p> <pre><code>fmt.Println(strings.TrimRight(\\\"123oxo\\\", \\\"xo\\\"))\\n</code></pre> <p>The example prints 123:</p> <p></p> <p>Conversely, <code>strings.TrimLeft</code> removes all the leading runes contained in a set.</p> <p>On the other side, <code>strings.TrimSuffix</code> / <code>strings.TrimPrefix</code> returns a string without the provided trailing suffix / prefix.</p> <p> Source code</p>\"},{\"location\":\"#under-optimized-strings-concatenation-39\",\"title\":\"Under-optimized strings concatenation (#39)\",\"text\":\"TL;DR <p>Concatenating a list of strings should be done with <code>strings.Builder</code> to prevent allocating a new string during each iteration.</p> <p>Let\\u2019s consider a <code>concat</code> function that concatenates all the string elements of a slice using the <code>+=</code> operator:</p> <pre><code>func concat(values []string) string {\\n    s := \\\"\\\"\\n    for _, value := range values {\\n        s += value\\n    }\\n    return s\\n}\\n</code></pre> <p>During each iteration, the <code>+=</code> operator concatenates <code>s</code> with the value string. At first sight, this function may not look wrong. But with this implementation, we forget one of the core characteristics of a string: its immutability. Therefore, each iteration doesn\\u2019t update <code>s</code>; it reallocates a new string in memory, which significantly impacts the performance of this function.</p> <p>Fortunately, there is a solution to deal with this problem, using <code>strings.Builder</code>:</p> <pre><code>func concat(values []string) string {\\n    sb := strings.Builder{}\\n    for _, value := range values {\\n        _, _ = sb.WriteString(value)\\n    }\\n    return sb.String()\\n}\\n</code></pre> <p>During each iteration, we constructed the resulting string by calling the <code>WriteString</code> method that appends the content of value to its internal buffer, hence minimizing memory copying.</p> Note <p><code>WriteString</code> returns an error as the second output, but we purposely ignore it. Indeed, this method will never return a non-nil error. So what\\u2019s the purpose of this method returning an error as part of its signature? <code>strings.Builder</code> implements the <code>io.StringWriter</code> interface, which contains a single method: <code>WriteString(s string) (n int, err error)</code>. Hence, to comply with this interface, <code>WriteString</code> must return an error.</p> <p>Internally, <code>strings.Builder</code> holds a byte slice. Each call to <code>WriteString</code> results in a call to append on this slice. There are two impacts. First, this struct shouldn\\u2019t be used concurrently, as the calls to <code>append</code> would lead to race conditions. The second impact is something that we saw in mistake #21, \\\"Inefficient slice initialization\\\": if the future length of a slice is already known, we should preallocate it. For that purpose, <code>strings.Builder</code> exposes a method <code>Grow(n int)</code> to guarantee space for another <code>n</code> bytes:</p> <pre><code>func concat(values []string) string {\\n    total := 0\\n    for i := 0; i &lt; len(values); i++ {\\n        total += len(values[i])\\n    }\\n\\n    sb := strings.Builder{}\\n    sb.Grow(total) (2)\\n    for _, value := range values {\\n        _, _ = sb.WriteString(value)\\n    }\\n    return sb.String()\\n}\\n</code></pre> <p>Let\\u2019s run a benchmark to compare the three versions (v1 using <code>+=</code>; v2 using <code>strings.Builder{}</code> without preallocation; and v3 using <code>strings.Builder{}</code> with preallocation). The input slice contains 1,000 strings, and each string contains 1,000 bytes:</p> <pre><code>BenchmarkConcatV1-4             16      72291485 ns/op\\nBenchmarkConcatV2-4           1188        878962 ns/op\\nBenchmarkConcatV3-4           5922        190340 ns/op\\n</code></pre> <p>As we can see, the latest version is by far the most efficient: 99% faster than v1 and 78% faster than v2.</p> <p><code>strings.Builder</code> is the recommended solution to concatenate a list of strings. Usually, this solution should be used within a loop. Indeed, if we just have to concatenate a few strings (such as a name and a surname), using <code>strings.Builder</code> is not recommended as doing so will make the code a bit less readable than using the <code>+=</code> operator or <code>fmt.Sprintf</code>.</p> <p> Source code</p>\"},{\"location\":\"#useless-string-conversions-40\",\"title\":\"Useless string conversions (#40)\",\"text\":\"TL;DR <p>Remembering that the <code>bytes</code> package offers the same operations as the <code>strings</code> package can help avoid extra byte/string conversions.</p> <p>When choosing to work with a string or a <code>[]byte</code>, most programmers tend to favor strings for convenience. But most I/O is actually done with <code>[]byte</code>. For example, <code>io.Reader</code>, <code>io.Writer</code>, and <code>io.ReadAll</code> work with <code>[]byte</code>, not strings.</p> <p>When we\\u2019re wondering whether we should work with strings or <code>[]byte</code>, let\\u2019s recall that working with <code>[]byte</code> isn\\u2019t necessarily less convenient. Indeed, all the exported functions of the strings package also have alternatives in the <code>bytes</code> package: <code>Split</code>, <code>Count</code>, <code>Contains</code>, <code>Index</code>, and so on. Hence, whether we\\u2019re doing I/O or not, we should first check whether we could implement a whole workflow using bytes instead of strings and avoid the price of additional conversions.</p> <p> Source code</p>\"},{\"location\":\"#substring-and-memory-leaks-41\",\"title\":\"Substring and memory leaks (#41)\",\"text\":\"TL;DR <p>Using copies instead of substrings can prevent memory leaks, as the string returned by a substring operation will be backed by the same byte array.</p> <p>In mistake #26, \\u201cSlices and memory leaks,\\u201d we saw how slicing a slice or array may lead to memory leak situations. This principle also applies to string and substring operations.</p> <p>We need to keep two things in mind while using the substring operation in Go. First, the interval provided is based on the number of bytes, not the number of runes. Second, a substring operation may lead to a memory leak as the resulting substring will share the same backing array as the initial string. The solutions to prevent this case from happening are to perform a string copy manually or to use <code>strings.Clone</code> from Go 1.18.</p> <p> Source code</p>\"},{\"location\":\"#functions-and-methods\",\"title\":\"Functions and Methods\",\"text\":\"\"},{\"location\":\"#not-knowing-which-type-of-receiver-to-use-42\",\"title\":\"Not knowing which type of receiver to use (#42)\",\"text\":\"TL;DR <p>The decision whether to use a value or a pointer receiver should be made based on factors such as the type, whether it has to be mutated, whether it contains a field that can\\u2019t be copied, and how large the object is. When in doubt, use a pointer receiver.</p> <p>Choosing between value and pointer receivers isn\\u2019t always straightforward. Let\\u2019s discuss some of the conditions to help us choose.</p> <p>A receiver must be a pointer</p> <ul> <li>If the method needs to mutate the receiver. This rule is also valid if the receiver is a slice and a method needs to append elements:</li> </ul> <pre><code>type slice []int\\n\\nfunc (s *slice) add(element int) {\\n    *s = append(*s, element)\\n}\\n</code></pre> <ul> <li>If the method receiver contains a field that cannot be copied: for example, a type part of the sync package (see #74, \\u201cCopying a sync type\\u201d).</li> </ul> <p>A receiver should be a pointer</p> <ul> <li>If the receiver is a large object. Using a pointer can make the call more efficient, as doing so prevents making an extensive copy. When in doubt about how large is large, benchmarking can be the solution; it\\u2019s pretty much impossible to state a specific size, because it depends on many factors.</li> </ul> <p>A receiver must be a value</p> <ul> <li>If we have to enforce a receiver\\u2019s immutability.</li> <li>If the receiver is a map, function, or channel. Otherwise, a compilation error   occurs.</li> </ul> <p>A receiver should be a value</p> <ul> <li>If the receiver is a slice that doesn\\u2019t have to be mutated.</li> <li>If the receiver is a small array or struct that is naturally a value type without mutable fields, such as <code>time.Time</code>.</li> <li>If the receiver is a basic type such as <code>int</code>, <code>float64</code>, or <code>string</code>.</li> </ul> <p>Of course, it\\u2019s impossible to be exhaustive, as there will always be edge cases, but this section\\u2019s goal was to provide guidance to cover most cases. By default, we can choose to go with a value receiver unless there\\u2019s a good reason not to do so. In doubt, we should use a pointer receiver.</p> <p> Source code</p>\"},{\"location\":\"#never-using-named-result-parameters-43\",\"title\":\"Never using named result parameters (#43)\",\"text\":\"TL;DR <p>Using named result parameters can be an efficient way to improve the readability of a function/method, especially if multiple result parameters have the same type. In some cases, this approach can also be convenient because named result parameters are initialized to their zero value. But be cautious about potential side effects.</p> <p>When we return parameters in a function or a method, we can attach names to these parameters and use them as regular variables. When a result parameter is named, it\\u2019s initialized to its zero value when the function/method begins. With named result parameters, we can also call a naked return statement (without arguments). In that case, the current values of the result parameters are used as the returned values.</p> <p>Here\\u2019s an example that uses a named result parameter <code>b</code>:</p> <pre><code>func f(a int) (b int) {\\n    b = a\\n    return\\n}\\n</code></pre> <p>In this example, we attach a name to the result parameter: <code>b</code>. When we call return without arguments, it returns the current value of <code>b</code>.</p> <p>In some cases, named result parameters can also increase readability: for example, if two parameters have the same type. In other cases, they can also be used for convenience. Therefore, we should use named result parameters sparingly when there\\u2019s a clear benefit.</p> <p> Source code</p>\"},{\"location\":\"#unintended-side-effects-with-named-result-parameters-44\",\"title\":\"Unintended side effects with named result parameters (#44)\",\"text\":\"TL;DR <p>See #43.</p> <p>We mentioned why named result parameters can be useful in some situations. But as these result parameters are initialized to their zero value, using them can sometimes lead to subtle bugs if we\\u2019re not careful enough. For example, can you spot what\\u2019s wrong with this code?</p> <pre><code>func (l loc) getCoordinates(ctx context.Context, address string) (\\n    lat, lng float32, err error) {\\n    isValid := l.validateAddress(address) (1)\\n    if !isValid {\\n        return 0, 0, errors.New(\\\"invalid address\\\")\\n    }\\n\\n    if ctx.Err() != nil { (2)\\n        return 0, 0, err\\n    }\\n\\n    // Get and return coordinates\\n}\\n</code></pre> <p>The error might not be obvious at first glance. Here, the error returned in the <code>if ctx.Err() != nil</code> scope is <code>err</code>. But we haven\\u2019t assigned any value to the <code>err</code> variable. It\\u2019s still assigned to the zero value of an <code>error</code> type: <code>nil</code>. Hence, this code will always return a nil error.</p> <p>When using named result parameters, we must recall that each parameter is initialized to its zero value. As we have seen in this section, this can lead to subtle bugs that aren\\u2019t always straightforward to spot while reading code. Therefore, let\\u2019s remain cautious when using named result parameters, to avoid potential side effects.</p> <p> Source code</p>\"},{\"location\":\"#returning-a-nil-receiver-45\",\"title\":\"Returning a nil receiver (#45)\",\"text\":\"TL;DR <p>When returning an interface, be cautious about not returning a nil pointer but an explicit nil value. Otherwise, unintended consequences may occur and the caller will receive a non-nil value.</p> <p> Source code</p>\"},{\"location\":\"#using-a-filename-as-a-function-input-46\",\"title\":\"Using a filename as a function input (#46)\",\"text\":\"TL;DR <p>Designing functions to receive <code>io.Reader</code> types instead of filenames improves the reusability of a function and makes testing easier.</p> <p>Accepting a filename as a function input to read from a file should, in most cases, be considered a code smell (except in specific functions such as <code>os.Open</code>). Indeed, it makes unit tests more complex because we may have to create multiple files. It also reduces the reusability of a function (although not all functions are meant to be reused). Using the <code>io.Reader</code> interface abstracts the data source. Regardless of whether the input is a file, a string, an HTTP request, or a gRPC request, the implementation can be reused and easily tested.</p> <p> Source code</p>\"},{\"location\":\"#ignoring-how-defer-arguments-and-receivers-are-evaluated-argument-evaluation-pointer-and-value-receivers-47\",\"title\":\"Ignoring how <code>defer</code> arguments and receivers are evaluated (argument evaluation, pointer, and value receivers) (#47)\",\"text\":\"TL;DR <p>Passing a pointer to a <code>defer</code> function and wrapping a call inside a closure are two possible solutions to overcome the immediate evaluation of arguments and receivers.</p> <p>In a <code>defer</code> function the arguments are evaluated right away, not once the surrounding function returns. For example, in this code, we always call <code>notify</code> and <code>incrementCounter</code> with the same status: an empty string.</p> <pre><code>const (\\n    StatusSuccess  = \\\"success\\\"\\n    StatusErrorFoo = \\\"error_foo\\\"\\n    StatusErrorBar = \\\"error_bar\\\"\\n)\\n\\nfunc f() error {\\n    var status string\\n    defer notify(status)\\n    defer incrementCounter(status)\\n\\n    if err := foo(); err != nil {\\n        status = StatusErrorFoo\\n        return err\\n    }\\n\\n    if err := bar(); err != nil {\\n        status = StatusErrorBar\\n        return err\\n    }\\n\\n    status = StatusSuccess\\n    return nil\\n}\\n</code></pre> <p>Indeed, we call <code>notify(status)</code> and <code>incrementCounter(status)</code> as <code>defer</code> functions. Therefore, Go will delay these calls to be executed once <code>f</code> returns with the current value of status at the stage we used defer, hence passing an empty string.</p> <p>Two leading options if we want to keep using <code>defer</code>.</p> <p>The first solution is to pass a string pointer:</p> <pre><code>func f() error {\\n    var status string\\n    defer notify(&amp;status) \\n    defer incrementCounter(&amp;status)\\n\\n    // The rest of the function unchanged\\n}\\n</code></pre> <p>Using <code>defer</code> evaluates the arguments right away: here, the address of status. Yes, status itself is modified throughout the function, but its address remains constant, regardless of the assignments. Hence, if <code>notify</code> or <code>incrementCounter</code> uses the value referenced by the string pointer, it will work as expected. But this solution requires changing the signature of the two functions, which may not always be possible.</p> <p>There\\u2019s another solution: calling a closure (an anonymous function value that references variables from outside its body) as a <code>defer</code> statement:</p> <pre><code>func f() error {\\n    var status string\\n    defer func() {\\n        notify(status)\\n        incrementCounter(status)\\n    }()\\n\\n    // The rest of the function unchanged\\n}\\n</code></pre> <p>Here, we wrap the calls to both <code>notify</code> and <code>incrementCounter</code> within a closure. This closure references the status variable from outside its body. Therefore, <code>status</code> is evaluated once the closure is executed, not when we call <code>defer</code>. This solution also works and doesn\\u2019t require <code>notify</code> and <code>incrementCounter</code> to change their signature.</p> <p>Let's also note this behavior applies with method receiver: the receiver is evaluated immediately.</p> <p> Source code</p>\"},{\"location\":\"#error-management\",\"title\":\"Error Management\",\"text\":\"\"},{\"location\":\"#panicking-48\",\"title\":\"Panicking (#48)\",\"text\":\"TL;DR <p>Using <code>panic</code> is an option to deal with errors in Go. However, it should only be used sparingly in unrecoverable conditions: for example, to signal a programmer error or when you fail to load a mandatory dependency.</p> <p>In Go, panic is a built-in function that stops the ordinary flow:</p> <pre><code>func main() {\\n    fmt.Println(\\\"a\\\")\\n    panic(\\\"foo\\\")\\n    fmt.Println(\\\"b\\\")\\n}\\n</code></pre> <p>This code prints a and then stops before printing b:</p> <pre><code>a\\npanic: foo\\n\\ngoroutine 1 [running]:\\nmain.main()\\n        main.go:7 +0xb3\\n</code></pre> <p>Panicking in Go should be used sparingly. There are two prominent cases, one to signal a programmer error (e.g., <code>sql.Register</code> that panics if the driver is <code>nil</code> or has already been register) and another where our application fails to create a mandatory dependency. Hence, exceptional conditions that lead us to stop the application. In most other cases, error management should be done with a function that returns a proper error type as the last return argument.</p> <p> Source code</p>\"},{\"location\":\"#ignoring-when-to-wrap-an-error-49\",\"title\":\"Ignoring when to wrap an error (#49)\",\"text\":\"TL;DR <p>Wrapping an error allows you to mark an error and/or provide additional context. However, error wrapping creates potential coupling as it makes the source error available for the caller. If you want to prevent that, don\\u2019t use error wrapping.</p> <p>Since Go 1.13, the %w directive allows us to wrap errors conveniently. Error wrapping is about wrapping or packing an error inside a wrapper container that also makes the source error available. In general, the two main use cases for error wrapping are the following:</p> <ul> <li>Adding additional context to an error</li> <li>Marking an error as a specific error</li> </ul> <p>When handling an error, we can decide to wrap it. Wrapping is about adding additional context to an error and/or marking an error as a specific type. If we need to mark an error, we should create a custom error type. However, if we just want to add extra context, we should use fmt.Errorf with the %w directive as it doesn\\u2019t require creating a new error type. Yet, error wrapping creates potential coupling as it makes the source error available for the caller. If we want to prevent it, we shouldn\\u2019t use error wrapping but error transformation, for example, using fmt.Errorf with the %v directive.</p> <p> Source code</p>\"},{\"location\":\"#comparing-an-error-type-inaccurately-50\",\"title\":\"Comparing an error type inaccurately (#50)\",\"text\":\"TL;DR <p>If you use Go 1.13 error wrapping with the <code>%w</code> directive and <code>fmt.Errorf</code>, comparing an error against a type has to be done using <code>errors.As</code>. Otherwise, if the returned error you want to check is wrapped, it will fail the checks.</p> <p> Source code</p>\"},{\"location\":\"#comparing-an-error-value-inaccurately-51\",\"title\":\"Comparing an error value inaccurately (#51)\",\"text\":\"TL;DR <p>If you use Go 1.13 error wrapping with the <code>%w</code> directive and <code>fmt.Errorf</code>, comparing an error against or a value has to be done using <code>errors.As</code>. Otherwise, if the returned error you want to check is wrapped, it will fail the checks.</p> <p>A sentinel error is an error defined as a global variable:</p> <pre><code>import \\\"errors\\\"\\n\\nvar ErrFoo = errors.New(\\\"foo\\\")\\n</code></pre> <p>In general, the convention is to start with <code>Err</code> followed by the error type: here, <code>ErrFoo</code>. A sentinel error conveys an expected error, an error that clients will expect to check. As general guidelines:</p> <ul> <li>Expected errors should be designed as error values (sentinel errors): <code>var ErrFoo = errors.New(\\\"foo\\\")</code>.</li> <li>Unexpected errors should be designed as error types: <code>type BarError struct { ... }</code>, with <code>BarError</code> implementing the <code>error</code> interface.</li> </ul> <p>If we use error wrapping in our application with the <code>%w</code> directive and <code>fmt.Errorf</code>, checking an error against a specific value should be done using <code>errors.Is</code> instead of <code>==</code>. Thus, even if the sentinel error is wrapped, <code>errors.Is</code> can recursively unwrap it and compare each error in the chain against the provided value.</p> <p> Source code</p>\"},{\"location\":\"#handling-an-error-twice-52\",\"title\":\"Handling an error twice (#52)\",\"text\":\"TL;DR <p>In most situations, an error should be handled only once. Logging an error is handling an error. Therefore, you have to choose between logging or returning an error. In many cases, error wrapping is the solution as it allows you to provide additional context to an error and return the source error.</p> <p>Handling an error multiple times is a mistake made frequently by developers, not specifically in Go. This can cause situations where the same error is logged multiple times make debugging harder.</p> <p>Let's remind us that handling an error should be done only once. Logging an error is handling an error. Hence, we should either log or return an error. By doing this, we simplify our code and gain better insights into the error situation. Using error wrapping is the most convenient approach as it allows us to propagate the source error and add context to an error.</p> <p> Source code</p>\"},{\"location\":\"#not-handling-an-error-53\",\"title\":\"Not handling an error (#53)\",\"text\":\"TL;DR <p>Ignoring an error, whether during a function call or in a <code>defer</code> function, should be done explicitly using the blank identifier. Otherwise, future readers may be confused about whether it was intentional or a miss.</p> <p> Source code</p>\"},{\"location\":\"#not-handling-defer-errors-54\",\"title\":\"Not handling <code>defer</code> errors (#54)\",\"text\":\"TL;DR <p>In many cases, you shouldn\\u2019t ignore an error returned by a <code>defer</code> function. Either handle it directly or propagate it to the caller, depending on the context. If you want to ignore it, use the blank identifier.</p> <p>Consider the following code:</p> <pre><code>func f() {\\n  // ...\\n  notify() // Error handling is omitted\\n}\\n\\nfunc notify() error {\\n  // ...\\n}\\n</code></pre> <p>From a maintainability perspective, the code can lead to some issues. Let\\u2019s consider a new reader looking at it. This reader notices that notify returns an error but that the error isn\\u2019t handled by the parent function. How can they guess whether or not handling the error was intentional? How can they know whether the previous developer forgot to handle it or did it purposely?</p> <p>For these reasons, when we want to ignore an error, there's only one way to do it, using the blank identifier (<code>_</code>):</p> <pre><code>_ = notify\\n</code></pre> <p>In terms of compilation and run time, this approach doesn\\u2019t change anything compared to the first piece of code. But this new version makes explicit that we aren\\u2019t interested in the error. Also, we can add a comment that indicates the rationale for why an error is ignored:</p> <pre><code>// At-most once delivery.\\n// Hence, it's accepted to miss some of them in case of errors.\\n_ = notify()\\n</code></pre> <p> Source code</p>\"},{\"location\":\"#concurrency-foundations\",\"title\":\"Concurrency: Foundations\",\"text\":\"\"},{\"location\":\"#mixing-up-concurrency-and-parallelism-55\",\"title\":\"Mixing up concurrency and parallelism (#55)\",\"text\":\"TL;DR <p>Understanding the fundamental differences between concurrency and parallelism is a cornerstone of the Go developer\\u2019s knowledge. Concurrency is about structure, whereas parallelism is about execution.</p> <p>Concurrency and parallelism are not the same:</p> <ul> <li>Concurrency is about structure. We can change a sequential implementation into a concurrent one by introducing different steps that separate concurrent goroutines can tackle.</li> <li>Meanwhile, parallelism is about execution. We can use parallism at the steps level by adding more parallel goroutines.</li> </ul> <p>In summary, concurrency provides a structure to solve a problem with parts that may be parallelized. Therefore, concurrency enables parallelism.</p>\"},{\"location\":\"#thinking-concurrency-is-always-faster-56\",\"title\":\"Thinking concurrency is always faster (#56)\",\"text\":\"TL;DR <p>To be a proficient developer, you must acknowledge that concurrency isn\\u2019t always faster. Solutions involving parallelization of minimal workloads may not necessarily be faster than a sequential implementation. Benchmarking sequential versus concurrent solutions should be the way to validate assumptions.</p> <p>Read the full section here.</p> <p> Source code</p>\"},{\"location\":\"#being-puzzled-about-when-to-use-channels-or-mutexes-57\",\"title\":\"Being puzzled about when to use channels or mutexes (#57)\",\"text\":\"TL;DR <p>Being aware of goroutine interactions can also be helpful when deciding between channels and mutexes. In general, parallel goroutines require synchronization and hence mutexes. Conversely, concurrent goroutines generally require coordination and orchestration and hence channels.</p> <p>Given a concurrency problem, it may not always be clear whether we can implement a solution using channels or mutexes. Because Go promotes sharing memory by communication, one mistake could be to always force the use of channels, regardless of the use case. However, we should see the two options as complementary. </p> <p>When should we use channels or mutexes? We will use the example in the next figure as a backbone. Our example has three different goroutines with specific relationships:</p> <ul> <li>G1 and G2 are parallel goroutines. They may be two goroutines executing the same function that keeps receiving messages from a channel, or perhaps two goroutines executing the same HTTP handler at the same time.</li> <li>On the other hand, G1 and G3 are concurrent goroutines, as are G2 and G3. All the goroutines are part of an overall concurrent structure, but G1 and G2 perform the first step, whereas G3 does the next step.</li> </ul> <p>In general, parallel goroutines have to synchronize: for example, when they need to access or mutate a shared resource such as a slice. Synchronization is enforced with mutexes but not with any channel types (not with buffered channels). Hence, in general, synchronization between parallel goroutines should be achieved via mutexes.</p> <p>Conversely, in general, concurrent goroutines have to coordinate and orchestrate. For example, if G3 needs to aggregate results from both G1 and G2, G1 and G2 need to signal to G3 that a new intermediate result is available. This coordination falls under the scope of communication\\u2014therefore, channels.</p> <p>Regarding concurrent goroutines, there\\u2019s also the case where we want to transfer the ownership of a resource from one step (G1 and G2) to another (G3); for example, if G1 and G2 are enriching a shared resource and at some point, we consider this job as complete. Here, we should use channels to signal that a specific resource is ready and handle the ownership transfer.</p> <p>Mutexes and channels have different semantics. Whenever we want to share a state or access a shared resource, mutexes ensure exclusive access to this resource. Conversely, channels are a mechanic for signaling with or without data (<code>chan struct{}</code> or not). Coordination or ownership transfer should be achieved via channels. It\\u2019s important to know whether goroutines are parallel or concurrent because, in general, we need mutexes for parallel goroutines and channels for concurrent ones.</p>\"},{\"location\":\"#not-understanding-race-problems-data-races-vs-race-conditions-and-the-go-memory-model-58\",\"title\":\"Not understanding race problems (data races vs. race conditions and the Go memory model) (#58)\",\"text\":\"TL;DR <p>Being proficient in concurrency also means understanding that data races and race conditions are different concepts. Data races occur when multiple goroutines simultaneously access the same memory location and at least one of them is writing. Meanwhile, being data-race-free doesn\\u2019t necessarily mean deterministic execution. When a behavior depends on the sequence or the timing of events that can\\u2019t be controlled, this is a race condition.</p> <p>Race problems can be among the hardest and most insidious bugs a programmer can face. As Go developers, we must understand crucial aspects such as data races and race conditions, their possible impacts, and how to avoid them.</p>\"},{\"location\":\"#data-race\",\"title\":\"Data Race\",\"text\":\"<p>A data race occurs when two or more goroutines simultaneously access the same memory location and at least one is writing. In this case, the result can be hazardous. Even worse, in some situations, the memory location may end up holding a value containing a meaningless combination of bits.</p> <p>We can prevent a data race from happening using different techniques. For example: </p> <ul> <li>Using the <code>sync/atomic</code> package</li> <li>In synchronizing the two goroutines with an ad hoc data structure like a mutex</li> <li>Using channels to make the two goroutines communicating to ensure that a variable is updated by only one goroutine at a time</li> </ul>\"},{\"location\":\"#race-condition\",\"title\":\"Race Condition\",\"text\":\"<p>Depending on the operation we want to perform, does a data-race-free application necessarily mean a deterministic result? Not necessarily.</p> <p>A race condition occurs when the behavior depends on the sequence or the timing of events that can\\u2019t be controlled. Here, the timing of events is the goroutines\\u2019 execution order.</p> <p>In summary, when we work in concurrent applications, it\\u2019s essential to understand that a data race is different from a race condition. A data race occurs when multiple goroutines simultaneously access the same memory location and at least one of them is writing. A data race means unexpected behavior. However, a data-race-free application doesn\\u2019t necessarily mean deterministic results. An application can be free of data races but still have behavior that depends on uncontrolled events (such as goroutine execution, how fast a message is published to a channel, or how long a call to a database lasts); this is a race condition. Understanding both concepts is crucial to becoming proficient in designing concurrent applications.</p> <p> Source code</p>\"},{\"location\":\"#not-understanding-the-concurrency-impacts-of-a-workload-type-59\",\"title\":\"Not understanding the concurrency impacts of a workload type (#59)\",\"text\":\"TL;DR <p>When creating a certain number of goroutines, consider the workload type. Creating CPU-bound goroutines means bounding this number close to the GOMAXPROCS variable (based by default on the number of CPU cores on the host). Creating I/O-bound goroutines depends on other factors, such as the external system.</p> <p>In programming, the execution time of a workload is limited by one of the following:</p> <ul> <li>The speed of the CPU\\u2014For example, running a merge sort algorithm. The workload is called CPU-bound.</li> <li>The speed of I/O\\u2014For example, making a REST call or a database query. The workload is called I/O-bound.</li> <li>The amount of available memory\\u2014The workload is called memory-bound.</li> </ul> Note <p>The last is the rarest nowadays, given that memory has become very cheap in recent decades. Hence, this section focuses on the two first workload types: CPU- and I/O-bound.</p> <p>If the workload executed by the workers is I/O-bound, the value mainly depends on the external system. Conversely, if the workload is CPU-bound, the optimal number of goroutines is close to the number of available CPU cores (a best practice can be to use <code>runtime.GOMAXPROCS</code>). Knowing the workload type (I/O or CPU) is crucial when designing concurrent applications.</p> <p> Source code</p>\"},{\"location\":\"#misunderstanding-go-contexts-60\",\"title\":\"Misunderstanding Go contexts (#60)\",\"text\":\"TL;DR <p>Go contexts are also one of the cornerstones of concurrency in Go. A context allows you to carry a deadline, a cancellation signal, and/or a list of keys-values.</p> <p>https://pkg.go.dev/context</p> <p>A Context carries a deadline, a cancellation signal, and other values across API boundaries.</p>\"},{\"location\":\"#deadline\",\"title\":\"Deadline\",\"text\":\"<p>A deadline refers to a specific point in time determined with one of the following:</p> <ul> <li>A <code>time.Duration</code> from now (for example, in 250 ms)</li> <li>A <code>time.Time</code> (for example, 2023-02-07 00:00:00 UTC)</li> </ul> <p>The semantics of a deadline convey that an ongoing activity should be stopped if this deadline is met. An activity is, for example, an I/O request or a goroutine waiting to receive a message from a channel.</p>\"},{\"location\":\"#cancellation-signals\",\"title\":\"Cancellation signals\",\"text\":\"<p>Another use case for Go contexts is to carry a cancellation signal. Let\\u2019s imagine that we want to create an application that calls <code>CreateFileWatcher(ctx context.Context, filename string)</code> within another goroutine. This function creates a specific file watcher that keeps reading from a file and catches updates. When the provided context expires or is canceled, this function handles it to close the file descriptor.</p>\"},{\"location\":\"#context-values\",\"title\":\"Context values\",\"text\":\"<p>The last use case for Go contexts is to carry a key-value list. What\\u2019s the point of having a context carrying a key-value list? Because Go contexts are generic and mainstream, there are infinite use cases.</p> <p>For example, if we use tracing, we may want different subfunctions to share the same correlation ID. Some developers may consider this ID too invasive to be part of the function signature. In this regard, we could also decide to include it as part of the provided context.</p>\"},{\"location\":\"#catching-a-context-cancellation\",\"title\":\"Catching a context cancellation\",\"text\":\"<p>The <code>context.Context</code> type exports a <code>Done</code> method that returns a receive-only notification channel: <code>&lt;-chan struct{}</code>. This channel is closed when the work associated with the context should be canceled. For example,</p> <ul> <li>The Done channel related to a context created with <code>context.WithCancel</code> is closed when the cancel function is called.</li> <li>The Done channel related to a context created with <code>context.WithDeadline</code> is closed when the deadline has expired.</li> </ul> <p>One thing to note is that the internal channel should be closed when a context is canceled or has met a deadline, instead of when it receives a specific value, because the closure of a channel is the only channel action that all the consumer goroutines will receive. This way, all the consumers will be notified once a context is canceled or a deadline is reached.</p> <p>In summary, to be a proficient Go developer, we have to understand what a context is and how to use it. In general, a function that users wait for should take a context, as doing so allows upstream callers to decide when calling this function should be aborted. </p> <p> Source code</p>\"},{\"location\":\"#concurrency-practice\",\"title\":\"Concurrency: Practice\",\"text\":\"\"},{\"location\":\"#propagating-an-inappropriate-context-61\",\"title\":\"Propagating an inappropriate context (#61)\",\"text\":\"TL;DR <p>Understanding the conditions when a context can be canceled should matter when propagating it: for example, an HTTP handler canceling the context when the response has been sent.</p> <p>In many situations, it is recommended to propagate Go contexts. However, context propagation can sometimes lead to subtle bugs, preventing subfunctions from being correctly executed.</p> <p>Let\\u2019s consider the following example. We expose an HTTP handler that performs some tasks and returns a response. But just before returning the response, we also want to send it to a Kafka topic. We don\\u2019t want to penalize the HTTP consumer latency-wise, so we want the publish action to be handled asynchronously within a new goroutine. We assume that we have at our disposal a <code>publish</code> function that accepts a context so the action of publishing a message can be interrupted if the context is canceled, for example. Here is a possible implementation:</p> <pre><code>func handler(w http.ResponseWriter, r *http.Request) {\\n    response, err := doSomeTask(r.Context(), r)\\n    if err != nil {\\n        http.Error(w, err.Error(), http.StatusInternalServerError)\\n    return\\n    }\\n    go func() {\\n        err := publish(r.Context(), response)\\n        // Do something with err\\n    }()\\n    writeResponse(response)\\n}\\n</code></pre> <p>What\\u2019s wrong with this piece of code? We have to know that the context attached to an HTTP request can cancel in different conditions:</p> <ul> <li>When the client\\u2019s connection closes</li> <li>In the case of an HTTP/2 request, when the request is canceled</li> <li>When the response has been written back to the client</li> </ul> <p>In the first two cases, we probably handle things correctly. For example, if we get a response from doSomeTask but the client has closed the connection, it\\u2019s probably OK to call publish with a context already canceled so the message isn\\u2019t published. But what about the last case?</p> <p>When the response has been written to the client, the context associated with the request will be canceled. Therefore, we are facing a race condition:</p> <ul> <li>If the response is written after the Kafka publication, we both return a response and publish a message successfully</li> <li>However, if the response is written before or during the Kafka publication, the message shouldn\\u2019t be published.</li> </ul> <p>In the latter case, calling publish will return an error because we returned the HTTP response quickly.</p> Note <p>From Go 1.21, there is a way to create a new context without cancel. <code>context.WithoutCancel</code> returns a copy of parent that is not canceled when parent is canceled.</p> <p>In summary, propagating a context should be done cautiously.</p> <p> Source code</p>\"},{\"location\":\"#starting-a-goroutine-without-knowing-when-to-stop-it-62\",\"title\":\"Starting a goroutine without knowing when to stop it (#62)\",\"text\":\"TL;DR <p>Avoiding leaks means being mindful that whenever a goroutine is started, you should have a plan to stop it eventually.</p> <p>Goroutines are easy and cheap to start\\u2014so easy and cheap that we may not necessarily have a plan for when to stop a new goroutine, which can lead to leaks. Not knowing when to stop a goroutine is a design issue and a common concurrency mistake in Go.</p> <p>Let\\u2019s discuss a concrete example. We will design an application that needs to watch some external configuration (for example, using a database connection). Here\\u2019s a first implementation:</p> <pre><code>func main() {\\n    newWatcher()\\n    // Run the application\\n}\\n\\ntype watcher struct { /* Some resources */ }\\n\\nfunc newWatcher() {\\n    w := watcher{}\\n    go w.watch() // Creates a goroutine that watches some external configuration\\n}\\n</code></pre> <p>The problem with this code is that when the main goroutine exits (perhaps because of an OS signal or because it has a finite workload), the application is stopped. Hence, the resources created by watcher aren\\u2019t closed gracefully. How can we prevent this from happening?</p> <p>One option could be to pass to newWatcher a context that will be canceled when main returns:</p> <pre><code>func main() {\\n    ctx, cancel := context.WithCancel(context.Background())\\n    defer cancel()\\n    newWatcher(ctx)\\n    // Run the application\\n}\\n\\nfunc newWatcher(ctx context.Context) {\\n    w := watcher{}\\n    go w.watch(ctx)\\n}\\n</code></pre> <p>We propagate the context created to the watch method. When the context is canceled, the watcher struct should close its resources. However, can we guarantee that watch will have time to do so? Absolutely not\\u2014and that\\u2019s a design flaw.</p> <p>The problem is that we used signaling to convey that a goroutine had to be stopped. We didn\\u2019t block the parent goroutine until the resources had been closed.  Let\\u2019s make sure we do:</p> <pre><code>func main() {\\n    w := newWatcher()\\n    defer w.close()\\n    // Run the application\\n}\\n\\nfunc newWatcher() watcher {\\n    w := watcher{}\\n    go w.watch()\\n    return w\\n}\\n\\nfunc (w watcher) close() {\\n    // Close the resources\\n}\\n</code></pre> <p>Instead of signaling <code>watcher</code> that it\\u2019s time to close its resources, we now call this <code>close</code> method, using <code>defer</code> to guarantee that the resources are closed before the application exits.</p> <p>In summary, let\\u2019s be mindful that a goroutine is a resource like any other that must eventually be closed to free memory or other resources. Starting a goroutine without knowing when to stop it is a design issue. Whenever a goroutine is started, we should have a clear plan about when it will stop. Last but not least, if a goroutine creates resources and its lifetime is bound to the lifetime of the application, it\\u2019s probably safer to wait for this goroutine to complete before exiting the application. This way, we can ensure that the resources can be freed.</p> <p> Source code</p>\"},{\"location\":\"#not-being-careful-with-goroutines-and-loop-variables-63\",\"title\":\"Not being careful with goroutines and loop variables (#63)\",\"text\":\"Warning <p>This mistake isn't relevant anymore from Go 1.22 (details).</p>\"},{\"location\":\"#expecting-a-deterministic-behavior-using-select-and-channels-64\",\"title\":\"Expecting a deterministic behavior using select and channels (#64)\",\"text\":\"TL;DR <p>Understanding that <code>select</code> with multiple channels chooses the case randomly if multiple options are possible prevents making wrong assumptions that can lead to subtle concurrency bugs.</p> <p>One common mistake made by Go developers while working with channels is to make wrong assumptions about how select behaves with multiple channels.</p> <p>For example, let's consider the following case (<code>disconnectCh</code> is a unbuffered channel):</p> <pre><code>go func() {\\n  for i := 0; i &lt; 10; i++ {\\n      messageCh &lt;- i\\n    }\\n    disconnectCh &lt;- struct{}{}\\n}()\\n\\nfor {\\n    select {\\n    case v := &lt;-messageCh:\\n        fmt.Println(v)\\n    case &lt;-disconnectCh:\\n        fmt.Println(\\\"disconnection, return\\\")\\n        return\\n    }\\n}\\n</code></pre> <p>If we run this example multiple times, the result will be random:</p> <pre><code>0\\n1\\n2\\ndisconnection, return\\n\\n0\\ndisconnection, return\\n</code></pre> <p>Instead of consuming the 10 messages, we only received a few of them. What\\u2019s the reason? It lies in the specification of the select statement with multiple channels (https:// go.dev/ref/spec):</p> <p>Quote</p> <p>If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection.</p> <p>Unlike a switch statement, where the first case with a match wins, the select statement selects randomly if multiple options are possible.</p> <p>This behavior might look odd at first, but there\\u2019s a good reason for it: to prevent possible starvation. Suppose the first possible communication chosen is based on the source order. In that case, we may fall into a situation where, for example, we only receive from one channel because of a fast sender. To prevent this, the language designers decided to use a random selection.</p> <p>When using <code>select</code> with multiple channels, we must remember that if multiple options are possible, the first case in the source order does not automatically win. Instead, Go selects randomly, so there\\u2019s no guarantee about which option will be chosen. To overcome this behavior, in the case of a single producer goroutine, we can use either unbuffered channels or a single channel.</p> <p> Source code</p>\"},{\"location\":\"#not-using-notification-channels-65\",\"title\":\"Not using notification channels (#65)\",\"text\":\"TL;DR <p>Send notifications using a <code>chan struct{}</code> type.</p> <p>Channels are a mechanism for communicating across goroutines via signaling. A signal can be either with or without data.</p> <p>Let\\u2019s look at a concrete example. We will create a channel that will notify us whenever a certain disconnection occurs. One idea is to handle it as a <code>chan bool</code>:</p> <pre><code>disconnectCh := make(chan bool)\\n</code></pre> <p>Now, let\\u2019s say we interact with an API that provides us with such a channel. Because it\\u2019s a channel of Booleans, we can receive either <code>true</code> or <code>false</code> messages. It\\u2019s probably clear what <code>true</code> conveys. But what does <code>false</code> mean? Does it mean we haven\\u2019t been disconnected? And in this case, how frequently will we receive such a signal? Does it mean we have reconnected? Should we even expect to receive <code>false</code>? Perhaps we should only expect to receive <code>true</code> messages.</p> <p>If that\\u2019s the case, meaning we don\\u2019t need a specific value to convey some information, we need a channel without data. The idiomatic way to handle it is a channel of empty structs: <code>chan struct{}</code>.</p>\"},{\"location\":\"#not-using-nil-channels-66\",\"title\":\"Not using nil channels (#66)\",\"text\":\"TL;DR <p>Using nil channels should be part of your concurrency toolset because it allows you to remove cases from <code>select</code> statements, for example.</p> <p>What should this code do?</p> <pre><code>var ch chan int\\n&lt;-ch\\n</code></pre> <p><code>ch</code> is a <code>chan int</code> type. The zero value of a channel being nil, <code>ch</code> is <code>nil</code>. The goroutine won\\u2019t panic; however, it will block forever.</p> <p>The principle is the same if we send a message to a nil channel. This goroutine blocks forever:</p> <pre><code>var ch chan int\\nch &lt;- 0\\n</code></pre> <p>Then what\\u2019s the purpose of Go allowing messages to be received from or sent to a nil channel? For example, we can use nil channels to implement an idiomatic way to merge two channels:</p> <pre><code>func merge(ch1, ch2 &lt;-chan int) &lt;-chan int {\\n    ch := make(chan int, 1)\\n\\n    go func() {\\n        for ch1 != nil || ch2 != nil { // Continue if at least one channel isn\\u2019t nil\\n            select {\\n            case v, open := &lt;-ch1:\\n                if !open {\\n                    ch1 = nil // Assign ch1 to a nil channel once closed\\n                    break\\n                }\\n                ch &lt;- v\\n            case v, open := &lt;-ch2:\\n                if !open {\\n                    ch2 = nil // Assigns ch2 to a nil channel once closed\\n                    break\\n                }\\n                ch &lt;- v\\n            }\\n        }\\n        close(ch)\\n    }()\\n\\n    return ch\\n}\\n</code></pre> <p>This elegant solution relies on nil channels to somehow remove one case from the <code>select</code> statement.</p> <p>Let\\u2019s keep this idea in mind: nil channels are useful in some conditions and should be part of the Go developer\\u2019s toolset when dealing with concurrent code.</p> <p> Source code</p>\"},{\"location\":\"#being-puzzled-about-channel-size-67\",\"title\":\"Being puzzled about channel size (#67)\",\"text\":\"TL;DR <p>Carefully decide on the right channel type to use, given a problem. Only unbuffered channels provide strong synchronization guarantees. For buffered channels, you should have a good reason to specify a channel size other than one.</p> <p>An unbuffered channel is a channel without any capacity. It can be created by either omitting the size or providing a 0 size:</p> <pre><code>ch1 := make(chan int)\\nch2 := make(chan int, 0)\\n</code></pre> <p>With an unbuffered channel (sometimes called a synchronous channel), the sender will block until the receiver receives data from the channel.</p> <p>Conversely, a buffered channel has a capacity, and it must be created with a size greater than or equal to 1:</p> <pre><code>ch3 := make(chan int, 1)\\n</code></pre> <p>With a buffered channel, a sender can send messages while the channel isn\\u2019t full. Once the channel is full, it will block until a receiver goroutine receives a message:</p> <pre><code>ch3 := make(chan int, 1)\\nch3 &lt;-1 // Non-blocking\\nch3 &lt;-2 // Blocking\\n</code></pre> <p>The first send isn\\u2019t blocking, whereas the second one is, as the channel is full at this stage.</p> <p>What's the main difference between unbuffered and buffered channels:</p> <ul> <li>An unbuffered channel enables synchronization. We have the guarantee that two goroutines will be in a known state: one receiving and another sending a message.</li> <li>A buffered channel doesn\\u2019t provide any strong synchronization. Indeed, a producer goroutine can send a message and then continue its execution if the channel isn\\u2019t full. The only guarantee is that a goroutine won\\u2019t receive a message before it is sent. But this is only a guarantee because of causality (you don\\u2019t drink your coffee before you prepare it).</li> </ul> <p>If we need a buffered channel, what size should we provide?</p> <p>The default value we should use for buffered channels is its minimum: 1. So, we may approach the problem from this standpoint: is there any good reason not to use a value of 1? Here\\u2019s a list of possible cases where we should use another size:</p> <ul> <li>While using a worker pooling-like pattern, meaning spinning a fixed number of goroutines that need to send data to a shared channel. In that case, we can tie the channel size to the number of goroutines created.</li> <li>When using channels for rate-limiting problems. For example, if we need to enforce resource utilization by bounding the number of requests, we should set up the channel size according to the limit.</li> </ul> <p>If we are outside of these cases, using a different channel size should be done cautiously. Let\\u2019s bear in mind that deciding about an accurate queue size isn\\u2019t an easy problem:</p> <p>Martin Thompson</p> <p>Queues are typically always close to full or close to empty due to the differences in pace between consumers and producers. They very rarely operate in a balanced middle ground where the rate of production and consumption is evenly matched.</p>\"},{\"location\":\"#forgetting-about-possible-side-effects-with-string-formatting-68\",\"title\":\"Forgetting about possible side effects with string formatting (#68)\",\"text\":\"TL;DR <p>Being aware that string formatting may lead to calling existing functions means watching out for possible deadlocks and other data races.</p> <p>It\\u2019s pretty easy to forget the potential side effects of string formatting while working in a concurrent application.</p>\"},{\"location\":\"#etcd-data-race\",\"title\":\"etcd data race\",\"text\":\"<p>github.com/etcd-io/etcd/pull/7816 shows an example of an issue where a map's key was formatted based on a mutable values from a context.</p>\"},{\"location\":\"#deadlock\",\"title\":\"Deadlock\",\"text\":\"<p>Can you see what the problem is in this code with a <code>Customer</code> struct exposing an <code>UpdateAge</code> method and implementing the <code>fmt.Stringer</code> interface?</p> <pre><code>type Customer struct {\\n    mutex sync.RWMutex // Uses a sync.RWMutex to protect concurrent accesses\\n    id    string\\n    age   int\\n}\\n\\nfunc (c *Customer) UpdateAge(age int) error {\\n    c.mutex.Lock() // Locks and defers unlock as we update Customer\\n    defer c.mutex.Unlock()\\n\\n    if age &lt; 0 { // Returns an error if age is negative\\n        return fmt.Errorf(\\\"age should be positive for customer %v\\\", c)\\n    }\\n\\n    c.age = age\\n    return nil\\n}\\n\\nfunc (c *Customer) String() string {\\n    c.mutex.RLock() // Locks and defers unlock as we read Customer\\n    defer c.mutex.RUnlock()\\n    return fmt.Sprintf(\\\"id %s, age %d\\\", c.id, c.age)\\n}\\n</code></pre> <p>The problem here may not be straightforward. If the provided age is negative, we return an error. Because the error is formatted, using the <code>%s</code> directive on the receiver, it will call the <code>String</code> method to format <code>Customer</code>. But because <code>UpdateAge</code> already acquires the mutex lock, the <code>String</code> method won\\u2019t be able to acquire it. Hence, this leads to a deadlock situation. If all goroutines are also asleep, it leads to a panic.</p> <p>One possible solution is to restrict the scope of the mutex lock:</p> <pre><code>func (c *Customer) UpdateAge(age int) error {\\n    if age &lt; 0 {\\n        return fmt.Errorf(\\\"age should be positive for customer %v\\\", c)\\n    }\\n\\n    c.mutex.Lock()\\n    defer c.mutex.Unlock()\\n\\n    c.age = age\\n    return nil\\n}\\n</code></pre> <p>Yet, such an approach isn't always possible. In these conditions, we have to be extremely careful with string formatting.</p> <p>Another approach is to access the <code>id</code> field directly:</p> <pre><code>func (c *Customer) UpdateAge(age int) error {\\n    c.mutex.Lock()\\n    defer c.mutex.Unlock()\\n\\n    if age &lt; 0 {\\n        return fmt.Errorf(\\\"age should be positive for customer id %s\\\", c.id)\\n    }\\n\\n    c.age = age\\n    return nil\\n}\\n</code></pre> <p>In concurrent applications, we should remain cautious about the possible side effects of string formatting.</p> <p> Source code</p>\"},{\"location\":\"#creating-data-races-with-append-69\",\"title\":\"Creating data races with append (#69)\",\"text\":\"TL;DR <p>Calling <code>append</code> isn\\u2019t always data-race-free; hence, it shouldn\\u2019t be used concurrently on a shared slice.</p> <p>Should adding an element to a slice using <code>append</code> is data-race-free? Spoiler: it depends.</p> <p>Do you believe this example has a data race? </p> <pre><code>s := make([]int, 1)\\n\\ngo func() { // In a new goroutine, appends a new element on s\\n    s1 := append(s, 1)\\n    fmt.Println(s1)\\n}()\\n\\ngo func() { // Same\\n    s2 := append(s, 1)\\n    fmt.Println(s2)\\n}()\\n</code></pre> <p>The answer is no.</p> <p>In this example, we create a slice with <code>make([]int, 1)</code>. The code creates a one-length, one-capacity slice. Thus, because the slice is full, using append in each goroutine returns a slice backed by a new array. It doesn\\u2019t mutate the existing array; hence, it doesn\\u2019t lead to a data race.</p> <p>Now, let\\u2019s run the same example with a slight change in how we initialize <code>s</code>. Instead of creating a slice with a length of 1, we create it with a length of 0 but a capacity of 1. How about this new example? Does it contain a data race?</p> <pre><code>s := make([]int, 0, 1)\\n\\ngo func() { \\n    s1 := append(s, 1)\\n    fmt.Println(s1)\\n}()\\n\\ngo func() {\\n    s2 := append(s, 1)\\n    fmt.Println(s2)\\n}()\\n</code></pre> <p>The answer is yes. We create a slice with <code>make([]int, 0, 1)</code>. Therefore, the array isn\\u2019t full. Both goroutines attempt to update the same index of the backing array (index 1), which is a data race.</p> <p>How can we prevent the data race if we want both goroutines to work on a slice containing the initial elements of <code>s</code> plus an extra element? One solution is to create a copy of <code>s</code>.</p> <p>We should remember that using append on a shared slice in concurrent applications can lead to a data race. Hence, it should be avoided.</p> <p> Source code</p>\"},{\"location\":\"#using-mutexes-inaccurately-with-slices-and-maps-70\",\"title\":\"Using mutexes inaccurately with slices and maps (#70)\",\"text\":\"TL;DR <p>Remembering that slices and maps are pointers can prevent common data races.</p> <p>Let's implement a <code>Cache</code> struct used to handle caching for customer balances. This struct will contain a map of balances per customer ID and a mutex to protect concurrent accesses:</p> <pre><code>type Cache struct {\\n    mu       sync.RWMutex\\n    balances map[string]float64\\n}\\n</code></pre> <p>Next, we add an <code>AddBalance</code> method that mutates the <code>balances</code> map. The mutation is done in a critical section (within a mutex lock and a mutex unlock):</p> <pre><code>func (c *Cache) AddBalance(id string, balance float64) {\\n    c.mu.Lock()\\n    c.balances[id] = balance\\n    c.mu.Unlock()\\n}\\n</code></pre> <p>Meanwhile, we have to implement a method to calculate the average balance for all the customers. One idea is to handle a minimal critical section this way:</p> <pre><code>func (c *Cache) AverageBalance() float64 {\\n    c.mu.RLock()\\n    balances := c.balances // Creates a copy of the balances map\\n    c.mu.RUnlock()\\n\\n    sum := 0.\\n    for _, balance := range balances { // Iterates over the copy, outside of the critical section\\n        sum += balance\\n    }\\n    return sum / float64(len(balances))\\n}\\n</code></pre> <p>What's the problem with this code?</p> <p>If we run a test using the <code>-race</code> flag with two concurrent goroutines, one calling <code>AddBalance</code> (hence mutating balances) and another calling <code>AverageBalance</code>, a data race occurs. What\\u2019s the problem here?</p> <p>Internally, a map is a <code>runtime.hmap</code> struct containing mostly metadata (for example, a counter) and a pointer referencing data buckets. So, <code>balances := c.balances</code> doesn\\u2019t copy the actual data. Therefore, the two goroutines perform operations on the same data set, and one mutates it. Hence, it's a data race.</p> <p>One possible solution is to protect the whole <code>AverageBalance</code> function:</p> <pre><code>func (c *Cache) AverageBalance() float64 {\\n    c.mu.RLock()\\n    defer c.mu.RUnlock() // Unlocks when the function returns\\n\\n    sum := 0.\\n    for _, balance := range c.balances {\\n        sum += balance\\n    }\\n    return sum / float64(len(c.balances))\\n}\\n</code></pre> <p>Another option, if the iteration operation isn\\u2019t lightweight, is to work on an actual copy of the data and protect only the copy:</p> <pre><code>func (c *Cache) AverageBalance() float64 {\\n    c.mu.RLock()\\n    m := maps.Clone(c.balances)\\n    c.mu.RUnlock()\\n\\n    sum := 0.\\n    for _, balance := range m {\\n        sum += balance\\n    }\\n    return sum / float64(len(m))\\n}\\n</code></pre> <p>Once we have made a deep copy, we release the mutex. The iterations are done on the copy outside of the critical section.</p> <p>In summary, we have to be careful with the boundaries of a mutex lock. In this section, we have seen why assigning an existing map (or an existing slice) to a map isn\\u2019t enough to protect against data races. The new variable, whether a map or a slice, is backed by the same data set. There are two leading solutions to prevent this: protect the whole function, or work on a copy of the actual data. In all cases, let\\u2019s be cautious when designing critical sections and make sure the boundaries are accurately defined.</p> <p> Source code</p>\"},{\"location\":\"#misusing-syncwaitgroup-71\",\"title\":\"Misusing <code>sync.WaitGroup</code> (#71)\",\"text\":\"TL;DR <p>To accurately use <code>sync.WaitGroup</code>, call the <code>Add</code> method before spinning up goroutines.</p> <p>In the following example, we will initialize a wait group, start three goroutines that will update a counter atomically, and then wait for them to complete. We want to wait for these three goroutines to print the value of the counter (which should be 3):</p> <pre><code>wg := sync.WaitGroup{}\\nvar v uint64\\nfor i := 0; i &lt; 3; i++ {\\n    go func() {\\n        wg.Add(1)\\n        atomic.AddUint64(&amp;v, 1)\\n        wg.Done()\\n    }()\\n}\\nwg.Wait()\\nfmt.Println(v)\\n</code></pre> <p>If we run this example, we get a non-deterministic value: the code can print any value from 0 to 3. Also, if we enable the <code>-race</code> flag, Go will even catch a data race.</p> <p>The problem is that <code>wg.Add(1)</code> is called within the newly created goroutine, not in the parent goroutine. Hence, there is no guarantee that we have indicated to the wait group that we want to wait for three goroutines before calling <code>wg.Wait()</code>.</p> <p>To fix this issue, we can call <code>wg.Add</code> before the loop:</p> <pre><code>wg := sync.WaitGroup{}\\nvar v uint64\\nwg.Add(3)\\nfor i := 0; i &lt; 3; i++ {\\n    go func() {\\n        atomic.AddUint64(&amp;v, 1)\\n        wg.Done()\\n    }()\\n}\\nwg.Wait()\\nfmt.Println(v)\\n</code></pre> <p>Or inside the loop but not in the newly created goroutine:</p> <pre><code>wg := sync.WaitGroup{}\\nvar v uint64\\nfor i := 0; i &lt; 3; i++ {\\n    wg.Add(1)\\n    go func() {\\n        atomic.AddUint64(&amp;v, 1)\\n        wg.Done()\\n    }()\\n}\\nwg.Wait()\\nfmt.Println(v)\\n</code></pre> <p> Source code</p>\"},{\"location\":\"#forgetting-about-synccond-72\",\"title\":\"Forgetting about <code>sync.Cond</code> (#72)\",\"text\":\"TL;DR <p>You can send repeated notifications to multiple goroutines with <code>sync.Cond</code>.</p> <p> Source code</p>\"},{\"location\":\"#not-using-errgroup-73\",\"title\":\"Not using <code>errgroup</code> (#73)\",\"text\":\"TL;DR <p>You can synchronize a group of goroutines and handle errors and contexts with the <code>errgroup</code> package.</p> <p> Source code</p>\"},{\"location\":\"#copying-a-sync-type-74\",\"title\":\"Copying a <code>sync</code> type (#74)\",\"text\":\"TL;DR <p><code>sync</code> types shouldn\\u2019t be copied.</p> <p> Source code</p>\"},{\"location\":\"#standard-library\",\"title\":\"Standard Library\",\"text\":\"\"},{\"location\":\"#providing-a-wrong-time-duration-75\",\"title\":\"Providing a wrong time duration (#75)\",\"text\":\"TL;DR <p>Remain cautious with functions accepting a <code>time.Duration</code>. Even though passing an integer is allowed, strive to use the time API to prevent any possible confusion.</p> <p>Many common functions in the standard library accept a <code>time.Duration</code>, which is an alias for the <code>int64</code> type. However, one <code>time.Duration</code> unit represents one nanosecond, instead of one millisecond, as commonly seen in other programming languages. As a result, passing numeric types instead of using the <code>time.Duration</code> API can lead to unexpected behavior.</p> <p>A developer with experience in other languages might assume that the following code creates a new <code>time.Ticker</code> that delivers ticks every second, given the value <code>1000</code>:</p> <pre><code>ticker := time.NewTicker(1000)\\nfor {\\n    select {\\n    case &lt;-ticker.C:\\n        // Do something\\n    }\\n}\\n</code></pre> <p>However, because 1,000 <code>time.Duration</code> units = 1,000 nanoseconds, ticks are delivered every 1,000 nanoseconds = 1 microsecond, not every second as assumed.</p> <p>We should always use the <code>time.Duration</code> API to avoid confusion and unexpected behavior: </p><pre><code>ticker = time.NewTicker(time.Microsecond)\\n// Or\\nticker = time.NewTicker(1000 * time.Nanosecond)\\n</code></pre><p></p> <p> Source code</p>\"},{\"location\":\"#timeafter-and-memory-leaks-76\",\"title\":\"<code>time.After</code> and memory leaks (#76)\",\"text\":\"Warning <p>This mistake isn't relevant anymore from Go 1.23 (details).</p>\"},{\"location\":\"#json-handling-common-mistakes-77\",\"title\":\"JSON handling common mistakes (#77)\",\"text\":\"<ul> <li>Unexpected behavior because of type embedding</li> </ul> <p>Be careful about using embedded fields in Go structs. Doing so may lead to sneaky bugs like an embedded time.Time field implementing the <code>json.Marshaler</code> interface, hence overriding the default marshaling behavior.</p> <p> Source code</p> <ul> <li>JSON and the monotonic clock</li> </ul> <p>When comparing two <code>time.Time</code> structs, recall that <code>time.Time</code> contains both a wall clock and a monotonic clock, and the comparison using the == operator is done on both clocks.</p> <p> Source code</p> <ul> <li>Map of <code>any</code></li> </ul> <p>To avoid wrong assumptions when you provide a map while unmarshaling JSON data, remember that numerics are converted to <code>float64</code> by default.</p> <p> Source code</p>\"},{\"location\":\"#common-sql-mistakes-78\",\"title\":\"Common SQL mistakes (#78)\",\"text\":\"<ul> <li>Forgetting that <code>sql.Open</code> doesn't necessarily establish connections to a database</li> </ul> <p>Call the <code>Ping</code> or <code>PingContext</code> method if you need to test your configuration and make sure a database is reachable.</p> <p> Source code</p> <ul> <li>Forgetting about connections pooling</li> </ul> <p>Configure the database connection parameters for production-grade applications.</p> <ul> <li>Not using prepared statements</li> </ul> <p>Using SQL prepared statements makes queries more efficient and more secure.</p> <p> Source code</p> <ul> <li>Mishandling null values</li> </ul> <p>Deal with nullable columns in tables using pointers or <code>sql.NullXXX</code> types.</p> <p> Source code</p> <ul> <li>Not handling rows iteration errors</li> </ul> <p>Call the <code>Err</code> method of <code>sql.Rows</code> after row iterations to ensure that you haven\\u2019t missed an error while preparing the next row.</p> <p> Source code</p>\"},{\"location\":\"#not-closing-transient-resources-http-body-sqlrows-and-osfile-79\",\"title\":\"Not closing transient resources (HTTP body, <code>sql.Rows</code>, and <code>os.File</code>) (#79)\",\"text\":\"TL;DR <p>Eventually close all structs implementing <code>io.Closer</code> to avoid possible leaks.</p> <p> Source code</p>\"},{\"location\":\"#forgetting-the-return-statement-after-replying-to-an-http-request-80\",\"title\":\"Forgetting the return statement after replying to an HTTP request (#80)\",\"text\":\"TL;DR <p>To avoid unexpected behaviors in HTTP handler implementations, make sure you don\\u2019t miss the <code>return</code> statement if you want a handler to stop after <code>http.Error</code>.</p> <p>Consider the following HTTP handler that handles an error from <code>foo</code> using <code>http.Error</code>:</p> <pre><code>func handler(w http.ResponseWriter, req *http.Request) {\\n    err := foo(req)\\n    if err != nil {\\n        http.Error(w, \\\"foo\\\", http.StatusInternalServerError)\\n    }\\n\\n    _, _ = w.Write([]byte(\\\"all good\\\"))\\n    w.WriteHeader(http.StatusCreated)\\n}\\n</code></pre> <p>If we run this code and <code>err != nil</code>, the HTTP response would be:</p> <pre><code>foo\\nall good\\n</code></pre> <p>The response contains both the error and success messages, and also the first HTTP status code, 500. There would also be a warning log indicating that we attempted to write the status code multiple times:</p> <pre><code>2023/10/10 16:45:33 http: superfluous response.WriteHeader call from main.handler (main.go:20)\\n</code></pre> <p>The mistake in this code is that <code>http.Error</code> does not stop the handler's execution, which means the success message and status code get written in addition to the error. Beyond an incorrect response, failing to return after writing an error can lead to the unwanted execution of code and unexpected side-effects. The following code adds the <code>return</code> statement following the <code>http.Error</code> and exhibits the desired behavior when ran:</p> <pre><code>func handler(w http.ResponseWriter, req *http.Request) {\\n    err := foo(req)\\n    if err != nil {\\n        http.Error(w, \\\"foo\\\", http.StatusInternalServerError)\\n        return // Adds the return statement\\n    }\\n\\n    _, _ = w.Write([]byte(\\\"all good\\\"))\\n    w.WriteHeader(http.StatusCreated)\\n}\\n</code></pre> <p> Source code</p>\"},{\"location\":\"#using-the-default-http-client-and-server-81\",\"title\":\"Using the default HTTP client and server (#81)\",\"text\":\"TL;DR <p>For production-grade applications, don\\u2019t use the default HTTP client and server implementations. These implementations are missing timeouts and behaviors that should be mandatory in production.</p> <p> Source code</p>\"},{\"location\":\"#testing\",\"title\":\"Testing\",\"text\":\"\"},{\"location\":\"#not-categorizing-tests-build-tags-environment-variables-and-short-mode-82\",\"title\":\"Not categorizing tests (build tags, environment variables, and short mode) (#82)\",\"text\":\"TL;DR <p>Categorizing tests using build flags, environment variables, or short mode makes the testing process more efficient. You can create test categories using build flags or environment variables (for example, unit versus integration tests) and differentiate short from long-running tests to decide which kinds of tests to execute.</p> <p> Source code</p>\"},{\"location\":\"#not-enabling-the-race-flag-83\",\"title\":\"Not enabling the race flag (#83)\",\"text\":\"TL;DR <p>Enabling the <code>-race</code> flag is highly recommended when writing concurrent applications. Doing so allows you to catch potential data races that can lead to software bugs.</p> <p>In Go, the race detector isn\\u2019t a static analysis tool used during compilation; instead, it\\u2019s a tool to find data races that occur at runtime. To enable it, we have to enable the -race flag while compiling or running a test. For example:</p> <pre><code>go test -race ./...\\n</code></pre> <p>Once the race detector is enabled, the compiler instruments the code to detect data races. Instrumentation refers to a compiler adding extra instructions: here, tracking all memory accesses and recording when and how they occur.</p> <p>Enabling the race detector adds an overhead in terms of memory and execution time; hence, it's generally recommended to enable it only during local testing or continuous integration, not production.</p> <p>If a race is detected, Go raises a warning. For example:</p> <pre><code>package main\\n\\nimport (\\n    \\\"fmt\\\"\\n)\\n\\nfunc main() {\\n    i := 0\\n    go func() { i++ }()\\n    fmt.Println(i)\\n}\\n</code></pre> <p>Running this code with the <code>-race</code> logs the following warning:</p> <pre><code>==================\\nWARNING: DATA RACE\\nWrite at 0x00c000026078 by goroutine 7: # (1)\\n  main.main.func1()\\n      /tmp/app/main.go:9 +0x4e\\n\\nPrevious read at 0x00c000026078 by main goroutine: # (2)\\n  main.main()\\n      /tmp/app/main.go:10 +0x88\\n\\nGoroutine 7 (running) created at: # (3)\\n  main.main()\\n      /tmp/app/main.go:9 +0x7a\\n==================\\n</code></pre> <ol> <li>Indicates that goroutine 7 was writing</li> <li>Indicates that the main goroutine was reading</li> <li>Indicates when the goroutine 7 was created</li> </ol> <p>Let\\u2019s make sure we are comfortable reading these messages. Go always logs the following:</p> <ul> <li>The concurrent goroutines that are incriminated: here, the main goroutine and goroutine 7.</li> <li>Where accesses occur in the code: in this case, lines 9 and 10.</li> <li>When these goroutines were created: goroutine 7 was created in main().</li> </ul> <p>In addition, if a specific file contains tests that lead to data races, we can exclude it  from race detection using the <code>!race</code> build tag:</p> <pre><code>//go:build !race\\n\\npackage main\\n\\nimport (\\n    \\\"testing\\\"\\n)\\n\\nfunc TestFoo(t *testing.T) {\\n    // ...\\n}\\n</code></pre>\"},{\"location\":\"#not-using-test-execution-modes-parallel-and-shuffle-84\",\"title\":\"Not using test execution modes (parallel and shuffle) (#84)\",\"text\":\"TL;DR <p>Using the <code>-parallel</code> flag is an efficient way to speed up tests, especially long-running ones. Use the <code>-shuffle</code> flag to help ensure that a test suite doesn\\u2019t rely on wrong assumptions that could hide bugs.</p>\"},{\"location\":\"#not-using-table-driven-tests-85\",\"title\":\"Not using table-driven tests (#85)\",\"text\":\"TL;DR <p>Table-driven tests are an efficient way to group a set of similar tests to prevent code duplication and make future updates easier to handle.</p> <p> Source code</p>\"},{\"location\":\"#sleeping-in-unit-tests-86\",\"title\":\"Sleeping in unit tests (#86)\",\"text\":\"TL;DR <p>Avoid sleeps using synchronization to make a test less flaky and more robust. If synchronization isn\\u2019t possible, consider a retry approach.</p> <p> Source code</p>\"},{\"location\":\"#not-dealing-with-the-time-api-efficiently-87\",\"title\":\"Not dealing with the time API efficiently (#87)\",\"text\":\"TL;DR <p>Understanding how to deal with functions using the time API is another way to make a test less flaky. You can use standard techniques such as handling the time as part of a hidden dependency or asking clients to provide it.</p> <p> Source code</p>\"},{\"location\":\"#not-using-testing-utility-packages-httptest-and-iotest-88\",\"title\":\"Not using testing utility packages (<code>httptest</code> and <code>iotest</code>) (#88)\",\"text\":\"<ul> <li>The <code>httptest</code> package is helpful for dealing with HTTP applications. It provides a set of utilities to test both clients and servers.</li> </ul> <p> Source code</p> <ul> <li>The <code>iotest</code> package helps write io.Reader and test that an application is tolerant to errors.</li> </ul> <p> Source code</p>\"},{\"location\":\"#writing-inaccurate-benchmarks-89\",\"title\":\"Writing inaccurate benchmarks (#89)\",\"text\":\"TL;DR <p>Regarding benchmarks:</p> <ul> <li>Use time methods to preserve the accuracy of a benchmark.</li> <li>Increasing benchtime or using tools such as benchstat can be helpful when dealing with micro-benchmarks.</li> <li>Be careful with the results of a micro-benchmark if the system that ends up running the application is different from the one running the micro-benchmark.</li> <li>Make sure the function under test leads to a side effect, to prevent compiler optimizations from fooling you about the benchmark results.</li> <li>To prevent the observer effect, force a benchmark to re-create the data used by a CPU-bound function.</li> </ul> <p>Read the full section here.</p> <p> Source code</p>\"},{\"location\":\"#not-exploring-all-the-go-testing-features-90\",\"title\":\"Not exploring all the Go testing features (#90)\",\"text\":\"<ul> <li>Code coverage</li> </ul> <p>Use code coverage with the <code>-coverprofile</code> flag to quickly see which part of the code needs more attention.</p> <ul> <li>Testing from a different package</li> </ul> <p>Place unit tests in a different package to enforce writing tests that focus on an exposed behavior, not internals.</p> <p> Source code</p> <ul> <li>Utility functions</li> </ul> <p>Handling errors using the <code>*testing.T</code> variable instead of the classic <code>if err != nil</code> makes code shorter and easier to read.</p> <p> Source code</p> <ul> <li>Setup and teardown</li> </ul> <p>You can use setup and teardown functions to configure a complex environment, such as in the case of integration tests.</p> <p> Source code</p>\"},{\"location\":\"#not-using-fuzzing-community-mistake\",\"title\":\"Not using fuzzing (community mistake)\",\"text\":\"TL;DR <p>Fuzzing is an efficient strategy to detect random, unexpected, or malformed inputs to complex functions and methods in order to discover vulnerabilities, bugs, or even potential crashes.</p> <p>Credits: @jeromedoucet</p>\"},{\"location\":\"#optimizations\",\"title\":\"Optimizations\",\"text\":\"\"},{\"location\":\"#not-understanding-cpu-caches-91\",\"title\":\"Not understanding CPU caches (#91)\",\"text\":\"<ul> <li>CPU architecture</li> </ul> <p>Understanding how to use CPU caches is important for optimizing CPU-bound applications because the L1 cache is about 50 to 100 times faster than the main memory.</p> <ul> <li>Cache line</li> </ul> <p>Being conscious of the cache line concept is critical to understanding how to organize data in data-intensive applications. A CPU doesn\\u2019t fetch memory word by word; instead, it usually copies a memory block to a 64-byte cache line. To get the most out of each individual cache line, enforce spatial locality.</p> <p> Source code</p> <ul> <li>Slice of structs vs. struct of slices</li> </ul> <p> Source code</p> <ul> <li>Predictability</li> </ul> <p>Making code predictable for the CPU can also be an efficient way to optimize certain functions. For example, a unit or constant stride is predictable for the CPU, but a non-unit stride (for example, a linked list) isn\\u2019t predictable.</p> <p> Source code</p> <ul> <li>Cache placement policy</li> </ul> <p>To avoid a critical stride, hence utilizing only a tiny portion of the cache, be aware that caches are partitioned.</p>\"},{\"location\":\"#writing-concurrent-code-that-leads-to-false-sharing-92\",\"title\":\"Writing concurrent code that leads to false sharing (#92)\",\"text\":\"TL;DR <p>Knowing that lower levels of CPU caches aren\\u2019t shared across all the cores helps avoid performance-degrading patterns such as false sharing while writing concurrency code. Sharing memory is an illusion.</p> <p>Read the full section here.</p> <p> Source code</p>\"},{\"location\":\"#not-taking-into-account-instruction-level-parallelism-93\",\"title\":\"Not taking into account instruction-level parallelism (#93)\",\"text\":\"TL;DR <p>Use ILP to optimize specific parts of your code to allow a CPU to execute as many parallel instructions as possible. Identifying data hazards is one of the main steps.</p> <p> Source code</p>\"},{\"location\":\"#not-being-aware-of-data-alignment-94\",\"title\":\"Not being aware of data alignment (#94)\",\"text\":\"TL;DR <p>You can avoid common mistakes by remembering that in Go, basic types are aligned with their own size. For example, keep in mind that reorganizing the fields of a struct by size in descending order can lead to more compact structs (less memory allocation and potentially a better spatial locality).</p> <p> Source code</p>\"},{\"location\":\"#not-understanding-stack-vs-heap-95\",\"title\":\"Not understanding stack vs. heap (#95)\",\"text\":\"TL;DR <p>Understanding the fundamental differences between heap and stack should also be part of your core knowledge when optimizing a Go application. Stack allocations are almost free, whereas heap allocations are slower and rely on the GC to clean the memory.</p> <p> Source code</p>\"},{\"location\":\"#not-knowing-how-to-reduce-allocations-api-change-compiler-optimizations-and-syncpool-96\",\"title\":\"Not knowing how to reduce allocations (API change, compiler optimizations, and <code>sync.Pool</code>) (#96)\",\"text\":\"TL;DR <p>Reducing allocations is also an essential aspect of optimizing a Go application. This can be done in different ways, such as designing the API carefully to prevent sharing up, understanding the common Go compiler optimizations, and using <code>sync.Pool</code>.</p> <p> Source code</p>\"},{\"location\":\"#not-relying-on-inlining-97\",\"title\":\"Not relying on inlining (#97)\",\"text\":\"TL;DR <p>Use the fast-path inlining technique to efficiently reduce the amortized time to call a function.</p>\"},{\"location\":\"#not-using-go-diagnostics-tooling-98\",\"title\":\"Not using Go diagnostics tooling (#98)\",\"text\":\"TL;DR <p>Rely on profiling and the execution tracer to understand how an application performs and the parts to optimize.</p> <p>Read the full section here.</p>\"},{\"location\":\"#not-understanding-how-the-gc-works-99\",\"title\":\"Not understanding how the GC works (#99)\",\"text\":\"TL;DR <p>Understanding how to tune the GC can lead to multiple benefits such as handling sudden load increases more efficiently.</p>\"},{\"location\":\"#not-understanding-the-impacts-of-running-go-in-docker-and-kubernetes-100\",\"title\":\"Not understanding the impacts of running Go in Docker and Kubernetes (#100)\",\"text\":\"Warning <p>This mistake isn't relevant anymore from Go 1.25 (details).</p>\"},{\"location\":\"#community\",\"title\":\"Community\",\"text\":\"<p>Thanks to all the contributors:</p> <p> </p>\"},{\"location\":\"#powered-by\",\"title\":\"Powered by\",\"text\":\"\"},{\"location\":\"20-slice/\",\"title\":\"Not understanding slice length and capacity (#20)\",\"text\":\"\"},{\"location\":\"20-slice/#not-understanding-slice-length-and-capacity\",\"title\":\"Not understanding slice length and capacity\",\"text\":\"<p>It\\u2019s pretty common for Go developers to mix slice length and capacity or not understand them thoroughly. Assimilating these two concepts is essential for efficiently handling core operations such as slice initialization and adding elements with append, copying, or slicing. This misunderstanding can lead to using slices suboptimally or even to memory leaks.</p> <p>In Go, a slice is backed by an array. That means the slice\\u2019s data is stored contiguously in an array data structure. A slice also handles the logic of adding an element if the backing array is full or shrinking the backing array if it\\u2019s almost empty.</p> <p>Internally, a slice holds a pointer to the backing array plus a length and a capacity. The length is the number of elements the slice contains, whereas the capacity is the number of elements in the backing array, counting from the first element in the slice. Let\\u2019s go through a few examples to make things clearer. First, let\\u2019s initialize a slice with a given length and capacity:</p> <pre><code>s := make([]int, 3, 6) // Three-length, six-capacity slice\\n</code></pre> <p>The first argument, representing the length, is mandatory. However, the second argument representing the capacity is optional. Figure 1 shows the result of this code in memory.</p> <p> </p> Figure 1: A three-length, six-capacity slice. <p>In this case, <code>make</code> creates an array of six elements (the capacity). But because the length was set to 3, Go initializes only the first three elements. Also, because the slice is an <code>[]int</code> type, the first three elements are initialized to the zeroed value of an <code>int</code>: 0. The grayed elements are allocated but not yet used.</p> <p>If we print this slice, we get the elements within the range of the length, <code>[0 0 0]</code>. If we set <code>s[1]</code> to 1, the second element of the slice updates without impacting its length or capacity. Figure 2 illustrates this.</p> <p> </p> Figure 2: Updating the slice\\u2019s second element: s[1] = 1. <p>However, accessing an element outside the length range is forbidden, even though it\\u2019s already allocated in memory. For example, <code>s[4]</code> = 0 would lead to the following panic:</p> <pre><code>panic: runtime error: index out of range [4] with length 3\\n</code></pre> <p>How can we use the remaining space of the slice? By using the <code>append</code> built-in function:</p> <pre><code>s = append(s, 2)\\n</code></pre> <p>This code appends to the existing <code>s</code> slice a new element. It uses the first grayed element (which was allocated but not yet used) to store element 2, as figure 3 shows.</p> <p> </p> Figure 3: Appending an element to s. <p>The length of the slice is updated from 3 to 4 because the slice now contains four elements. Now, what happens if we add three more elements so that the backing array isn\\u2019t large enough?</p> <pre><code>s = append(s, 3, 4, 5)\\nfmt.Println(s)\\n</code></pre> <p>If we run this code, we see that the slice was able to cope with our request:</p> <pre><code>[0 1 0 2 3 4 5]\\n</code></pre> <p>Because an array is a fixed-size structure, it can store the new elements until element 4. When we want to insert element 5, the array is already full: Go internally creates another array by doubling the capacity, copying all the elements, and then inserting element 5. Figure 4 shows this process.</p> <p> </p> Figure 4: Because the initial backing array is full, Go creates another array and copies all the elements. <p>The slice now references the new backing array. What will happen to the previous backing array? If it\\u2019s no longer referenced, it\\u2019s eventually freed by the garbage collector (GC) if allocated on the heap. (We discuss heap memory in mistake #95, \\u201cNot understanding stack vs. heap,\\u201d and we look at how the GC works in mistake #99, \\u201cNot understanding how the GC works.\\u201d)</p> <p>What happens with slicing? Slicing is an operation done on an array or a slice, providing a half-open range; the first index is included, whereas the second is excluded. The following example shows the impact, and figure 5 displays the result in memory:</p> <pre><code>s1 := make([]int, 3, 6) // Three-length, six-capacity slice\\ns2 := s1[1:3] // Slicing from indices 1 to 3\\n</code></pre> <p> </p> Figure 5: The slices s1 and s2 reference the same backing array with different lengths and capacities. <p>First, <code>s1</code> is created as a three-length, six-capacity slice. When <code>s2</code> is created by slicing <code>s1</code>, both slices reference the same backing array. However, <code>s2</code> starts from a different index, 1. Therefore, its length and capacity (a two-length, five-capacity slice) differ from s1. If we update <code>s1[1]</code> or <code>s2[0]</code>, the change is made to the same array, hence, visible in both slices, as figure 6 shows.</p> <p> </p> Figure 6: Because s1 and s2 are backed by the same array, updating a common element makes the change visible in both slices. <p>Now, what happens if we append an element to <code>s2</code>? Does the following code change <code>s1</code> as well?</p> <pre><code>s2 = append(s2, 2)\\n</code></pre> <p>The shared backing array is modified, but only the length of <code>s2</code> changes. Figure 7 shows the result of appending an element to <code>s2</code>.</p> <p> </p> Figure 7: Appending an element to s2. <p><code>s1</code> remains a three-length, six-capacity slice. Therefore, if we print <code>s1</code> and <code>s2</code>, the added element is only visible for <code>s2</code>:</p> <pre><code>s1=[0 1 0], s2=[1 0 2]\\n</code></pre> <p>It\\u2019s important to understand this behavior so that we don\\u2019t make wrong assumptions while using append.</p> Note <p>In these examples, the backing array is internal and not available directly to the Go developer. The only exception is when a slice is created from slicing an existing array.</p> <p>One last thing to note: what if we keep appending elements to <code>s2</code> until the backing array is full? What will the state be, memory-wise? Let\\u2019s add three more elements so that the backing array will not have enough capacity:</p> <pre><code>s2 = append(s2, 3)\\ns2 = append(s2, 4) // At this stage, the backing is already full\\ns2 = append(s2, 5)\\n</code></pre> <p>This code leads to creating another backing array. Figure 8 displays the results in memory.</p> <p> </p> Figure 8: Appending elements to s2 until the backing array is full. <p><code>s1</code> and <code>s2</code> now reference two different arrays. As <code>s1</code> is still a three-length, six-capacity slice, it still has some available buffer, so it keeps referencing the initial array. Also, the new backing array was made by copying the initial one from the first index of <code>s2</code>. That\\u2019s why the new array starts with element 1, not 0.</p> <p>To summarize, the slice length is the number of available elements in the slice, whereas the slice capacity is the number of elements in the backing array. Adding an element to a full slice (length == capacity) leads to creating a new backing array with a new capacity, copying all the elements from the previous array, and updating the slice pointer to the new array.</p>\"},{\"location\":\"28-maps-memory-leaks/\",\"title\":\"Maps and memory leaks (#28)\",\"text\":\"\"},{\"location\":\"28-maps-memory-leaks/#maps-and-memory-leaks\",\"title\":\"Maps and memory leaks\",\"text\":\"<p>When working with maps in Go, we need to understand some important characteristics of how a map grows and shrinks. Let\\u2019s delve into this to prevent issues that can cause memory leaks.</p> <p>First, to view a concrete example of this problem, let\\u2019s design a scenario where we will work with the following map:</p> <pre><code>m := make(map[int][128]byte)\\n</code></pre> <p>Each value of m is an array of 128 bytes. We will do the following:</p> <ol> <li>Allocate an empty map.</li> <li>Add 1 million elements.</li> <li>Remove all the elements, and run a Garbage Collection (GC).</li> </ol> <p>After each step, we want to print the size of the heap (using a <code>printAlloc</code> utility function). This shows us how this example behaves memory-wise:</p> <pre><code>func main() {\\n    n := 1_000_000\\n    m := make(map[int][128]byte)\\n    printAlloc()\\n\\n    for i := 0; i &lt; n; i++ { // Adds 1 million elements\\n        m[i] = [128]byte{}\\n    }\\n    printAlloc()\\n\\n    for i := 0; i &lt; n; i++ { // Deletes 1 million elements\\n        delete(m, i)\\n    }\\n\\n    runtime.GC() // Triggers a manual GC\\n    printAlloc()\\n    runtime.KeepAlive(m) // Keeps a reference to m so that the map isn\\u2019t collected\\n}\\n\\nfunc printAlloc() {\\n    var m runtime.MemStats\\n    runtime.ReadMemStats(&amp;m)\\n    fmt.Printf(\\\"%d MB\\\\n\\\", m.Alloc/(1024*1024))\\n}\\n</code></pre> <p>We allocate an empty map, add 1 million elements, remove 1 million elements, and then run a GC. We also make sure to keep a reference to the map using <code>runtime.KeepAlive</code> so that the map isn\\u2019t collected as well. Let\\u2019s run this example:</p> <pre><code>0 MB   &lt;-- After m is allocated\\n461 MB &lt;-- After we add 1 million elements\\n293 MB &lt;-- After we remove 1 million elements\\n</code></pre> <p>What can we observe? At first, the heap size is minimal. Then it grows significantly after having added 1 million elements to the map. But if we expected the heap size to decrease after removing all the elements, this isn\\u2019t how maps work in Go. In the end, even though the GC has collected all the elements, the heap size is still 293 MB. So the memory shrunk, but not as we might have expected. What\\u2019s the rationale? We need to delve into how a map works in Go.</p> <p>A map provides an unordered collection of key-value pairs in which all the keys are distinct. In Go, a map is based on the hash table data structure: an array where each element is a pointer to a bucket of key-value pairs, as shown in figure 1.</p> <p> </p> Figure 1: A hash table example with a focus on bucket 0. <p>Each bucket is a fixed-size array of eight elements. In the case of an insertion into a bucket that is already full (a bucket overflow), Go creates another bucket of eight elements and links the previous one to it. Figure 2 shows an example:</p> <p> </p> Figure 2: In case of a bucket overflow, Go allocates a new bucket and links the previous bucket to it. <p>Under the hood, a Go map is a pointer to a runtime.hmap struct. This struct contains multiple fields, including a B field, giving the number of buckets in the map:</p> <pre><code>type hmap struct {\\n    B uint8 // log_2 of # of buckets\\n            // (can hold up to loadFactor * 2^B items)\\n    // ...\\n}\\n</code></pre> <p>After adding 1 million elements, the value of B equals 18, which means 2\\u00b9\\u2078 = 262,144 buckets. When we remove 1 million elements, what\\u2019s the value of B? Still 18. Hence, the map still contains the same number of buckets.</p> <p>The reason is that the number of buckets in a map cannot shrink. Therefore, removing elements from a map doesn\\u2019t impact the number of existing buckets; it just zeroes the slots in the buckets. A map can only grow and have more buckets; it never shrinks.</p> <p>In the previous example, we went from 461 MB to 293 MB because the elements were collected, but running the GC didn\\u2019t impact the map itself. Even the number of extra buckets (the buckets created because of overflows) remains the same.</p> <p>Let\\u2019s take a step back and discuss when the fact that a map cannot shrink can be a problem. Imagine building a cache using a <code>map[int][128]byte</code>. This map holds per customer ID (the <code>int</code>), a sequence of 128 bytes. Now, suppose we want to save the last 1,000 customers. The map size will remain constant, so we shouldn\\u2019t worry about the fact that a map cannot shrink.</p> <p>However, let\\u2019s say we want to store one hour of data. Meanwhile, our company has decided to have a big promotion for Black Friday: in one hour, we may have millions of customers connected to our system. But a few days after Black Friday, our map will contain the same number of buckets as during the peak time. This explains why we can experience high memory consumption that doesn\\u2019t significantly decrease in such a scenario.</p> <p>What are the solutions if we don\\u2019t want to manually restart our service to clean the amount of memory consumed by the map? One solution could be to re-create a copy of the current map at a regular pace. For example, every hour, we can build a new map, copy all the elements, and release the previous one. The main drawback of this option is that following the copy and until the next garbage collection, we may consume twice the current memory for a short period.</p> <p>Another solution would be to change the map type to store an array pointer: <code>map[int]*[128]byte</code>. It doesn\\u2019t solve the fact that we will have a significant number of buckets; however, each bucket entry will reserve the size of a pointer for the value instead of 128 bytes (8 bytes on 64-bit systems and 4 bytes on 32-bit systems).</p> <p>Coming back to the original scenario, let\\u2019s compare the memory consumption for each map type following each step. The following table shows the comparison.</p> Step <code>map[int][128]byte</code> <code>map[int]*[128]byte</code> Allocate an empty map 0 MB 0 MB Add 1 million elements 461 MB 182 MB Remove all the elements and run a GC 293 MB 38 MB Note <p>If a key or a value is over 128 bytes, Go won\\u2019t store it directly in the map bucket. Instead, Go stores a pointer to reference the key or the value.</p> <p>As we have seen, adding n elements to a map and then deleting all the elements means keeping the same number of buckets in memory. So, we must remember that because a Go map can only grow in size, so does its memory consumption. There is no automated strategy to shrink it. If this leads to high memory consumption, we can try different options such as forcing Go to re-create the map or using pointers to check if it can be optimized.</p>\"},{\"location\":\"5-interface-pollution/\",\"title\":\"Interface pollution (#5)\",\"text\":\"\"},{\"location\":\"5-interface-pollution/#interface-pollution\",\"title\":\"Interface pollution\",\"text\":\"<p>Interfaces are one of the cornerstones of the Go language when designing and structuring our code. However, like many tools or concepts, abusing them is generally not a good idea. Interface pollution is about overwhelming our code with unnecessary abstractions, making it harder to understand. It\\u2019s a common mistake made by developers coming from another language with different habits. Before delving into the topic, let\\u2019s refresh our minds about Go\\u2019s interfaces. Then, we will see when it\\u2019s appropriate to use interfaces and when it may be considered pollution.</p>\"},{\"location\":\"5-interface-pollution/#concepts\",\"title\":\"Concepts\",\"text\":\"<p>An interface provides a way to specify the behavior of an object. We use interfaces to create common abstractions that multiple objects can implement. What makes Go interfaces so different is that they are satisfied implicitly. There is no explicit keyword like <code>implements</code> to mark that an object X implements interface Y.</p> <p>To understand what makes interfaces so powerful, we will dig into two popular ones from the standard library: <code>io.Reader</code> and <code>io.Writer</code>. The <code>io</code> package provides abstractions for I/O primitives. Among these abstractions, <code>io.Reader</code> relates to reading data from a data source and <code>io.Writer</code> to writing data to a target, as represented in the next figure:</p> <p></p> <p>The <code>io.Reader</code> contains a single Read method:</p> <pre><code>type Reader interface {\\n    Read(p []byte) (n int, err error)\\n}\\n</code></pre> <p>Custom implementations of the <code>io.Reader</code> interface should accept a slice of bytes, filling it with its data and returning either the number of bytes read or an error.</p> <p>On the other hand, <code>io.Writer</code> defines a single method, Write:</p> <pre><code>type Writer interface {\\n    Write(p []byte) (n int, err error)\\n}\\n</code></pre> <p>Custom implementations of <code>io.Writer</code> should write the data coming from a slice to a target and return either the number of bytes written or an error. Therefore, both interfaces provide fundamental abstractions:</p> <ul> <li><code>io.Reader</code> reads data from a source</li> <li><code>io.Writer</code> writes data to a target</li> </ul> <p>What is the rationale for having these two interfaces in the language? What is the point of creating these abstractions?</p> <p>Let\\u2019s assume we need to implement a function that should copy the content of one file to another. We could create a specific function that would take as input two <code>*os.File</code>. Or, we can choose to create a more generic function using <code>io.Reader</code> and <code>io.Writer</code> abstractions:</p> <pre><code>func copySourceToDest(source io.Reader, dest io.Writer) error {\\n    // ...\\n}\\n</code></pre> <p>This function would work with <code>*os.File</code> parameters (as <code>*os.File</code> implements both <code>io.Reader</code> and <code>io.Writer</code>) and any other type that would implement these interfaces. For example, we could create our own <code>io.Writer</code> that writes to a database, and the code would remain the same. It increases the genericity of the function; hence, its reusability.</p> <p>Furthermore, writing a unit test for this function is easier because, instead of having to handle files, we can use the <code>strings</code> and <code>bytes</code> packages that provide helpful implementations:</p> <pre><code>func TestCopySourceToDest(t *testing.T) {\\n    const input = \\\"foo\\\"\\n    source := strings.NewReader(input) // Creates an io.Reader\\n    dest := bytes.NewBuffer(make([]byte, 0)) // Creates an io.Writer\\n\\n    err := copySourceToDest(source, dest) // Calls copySourceToDest from a *strings.Reader and a *bytes.Buffer\\n    if err != nil {\\n        t.FailNow()\\n    }\\n\\n    got := dest.String()\\n    if got != input {\\n        t.Errorf(\\\"expected: %s, got: %s\\\", input, got)\\n    }\\n}\\n</code></pre> <p>In the example, source is a <code>*strings.Reader</code>, whereas dest is a <code>*bytes.Buffer</code>. Here, we test the behavior of <code>copySourceToDest</code> without creating any files.</p> <p>While designing interfaces, the granularity (how many methods the interface contains) is also something to keep in mind. A known proverb in Go relates to how big an interface should be:</p> <p>Rob Pike</p> <p>The bigger the interface, the weaker the abstraction.</p> <p>Indeed, adding methods to an interface can decrease its level of reusability. <code>io.Reader</code> and <code>io.Writer</code> are powerful abstractions because they cannot get any simpler. Furthermore, we can also combine fine-grained interfaces to create higher-level abstractions. This is the case with <code>io.ReadWriter</code>, which combines the reader and writer behaviors:</p> <pre><code>type ReadWriter interface {\\n    Reader\\n    Writer\\n}\\n</code></pre> Note <p>As Einstein said, \\u201cEverything should be made as simple as possible, but no simpler.\\u201d Applied to interfaces, this denotes that finding the perfect granularity for an interface isn\\u2019t necessarily a straightforward process.</p> <p>Let\\u2019s now discuss common cases where interfaces are recommended.</p>\"},{\"location\":\"5-interface-pollution/#when-to-use-interfaces\",\"title\":\"When to use interfaces\",\"text\":\"<p>When should we create interfaces in Go? Let\\u2019s look at three concrete use cases where interfaces are usually considered to bring value. Note that the goal isn\\u2019t to be exhaustive because the more cases we add, the more they would depend on the context. However, these three cases should give us a general idea:</p> <ul> <li>Common behavior </li> <li>Decoupling</li> <li>Restricting behavior</li> </ul>\"},{\"location\":\"5-interface-pollution/#common-behavior\",\"title\":\"Common behavior\",\"text\":\"<p>The first option we will discuss is to use interfaces when multiple types implement a common behavior. In such a case, we can factor out the behavior inside an interface. If we look at the standard library, we can find many examples of such a use case. For example, sorting a collection can be factored out via three methods:</p> <ul> <li>Retrieving the number of elements in the collection</li> <li>Reporting whether one element must be sorted before another </li> <li>Swapping two elements</li> </ul> <p>Hence, the following interface was added to the <code>sort</code> package:</p> <pre><code>type Interface interface {\\n    Len() int // Number of elements\\n    Less(i, j int) bool // Checks two elements\\n    Swap(i, j int) // Swaps two elements\\n}\\n</code></pre> <p>This interface has a strong potential for reusability because it encompasses the common behavior to sort any collection that is index-based.</p> <p>Throughout the <code>sort</code> package, we can find dozens of implementations. If at some point we compute a collection of integers, for example, and we want to sort it, are we necessarily interested in the implementation type? Is it important whether the sorting algorithm is a merge sort or a quicksort? In many cases, we don\\u2019t care. Hence, the sorting behavior can be abstracted, and we can depend on the <code>sort.Interface</code>.</p> <p>Finding the right abstraction to factor out a behavior can also bring many benefits. For example, the <code>sort</code> package provides utility functions that also rely on <code>sort.Interface</code>, such as checking whether a collection is already sorted. For instance:</p> <pre><code>func IsSorted(data Interface) bool {\\n    n := data.Len()\\n    for i := n - 1; i &gt; 0; i-- {\\n        if data.Less(i, i-1) {\\n            return false\\n        }\\n    }\\n    return true\\n}\\n</code></pre> <p>Because <code>sort.Interface</code> is the right level of abstraction, it makes it highly valuable.</p> <p>Let\\u2019s now see another main use case when using interfaces.</p>\"},{\"location\":\"5-interface-pollution/#decoupling\",\"title\":\"Decoupling\",\"text\":\"<p>Another important use case is about decoupling our code from an implementation. If we rely on an abstraction instead of a concrete implementation, the implementation itself can be replaced with another without even having to change our code. This is the Liskov Substitution Principle (the L in Robert C. Martin\\u2019s SOLID design principles).</p> <p>One benefit of decoupling can be related to unit testing. Let\\u2019s assume we want to implement a <code>CreateNewCustomer</code> method that creates a new customer and stores it. We decide to rely on the concrete implementation directly (let\\u2019s say a <code>mysql.Store</code> struct):</p> <pre><code>type CustomerService struct {\\n    store mysql.Store // Depends on the concrete implementation\\n}\\n\\nfunc (cs CustomerService) CreateNewCustomer(id string) error {\\n    customer := Customer{id: id}\\n    return cs.store.StoreCustomer(customer)\\n}\\n</code></pre> <p>Now, what if we want to test this method? Because <code>customerService</code> relies on the actual implementation to store a <code>Customer</code>, we are obliged to test it through integration tests, which requires spinning up a MySQL instance (unless we use an alternative technique such as <code>go-sqlmock</code>, but this isn\\u2019t the scope of this section). Although integration tests are helpful, that\\u2019s not always what we want to do. To give us more flexibility, we should decouple <code>CustomerService</code> from the actual implementation, which can be done via an interface like so:</p> <pre><code>type customerStorer interface { // Creates a storage abstraction\\n    StoreCustomer(Customer) error\\n}\\n\\ntype CustomerService struct {\\n    storer customerStorer // Decouples CustomerService from the actual implementation\\n}\\n\\nfunc (cs CustomerService) CreateNewCustomer(id string) error {\\n    customer := Customer{id: id}\\n    return cs.storer.StoreCustomer(customer)\\n}\\n</code></pre> <p>Because storing a customer is now done via an interface, this gives us more flexibility in how we want to test the method. For instance, we can:</p> <ul> <li>Use the concrete implementation via integration tests </li> <li>Use a mock (or any kind of test double) via unit tests </li> <li>Or both</li> </ul> <p>Let\\u2019s now discuss another use case: to restrict a behavior.</p>\"},{\"location\":\"5-interface-pollution/#restricting-behavior\",\"title\":\"Restricting behavior\",\"text\":\"<p>The last use case we will discuss can be pretty counterintuitive at first sight. It\\u2019s about restricting a type to a specific behavior. Let\\u2019s imagine we implement a custom configuration package to deal with dynamic configuration. We create a specific container for <code>int</code> configurations via an <code>IntConfig</code> struct that also exposes two methods: <code>Get</code> and <code>Set</code>. Here\\u2019s how that code would look:</p> <pre><code>type IntConfig struct {\\n    // ...\\n}\\n\\nfunc (c *IntConfig) Get() int {\\n    // Retrieve configuration\\n}\\n\\nfunc (c *IntConfig) Set(value int) {\\n    // Update configuration\\n}\\n</code></pre> <p>Now, suppose we receive an <code>IntConfig</code> that holds some specific configuration, such as a threshold. Yet, in our code, we are only interested in retrieving the configuration value, and we want to prevent updating it. How can we enforce that, semantically, this configuration is read-only, if we don\\u2019t want to change our configuration package? By creating an abstraction that restricts the behavior to retrieving only a config value:</p> <pre><code>type intConfigGetter interface {\\n    Get() int\\n}\\n</code></pre> <p>Then, in our code, we can rely on <code>intConfigGetter</code> instead of the concrete implementation:</p> <pre><code>type Foo struct {\\n    threshold intConfigGetter\\n}\\n\\nfunc NewFoo(threshold intConfigGetter) Foo { // Injects the configuration getter\\n    return Foo{threshold: threshold}\\n}\\n\\nfunc (f Foo) Bar()  {\\n    threshold := f.threshold.Get() // Reads the configuration\\n    // ...\\n}\\n</code></pre> <p>In this example, the configuration getter is injected into the <code>NewFoo</code> factory method. It doesn\\u2019t impact a client of this function because it can still pass an <code>IntConfig</code> struct as it implements <code>intConfigGetter</code>. Then, we can only read the configuration in the <code>Bar</code> method, not modify it. Therefore, we can also use interfaces to restrict a type to a specific behavior for various reasons, such as semantics enforcement.</p> <p>In this section, we saw three potential use cases where interfaces are generally considered as bringing value: factoring out a common behavior, creating some decoupling, and restricting a type to a certain behavior. Again, this list isn\\u2019t exhaustive, but it should give us a general understanding of when interfaces are helpful in Go.</p> <p>Now, let\\u2019s finish this section and discuss the problems with interface pollution.</p>\"},{\"location\":\"5-interface-pollution/#interface-pollution_1\",\"title\":\"Interface pollution\",\"text\":\"<p>It\\u2019s fairly common to see interfaces being overused in Go projects. Perhaps the developer\\u2019s background was C# or Java, and they found it natural to create interfaces before concrete types. However, this isn\\u2019t how things should work in Go.</p> <p>As we discussed, interfaces are made to create abstractions. And the main caveat when programming meets abstractions is remembering that abstractions should be discovered, not created. What does this mean? It means we shouldn\\u2019t start creating abstractions in our code if there is no immediate reason to do so. We shouldn\\u2019t design with interfaces but wait for a concrete need. Said differently, we should create an interface when we need it, not when we foresee that we could need it.</p> <p>What\\u2019s the main problem if we overuse interfaces? The answer is that they make the code flow more complex. Adding a useless level of indirection doesn\\u2019t bring any value; it creates a worthless abstraction making the code more difficult to read, understand, and reason about. If we don\\u2019t have a strong reason for adding an interface and it\\u2019s unclear how an interface makes a code better, we should challenge this interface\\u2019s purpose. Why not call the implementation directly?</p> Note <p>We may also experience performance overhead when calling a method through an interface. It requires a lookup in a hash table\\u2019s data structure to find the concrete type an interface points to. But this isn\\u2019t an issue in many contexts as the overhead is minimal.</p> <p>In summary, we should be cautious when creating abstractions in our code\\u2014abstractions should be discovered, not created. It\\u2019s common for us, software developers, to overengineer our code by trying to guess what the perfect level of abstraction is, based on what we think we might need later. This process should be avoided because, in most cases, it pollutes our code with unnecessary abstractions, making it more complex to read.</p> <p>Rob Pike</p> <p>Don\\u2019t design with interfaces, discover them.</p> <p>Let\\u2019s not try to solve a problem abstractly but solve what has to be solved now. Last, but not least, if it\\u2019s unclear how an interface makes the code better, we should probably consider removing it to make our code simpler.</p>\"},{\"location\":\"56-concurrency-faster/\",\"title\":\"Thinking concurrency is always faster (#56)\",\"text\":\"\"},{\"location\":\"56-concurrency-faster/#thinking-concurrency-is-always-faster\",\"title\":\"Thinking concurrency is always faster\",\"text\":\"<p>A misconception among many developers is believing that a concurrent solution is always faster than a sequential one. This couldn\\u2019t be more wrong. The overall performance of a solution depends on many factors, such as the efficiency of our code structure (concurrency), which parts can be tackled in parallel, and the level of contention among the computation units. This post reminds us about some fundamental knowledge of concurrency in Go; then we will see a concrete example where a concurrent solution isn\\u2019t necessarily faster.</p>\"},{\"location\":\"56-concurrency-faster/#go-scheduling\",\"title\":\"Go Scheduling\",\"text\":\"<p>A thread is the smallest unit of processing that an OS can perform. If a process wants to execute multiple actions simultaneously, it spins up multiple threads. These threads can be:</p> <ul> <li>Concurrent \\u2014 Two or more threads can start, run, and complete in overlapping time periods.</li> <li>Parallel \\u2014 The same task can be executed multiple times at once.</li> </ul> <p>The OS is responsible for scheduling the thread\\u2019s processes optimally so that:</p> <ul> <li>All the threads can consume CPU cycles without being starved for too much time.</li> <li>The workload is distributed as evenly as possible among the different CPU cores.</li> </ul> Note <p>The word thread can also have a different meaning at a CPU level. Each physical core can be composed of multiple logical cores (the concept of hyper-threading), and a logical core is also called a thread. In this post, when we use the word thread, we mean the unit of processing, not a logical core.</p> <p>A CPU core executes different threads. When it switches from one thread to another, it executes an operation called context switching. The active thread consuming CPU cycles was in an executing state and moves to a runnable state, meaning it\\u2019s ready to be executed pending an available core. Context switching is considered an expensive operation because the OS needs to save the current execution state of a thread before the switch (such as the current register values).</p> <p>As Go developers, we can\\u2019t create threads directly, but we can create goroutines, which can be thought of as application-level threads. However, whereas an OS thread is context-switched on and off a CPU core by the OS, a goroutine is context-switched on and off an OS thread by the Go runtime. Also, compared to an OS thread, a goroutine has a smaller memory footprint: 2 KB for goroutines from Go 1.4. An OS thread depends on the OS, but, for example, on Linux/x86\\u201332, the default size is 2 MB (see https://man7.org/linux/man-pages/man3/pthread_create.3.html). Having a smaller size makes context switching faster.</p> Note <p>Context switching a goroutine versus a thread is about 80% to 90% faster, depending on the architecture.</p> <p>Let\\u2019s now discuss how the Go scheduler works to overview how goroutines are handled. Internally, the Go scheduler uses the following terminology (see proc.go):</p> <ul> <li>G \\u2014 Goroutine</li> <li>M \\u2014 OS thread (stands for machine)</li> <li>P \\u2014 CPU core (stands for processor)</li> </ul> <p>Each OS thread (M) is assigned to a CPU core (P) by the OS scheduler. Then, each goroutine (G) runs on an M. The GOMAXPROCS variable defines the limit of Ms in charge of executing user-level code simultaneously. But if a thread is blocked in a system call (for example, I/O), the scheduler can spin up more Ms. As of Go 1.5, GOMAXPROCS is by default equal to the number of available CPU cores.</p> <p>A goroutine has a simpler lifecycle than an OS thread. It can be doing one of the following:</p> <ul> <li>Executing \\u2014 The goroutine is scheduled on an M and executing its instructions.</li> <li>Runnable \\u2014 The goroutine is waiting to be in an executing state.</li> <li>Waiting \\u2014 The goroutine is stopped and pending something completing, such as a system call or a synchronization operation (such as acquiring a mutex).</li> </ul> <p>There\\u2019s one last stage to understand about the implementation of Go scheduling: when a goroutine is created but cannot be executed yet; for example, all the other Ms are already executing a G. In this scenario, what will the Go runtime do about it? The answer is queuing. The Go runtime handles two kinds of queues: one local queue per P and a global queue shared among all the Ps.</p> <p>Figure 1 shows a given scheduling situation on a four-core machine with GOMAXPROCS equal to 4. The parts are the logical cores (Ps), goroutines (Gs), OS threads (Ms), local queues, and global queue:</p> <p> </p> Figure 1: An example of the current state of a Go application executed on a four-core machine. Goroutines that aren\\u2019t in an executing state are either runnable (pending being executed) or waiting (pending a blocking operation) <p>First, we can see five Ms, whereas GOMAXPROCS is set to 4. But as we mentioned, if needed, the Go runtime can create more OS threads than the GOMAXPROCS value.</p> <p>P0, P1, and P3 are currently busy executing Go runtime threads. But P2 is presently idle as M3 is switched off P2, and there\\u2019s no goroutine to be executed. This isn\\u2019t a good situation because six runnable goroutines are pending being executed, some in the global queue and some in other local queues. How will the Go runtime handle this situation? Here\\u2019s the scheduling implementation in pseudocode (see proc.go):</p> <pre><code>runtime.schedule() {\\n    // Only 1/61 of the time, check the global runnable queue for a G.\\n    // If not found, check the local queue.\\n    // If not found,\\n    //     Try to steal from other Ps.\\n    //     If not, check the global runnable queue.\\n    //     If not found, poll network.\\n}\\n</code></pre> <p>Every sixty-first execution, the Go scheduler will check whether goroutines from the global queue are available. If not, it will check its local queue. Meanwhile, if both the global and local queues are empty, the Go scheduler can pick up goroutines from other local queues. This principle in scheduling is called work stealing, and it allows an underutilized processor to actively look for another processor\\u2019s goroutines and steal some.</p> <p>One last important thing to mention: prior to Go 1.14, the scheduler was cooperative, which meant a goroutine could be context-switched off a thread only in specific blocking cases (for example, channel send or receive, I/O, waiting to acquire a mutex). Since Go 1.14, the Go scheduler is now preemptive: when a goroutine is running for a specific amount of time (10 ms), it will be marked preemptible and can be context-switched off to be replaced by another goroutine. This allows a long-running job to be forced to share CPU time.</p> <p>Now that we understand the fundamentals of scheduling in Go, let\\u2019s look at a concrete example: implementing a merge sort in a parallel manner.</p>\"},{\"location\":\"56-concurrency-faster/#parallel-merge-sort\",\"title\":\"Parallel Merge Sort\",\"text\":\"<p>First, let\\u2019s briefly review how the merge sort algorithm works. Then we will implement a parallel version. Note that the objective isn\\u2019t to implement the most efficient version but to support a concrete example showing why concurrency isn\\u2019t always faster.</p> <p>The merge sort algorithm works by breaking a list repeatedly into two sublists until each sublist consists of a single element and then merging these sublists so that the result is a sorted list (see figure 2). Each split operation splits the list into two sublists, whereas the merge operation merges two sublists into a sorted list.</p> <p> </p> Figure 2: Applying the merge sort algorithm repeatedly breaks each list into two sublists. Then the algorithm uses a merge operation such that the resulting list is sorted <p>Here is the sequential implementation of this algorithm. We don\\u2019t include all of the code as it\\u2019s not the main point of this section:</p> <pre><code>func sequentialMergesort(s []int) {\\n    if len(s) &lt;= 1 {\\n        return\\n    }\\n\\n    middle := len(s) / 2\\n    sequentialMergesort(s[:middle]) // First half\\n    sequentialMergesort(s[middle:]) // Second half\\n    merge(s, middle) // Merges the two halves\\n}\\n\\nfunc merge(s []int, middle int) {\\n    // ...\\n}\\n</code></pre> <p>This algorithm has a structure that makes it open to concurrency. Indeed, as each sequentialMergesort operation works on an independent set of data that doesn\\u2019t need to be fully copied (here, an independent view of the underlying array using slicing), we could distribute this workload among the CPU cores by spinning up each sequentialMergesort operation in a different goroutine. Let\\u2019s write a first parallel implementation:</p> <pre><code>func parallelMergesortV1(s []int) {\\n    if len(s) &lt;= 1 {\\n        return\\n    }\\n\\n    middle := len(s) / 2\\n\\n    var wg sync.WaitGroup\\n    wg.Add(2)\\n\\n    go func() { // Spins up the first half of the work in a goroutine\\n        defer wg.Done()\\n        parallelMergesortV1(s[:middle])\\n    }()\\n\\n    go func() { // Spins up the second half of the work in a goroutine\\n        defer wg.Done()\\n        parallelMergesortV1(s[middle:])\\n    }()\\n\\n    wg.Wait()\\n    merge(s, middle) // Merges the halves\\n}\\n</code></pre> <p>In this version, each half of the workload is handled in a separate goroutine. The parent goroutine waits for both parts by using sync.WaitGroup. Hence, we call the Wait method before the merge operation.</p> <p>We now have a parallel version of the merge sort algorithm. Therefore, if we run a benchmark to compare this version against the sequential one, the parallel version should be faster, correct? Let\\u2019s run it on a four-core machine with 10,000 elements:</p> <pre><code>Benchmark_sequentialMergesort-4       2278993555 ns/op\\nBenchmark_parallelMergesortV1-4      17525998709 ns/op\\n</code></pre> <p>Surprisingly, the parallel version is almost an order of magnitude slower. How can we explain this result? How is it possible that a parallel version that distributes a workload across four cores is slower than a sequential version running on a single machine? Let\\u2019s analyze the problem.</p> <p>If we have a slice of, say, 1,024 elements, the parent goroutine will spin up two goroutines, each in charge of handling a half consisting of 512 elements. Each of these goroutines will spin up two new goroutines in charge of handling 256 elements, then 128, and so on, until we spin up a goroutine to compute a single element.</p> <p>If the workload that we want to parallelize is too small, meaning we\\u2019re going to compute it too fast, the benefit of distributing a job across cores is destroyed: the time it takes to create a goroutine and have the scheduler execute it is much too high compared to directly merging a tiny number of items in the current goroutine. Although goroutines are lightweight and faster to start than threads, we can still face cases where a workload is too small.</p> <p>So what can we conclude from this result? Does it mean the merge sort algorithm cannot be parallelized? Wait, not so fast.</p> <p>Let\\u2019s try another approach. Because merging a tiny number of elements within a new goroutine isn\\u2019t efficient, let\\u2019s define a threshold. This threshold will represent how many elements a half should contain in order to be handled in a parallel manner. If the number of elements in the half is fewer than this value, we will handle it sequentially. Here\\u2019s a new version:</p> <pre><code>const max = 2048 // Defines the threshold\\n\\nfunc parallelMergesortV2(s []int) {\\n    if len(s) &lt;= 1 {\\n        return\\n    }\\n\\n    if len(s) &lt;= max {\\n        sequentialMergesort(s) // Calls our initial sequential version\\n    } else { // If bigger than the threshold, keeps the parallel version\\n        middle := len(s) / 2\\n\\n        var wg sync.WaitGroup\\n        wg.Add(2)\\n\\n        go func() {\\n            defer wg.Done()\\n            parallelMergesortV2(s[:middle])\\n        }()\\n\\n        go func() {\\n            defer wg.Done()\\n            parallelMergesortV2(s[middle:])\\n        }()\\n\\n        wg.Wait()\\n        merge(s, middle)\\n    }\\n}\\n</code></pre> <p>If the number of elements in the s slice is smaller than max, we call the sequential version. Otherwise, we keep calling our parallel implementation. Does this approach impact the result? Yes, it does:</p> <pre><code>Benchmark_sequentialMergesort-4       2278993555 ns/op\\nBenchmark_parallelMergesortV1-4      17525998709 ns/op\\nBenchmark_parallelMergesortV2-4       1313010260 ns/op\\n</code></pre> <p>Our v2 parallel implementation is more than 40% faster than the sequential one, thanks to this idea of defining a threshold to indicate when parallel should be more efficient than sequential.</p> Note <p>Why did I set the threshold to 2,048? Because it was the optimal value for this specific workload on my machine. In general, such magic values should be defined carefully with benchmarks (running on an execution environment similar to production). It\\u2019s also pretty interesting to note that running the same algorithm in a programming language that doesn\\u2019t implement the concept of goroutines has an impact on the value. For example, running the same example in Java using threads means an optimal value closer to 8,192. This tends to illustrate how goroutines are more efficient than threads.</p>\"},{\"location\":\"56-concurrency-faster/#conclusion\",\"title\":\"Conclusion\",\"text\":\"<p>We have seen throughout this post the fundamental concepts of scheduling in Go: the differences between a thread and a goroutine and how the Go runtime schedules goroutines. Meanwhile, using the parallel merge sort example, we illustrated that concurrency isn\\u2019t always necessarily faster. As we have seen, spinning up goroutines to handle minimal workloads (merging only a small set of elements) demolishes the benefit we could get from parallelism.</p> <p>So, where should we go from here? We must keep in mind that concurrency isn\\u2019t always faster and shouldn\\u2019t be considered the default way to go for all problems. First, it makes things more complex. Also, modern CPUs have become incredibly efficient at executing sequential code and predictable code. For example, a superscalar processor can parallelize instruction execution over a single core with high efficiency.</p> <p>Does this mean we shouldn\\u2019t use concurrency? Of course not. However, it\\u2019s essential to keep these conclusions in mind. If we\\u2019re not sure that a parallel version will be faster, the right approach may be to start with a simple sequential version and build from there using profiling (mistake #98, \\u201cNot using Go diagnostics tooling\\u201d) and benchmarks (mistake #89, \\u201cWriting inaccurate benchmarks\\u201d), for example. It can be the only way to ensure that a concurrent implementation is worth it.</p>\"},{\"location\":\"89-benchmarks/\",\"title\":\"Writing inaccurate benchmarks (#89)\",\"text\":\"\"},{\"location\":\"89-benchmarks/#writing-inaccurate-benchmarks\",\"title\":\"Writing inaccurate benchmarks\",\"text\":\"<p>In general, we should never guess about performance. When writing optimizations, so many factors may come into play that even if we have a strong opinion about the results, it\\u2019s rarely a bad idea to test them. However, writing benchmarks isn\\u2019t straightforward. It can be pretty simple to write inaccurate benchmarks and make wrong assumptions based on them. The goal of this post is to examine four common and concrete traps leading to inaccuracy:</p> <ul> <li>Not resetting or pausing the timer</li> <li>Making wrong assumptions about micro-benchmarks</li> <li>Not being careful about compiler optimizations</li> <li>Being fooled by the observer effect</li> </ul>\"},{\"location\":\"89-benchmarks/#general-concepts\",\"title\":\"General concepts\",\"text\":\"<p>Before discussing these traps, let\\u2019s briefly review how benchmarks work in Go. The skeleton of a benchmark is as follows:</p> <pre><code>func BenchmarkFoo(b *testing.B) {\\n    for i := 0; i &lt; b.N; i++ {\\n        foo()\\n    }\\n}\\n</code></pre> <p>The function name starts with the <code>Benchmark</code> prefix. The function under test (foo) is called within the <code>for</code> loop. <code>b.N</code> represents a variable number of iterations. When running a benchmark, Go tries to make it match the requested benchmark time. The benchmark time is set by default to 1 second and can be changed with the <code>-benchtime</code> flag. <code>b.N</code> starts at 1; if the benchmark completes in under 1 second, <code>b.N</code> is increased, and the benchmark runs again until <code>b.N</code> roughly matches benchtime:</p> <pre><code>$ go test -bench=.\\ncpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\\nBenchmarkFoo-4                73          16511228 ns/op\\n</code></pre> <p>Here, the benchmark took about 1 second, and <code>foo</code> was executed 73 times, for an average execution time of 16,511,228 nanoseconds. We can change the benchmark time using <code>-benchtime</code>:</p> <pre><code>$ go test -bench=. -benchtime=2s\\nBenchmarkFoo-4               150          15832169 ns/op\\n</code></pre> <p><code>foo</code> was executed roughly twice more than during the previous benchmark.</p> <p>Next, let\\u2019s look at some common traps.</p>\"},{\"location\":\"89-benchmarks/#not-resetting-or-pausing-the-timer\",\"title\":\"Not resetting or pausing the timer\",\"text\":\"<p>In some cases, we need to perform operations before the benchmark loop. These operations may take quite a while (for example, generating a large slice of data) and may significantly impact the benchmark results:</p> <pre><code>func BenchmarkFoo(b *testing.B) {\\n    expensiveSetup()\\n    for i := 0; i &lt; b.N; i++ {\\n        functionUnderTest()\\n    }\\n}\\n</code></pre> <p>In this case, we can use the <code>ResetTimer</code> method before entering the loop:</p> <pre><code>func BenchmarkFoo(b *testing.B) {\\n    expensiveSetup()\\n    b.ResetTimer() // Reset the benchmark timer\\n    for i := 0; i &lt; b.N; i++ {\\n        functionUnderTest()\\n    }\\n}\\n</code></pre> <p>Calling <code>ResetTimer</code> zeroes the elapsed benchmark time and memory allocation counters since the beginning of the test. This way, an expensive setup can be discarded from the test results.</p> <p>What if we have to perform an expensive setup not just once but within each loop iteration?</p> <pre><code>func BenchmarkFoo(b *testing.B) {\\n    for i := 0; i &lt; b.N; i++ {\\n        expensiveSetup()\\n        functionUnderTest()\\n    }\\n}\\n</code></pre> <p>We can\\u2019t reset the timer, because that would be executed during each loop iteration. But we can stop and resume the benchmark timer, surrounding the call to <code>expensiveSetup</code>:</p> <pre><code>func BenchmarkFoo(b *testing.B) {\\n    for i := 0; i &lt; b.N; i++ {\\n        b.StopTimer() // Pause the benchmark timer\\n        expensiveSetup()\\n        b.StartTimer() // Resume the benchmark timer\\n        functionUnderTest()\\n    }\\n}\\n</code></pre> <p>Here, we pause the benchmark timer to perform the expensive setup and then resume the timer.</p> Note <p>There\\u2019s one catch to remember about this approach: if the function under test is too fast to execute compared to the setup function, the benchmark may take too long to complete. The reason is that it would take much longer than 1 second to reach <code>benchtime</code>. Calculating the benchmark time is based solely on the execution time of <code>functionUnderTest</code>. So, if we wait a significant time in each loop iteration, the benchmark will be much slower than 1 second. If we want to keep the benchmark, one possible mitigation is to decrease <code>benchtime</code>.</p> <p>We must be sure to use the timer methods to preserve the accuracy of a benchmark.</p>\"},{\"location\":\"89-benchmarks/#making-wrong-assumptions-about-micro-benchmarks\",\"title\":\"Making wrong assumptions about micro-benchmarks\",\"text\":\"<p>A micro-benchmark measures a tiny computation unit, and it can be extremely easy to make wrong assumptions about it. Let\\u2019s say, for example, that we aren\\u2019t sure whether to use <code>atomic.StoreInt32</code> or <code>atomic.StoreInt64</code> (assuming that the values we handle will always fit in 32 bits). We want to write a benchmark to compare both functions:</p> <pre><code>func BenchmarkAtomicStoreInt32(b *testing.B) {\\n    var v int32\\n    for i := 0; i &lt; b.N; i++ {\\n        atomic.StoreInt32(&amp;v, 1)\\n    }\\n}\\n\\nfunc BenchmarkAtomicStoreInt64(b *testing.B) {\\n    var v int64\\n    for i := 0; i &lt; b.N; i++ {\\n        atomic.StoreInt64(&amp;v, 1)\\n    }\\n}\\n</code></pre> <p>If we run this benchmark, here\\u2019s some example output:</p> <pre><code>cpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\\nBenchmarkAtomicStoreInt32\\nBenchmarkAtomicStoreInt32-4    197107742           5.682 ns/op\\nBenchmarkAtomicStoreInt64\\nBenchmarkAtomicStoreInt64-4    213917528           5.134 ns/op\\n</code></pre> <p>We could easily take this benchmark for granted and decide to use <code>atomic.StoreInt64</code> because it appears to be faster. Now, for the sake of doing a fair benchmark, we reverse the order and test <code>atomic.StoreInt64</code> first, followed by <code>atomic.StoreInt32</code>. Here is some example output:</p> <pre><code>BenchmarkAtomicStoreInt64\\nBenchmarkAtomicStoreInt64-4    224900722           5.434 ns/op\\nBenchmarkAtomicStoreInt32\\nBenchmarkAtomicStoreInt32-4    230253900           5.159 ns/op\\n</code></pre> <p>This time, <code>atomic.StoreInt32</code> has better results. What happened?</p> <p>In the case of micro-benchmarks, many factors can impact the results, such as machine activity while running the benchmarks, power management, thermal scaling, and better cache alignment of a sequence of instructions. We must remember that many factors, even outside the scope of our Go project, can impact the results.</p> Note <p>We should make sure the machine executing the benchmark is idle. However, external processes may run in the background, which may affect benchmark results. For that reason, tools such as <code>perflock</code> can limit how much CPU a benchmark can consume. For example, we can run a benchmark with 70% of the total available CPU, giving 30% to the OS and other processes and reducing the impact of the machine activity factor on the results.</p> <p>One option is to increase the benchmark time using the <code>-benchtime</code> option. Similar to the law of large numbers in probability theory, if we run a benchmark a large number of times, it should tend to approach its expected value (assuming we omit the benefits of instructions caching and similar mechanics).</p> <p>Another option is to use external tools on top of the classic benchmark tooling. For instance, the <code>benchstat</code> tool, which is part of the <code>golang.org/x</code> repository, allows us to compute and compare statistics about benchmark executions.</p> <p>Let\\u2019s run the benchmark 10 times using the <code>-count</code> option and pipe the output to a specific file:</p> <pre><code>$ go test -bench=. -count=10 | tee stats.txt\\ncpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\\nBenchmarkAtomicStoreInt32-4     234935682                5.124 ns/op\\nBenchmarkAtomicStoreInt32-4     235307204                5.112 ns/op\\n// ...\\nBenchmarkAtomicStoreInt64-4     235548591                5.107 ns/op\\nBenchmarkAtomicStoreInt64-4     235210292                5.090 ns/op\\n// ...\\n</code></pre> <p>We can then run <code>benchstat</code> on this file:</p> <pre><code>$ benchstat stats.txt\\nname                time/op\\nAtomicStoreInt32-4  5.10ns \\u00b1 1%\\nAtomicStoreInt64-4  5.10ns \\u00b1 1%\\n</code></pre> <p>The results are the same: both functions take on average 5.10 nanoseconds to complete. We also see the percent variation between the executions of a given benchmark: \\u00b1 1%. This metric tells us that both benchmarks are stable, giving us more confidence in the computed average results. Therefore, instead of concluding that <code>atomic.StoreInt32</code> is faster or slower, we can conclude that its execution time is similar to that of <code>atomic.StoreInt64</code> for the usage we tested (in a specific Go version on a particular machine).</p> <p>In general, we should be cautious about micro-benchmarks. Many factors can significantly impact the results and potentially lead to wrong assumptions. Increasing the benchmark time or repeating the benchmark executions and computing stats with tools such as <code>benchstat</code> can be an efficient way to limit external factors and get more accurate results, leading to better conclusions.</p> <p>Let\\u2019s also highlight that we should be careful about using the results of a micro-benchmark executed on a given machine if another system ends up running the application. The production system may act quite differently from the one on which we ran the micro-benchmark.</p>\"},{\"location\":\"89-benchmarks/#not-being-careful-about-compiler-optimizations\",\"title\":\"Not being careful about compiler optimizations\",\"text\":\"<p>Another common mistake related to writing benchmarks is being fooled by compiler optimizations, which can also lead to wrong benchmark assumptions. In this section, we look at Go issue 14813 (https://github.com/golang/go/issues/14813, also discussed by Go project member Dave Cheney) with a population count function (a function that counts the number of bits set to 1):</p> <pre><code>const m1 = 0x5555555555555555\\nconst m2 = 0x3333333333333333\\nconst m4 = 0x0f0f0f0f0f0f0f0f\\nconst h01 = 0x0101010101010101\\n\\nfunc popcnt(x uint64) uint64 {\\n    x -= (x &gt;&gt; 1) &amp; m1\\n    x = (x &amp; m2) + ((x &gt;&gt; 2) &amp; m2)\\n    x = (x + (x &gt;&gt; 4)) &amp; m4\\n    return (x * h01) &gt;&gt; 56\\n}\\n</code></pre> <p>This function takes and returns a <code>uint64</code>. To benchmark this function, we can write the following:</p> <pre><code>func BenchmarkPopcnt1(b *testing.B) {\\n    for i := 0; i &lt; b.N; i++ {\\n        popcnt(uint64(i))\\n    }\\n}\\n</code></pre> <p>However, if we execute this benchmark, we get a surprisingly low result:</p> <pre><code>cpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\\nBenchmarkPopcnt1-4      1000000000               0.2858 ns/op\\n</code></pre> <p>A duration of 0.28 nanoseconds is roughly one clock cycle, so this number is unreasonably low. The problem is that the developer wasn\\u2019t careful enough about compiler optimizations. In this case, the function under test is simple enough to be a candidate for inlining: an optimization that replaces a function call with the body of the called function and lets us prevent a function call, which has a small footprint. Once the function is inlined, the compiler notices that the call has no side effects and replaces it with the following benchmark:</p> <pre><code>func BenchmarkPopcnt1(b *testing.B) {\\n    for i := 0; i &lt; b.N; i++ {\\n        // Empty\\n    }\\n}\\n</code></pre> <p>The benchmark is now empty \\u2014 which is why we got a result close to one clock cycle. To prevent this from happening, a best practice is to follow this pattern:</p> <ol> <li>During each loop iteration, assign the result to a local variable (local in the context of the benchmark function).</li> <li>Assign the latest result to a global variable.</li> </ol> <p>In our case, we write the following benchmark:</p> <pre><code>var global uint64 // Define a global variable\\n\\nfunc BenchmarkPopcnt2(b *testing.B) {\\n    var v uint64 // Define a local variable\\n    for i := 0; i &lt; b.N; i++ {\\n        v = popcnt(uint64(i)) // Assign the result to the local variable\\n    }\\n    global = v // Assign the result to the global variable\\n}\\n</code></pre> <p><code>global</code> is a global variable, whereas v is a local variable whose scope is the benchmark function. During each loop iteration, we assign the result of <code>popcnt</code> to the local variable. Then we assign the latest result to the global variable.</p> Note <p>Why not assign the result of the popcnt call directly to global to simplify the test? Writing to a global variable is slower than writing to a local variable (these concepts are discussed in 100 Go Mistakes, mistake #95: \\u201cNot understanding stack vs. heap\\u201d). Therefore, we should write each result to a local variable to limit the footprint during each loop iteration.</p> <p>If we run these two benchmarks, we now get a significant difference in the results:</p> <pre><code>cpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\\nBenchmarkPopcnt1-4      1000000000               0.2858 ns/op\\nBenchmarkPopcnt2-4      606402058                1.993 ns/op\\n</code></pre> <p><code>BenchmarkPopcnt2</code> is the accurate version of the benchmark. It guarantees that we avoid the inlining optimizations, which can artificially lower the execution time or even remove the call to the function under test. Relying on the results of <code>BenchmarkPopcnt1</code> could have led to wrong assumptions.</p> <p>Let\\u2019s remember the pattern to avoid compiler optimizations fooling benchmark results: assign the result of the function under test to a local variable, and then assign the latest result to a global variable. This best practice also prevents us from making incorrect assumptions.</p>\"},{\"location\":\"89-benchmarks/#being-fooled-by-the-observer-effect\",\"title\":\"Being fooled by the observer effect\",\"text\":\"<p>In physics, the observer effect is the disturbance of an observed system by the act of observation. This effect can also be seen in benchmarks and can lead to wrong assumptions about results. Let\\u2019s look at a concrete example and then try to mitigate it.</p> <p>We want to implement a function receiving a matrix of <code>int64</code> elements. This matrix has a fixed number of 512 columns, and we want to compute the total sum of the first eight columns, as shown in figure 1.</p> <p> </p> Figure 1: Computing the sum of the first eight columns. <p>For the sake of optimizations, we also want to determine whether varying the number of columns has an impact, so we also implement a second function with 513 columns. The implementation is the following:</p> <pre><code>func calculateSum512(s [][512]int64) int64 {\\n    var sum int64\\n    for i := 0; i &lt; len(s); i++ { // Iterate over each row\\n        for j := 0; j &lt; 8; j++ { // Iterate over the first eight columns\\n            sum += s[i][j] // Increment sum\\n        }\\n    }\\n    return sum\\n}\\n\\nfunc calculateSum513(s [][513]int64) int64 {\\n    // Same implementation as calculateSum512\\n}\\n</code></pre> <p>We iterate over each row and then over the first eight columns, and we increment a sum variable that we return. The implementation in <code>calculateSum513</code> remains the same.</p> <p>We want to benchmark these functions to decide which one is the most performant given a fixed number of rows:</p> <pre><code>const rows = 1000\\n\\nvar res int64\\n\\nfunc BenchmarkCalculateSum512(b *testing.B) {\\n    var sum int64\\n    s := createMatrix512(rows) // Create a matrix of 512 columns\\n    b.ResetTimer()\\n    for i := 0; i &lt; b.N; i++ {\\n        sum = calculateSum512(s) // Create a matrix of 512 columns\\n    }\\n    res = sum\\n}\\n\\nfunc BenchmarkCalculateSum513(b *testing.B) {\\n    var sum int64\\n    s := createMatrix513(rows) // Create a matrix of 513 columns\\n    b.ResetTimer()\\n    for i := 0; i &lt; b.N; i++ {\\n        sum = calculateSum513(s) // Calculate the sum\\n    }\\n    res = sum\\n}\\n</code></pre> <p>We want to create the matrix only once, to limit the footprint on the results. Therefore, we call <code>createMatrix512</code> and <code>createMatrix513</code> outside of the loop. We may expect the results to be similar as again we only want to iterate on the first eight columns, but this isn\\u2019t the case (on my machine):</p> <pre><code>cpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\\nBenchmarkCalculateSum512-4        81854             15073 ns/op\\nBenchmarkCalculateSum513-4       161479              7358 ns/op\\n</code></pre> <p>The second benchmark with 513 columns is about 50% faster. Again, because we iterate only over the first eight columns, this result is quite surprising.</p> <p>To understand this difference, we need to understand the basics of CPU caches. In a nutshell, a CPU is composed of different caches (usually L1, L2, and L3). These caches reduce the average cost of accessing data from the main memory. In some conditions, the CPU can fetch data from the main memory and copy it to L1. In this case, the CPU tries to fetch into L1 the matrix\\u2019s subset that <code>calculateSum</code> is interested in (the first eight columns of each row). However, the matrix fits in memory in one case (513 columns) but not in the other case (512 columns).</p> Note <p>This isn\\u2019t in the scope of this post to explain why, but we look at this problem in 100 Go Mistakes, mistake #91: \\u201cNot understanding CPU caches.\\u201d</p> <p>Coming back to the benchmark, the main issue is that we keep reusing the same matrix in both cases. Because the function is repeated thousands of times, we don\\u2019t measure the function\\u2019s execution when it receives a plain new matrix. Instead, we measure a function that gets a matrix that already has a subset of the cells present in the cache. Therefore, because <code>calculateSum513</code> leads to fewer cache misses, it has a better execution time.</p> <p>This is an example of the observer effect. Because we keep observing a repeatedly called CPU-bound function, CPU caching may come into play and significantly affect the results. In this example, to prevent this effect, we should create a matrix during each test instead of reusing one:</p> <pre><code>func BenchmarkCalculateSum512(b *testing.B) {\\n    var sum int64\\n    for i := 0; i &lt; b.N; i++ {\\n        b.StopTimer()\\n        s := createMatrix512(rows) // Create a new matrix during each loop iteration\\n        b.StartTimer()\\n        sum = calculateSum512(s)\\n    }\\n    res = sum\\n}\\n</code></pre> <p>A new matrix is now created during each loop iteration. If we run the benchmark again (and adjust <code>benchtime</code> \\u2014 otherwise, it takes too long to execute), the results are closer to each other:</p> <pre><code>cpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz\\nBenchmarkCalculateSum512-4         1116             33547 ns/op\\nBenchmarkCalculateSum513-4          998             35507 ns/op\\n</code></pre> <p>Instead of making the incorrect assumption that calculateSum513 is faster, we see that both benchmarks lead to similar results when receiving a new matrix.</p> <p>As we have seen in this post, because we were reusing the same matrix, CPU caches significantly impacted the results. To prevent this, we had to create a new matrix during each loop iteration. In general, we should remember that observing a function under test may lead to significant differences in results, especially in the context of micro-benchmarks of CPU-bound functions where low-level optimizations matter. Forcing a benchmark to re-create data during each iteration can be a good way to prevent this effect.</p>\"},{\"location\":\"9-generics/\",\"title\":\"Being confused about when to use generics (#9)\",\"text\":\"\"},{\"location\":\"9-generics/#being-confused-about-when-to-use-generics\",\"title\":\"Being confused about when to use generics\",\"text\":\"<p>Generics is a fresh addition to the language. In a nutshell, it allows writing code with types that can be specified later and instantiated when needed. However, it can be pretty easy to be confused about when to use generics and when not to. Throughout this post, we will describe the concept of generics in Go and then delve into common use and misuses.</p>\"},{\"location\":\"9-generics/#concepts\",\"title\":\"Concepts\",\"text\":\"<p>Consider the following function that extracts all the keys from a <code>map[string]int</code> type:</p> <pre><code>func getKeys(m map[string]int) []string {\\n    var keys []string\\n    for k := range m {\\n        keys = append(keys, k)\\n    }\\n    return keys\\n}\\n</code></pre> <p>What if we would like to use a similar feature for another map type such as a <code>map[int]string</code>? Before generics, Go developers had a couple of options: using code generation, reflection, or duplicating code.</p> <p>For example, we could write two functions, one for each map type, or even try to extend <code>getKeys</code> to accept different map types:</p> <pre><code>func getKeys(m any) ([]any, error) {\\n    switch t := m.(type) {\\n    default:\\n        return nil, fmt.Errorf(\\\"unknown type: %T\\\", t)\\n    case map[string]int:\\n        var keys []any\\n        for k := range t {\\n            keys = append(keys, k)\\n        }\\n        return keys, nil\\n    case map[int]string:\\n        // Copy the extraction logic\\n    }\\n}\\n</code></pre> <p>We can start noticing a couple of issues:</p> <ul> <li>First, it increases boilerplate code. Indeed, whenever we want to add a case, it will require duplicating the <code>range</code> loop.</li> <li>Meanwhile, the function now accepts an empty interface, which means we are losing some of the benefits of Go being a typed language. Indeed, checking whether a type is supported is done at runtime instead of compile-time. Hence, we also need to return an error if the provided type is unknown.</li> <li>Last but not least, as the key type can be either <code>int</code> or <code>string</code>, we are obliged to return a slice of empty interfaces to factor out key types. This approach increases the effort on the caller-side as the client may also have to perform a type check of the keys or extra conversion.</li> </ul> <p>Thanks to generics, we can now refactor this code using type parameters.</p> <p>Type parameters are generic types we can use with functions and types. For example, the following function accepts a type parameter:</p> <pre><code>func foo[T any](t T) {\\n    // ...\\n}\\n</code></pre> <p>When calling <code>foo</code>, we will pass a type argument of any type. Passing a type argument is called instantiation because the work is done at compile time which keeps type safety as part of the core language features and avoids runtime overheads.</p> <p>Let\\u2019s get back to the <code>getKeys</code> function and use type parameters to write a generic version that would accept any kind of map:</p> <pre><code>func getKeys[K comparable, V any](m map[K]V) []K {\\n  var keys []K\\n  for k := range m {\\n    keys = append(keys, k)\\n  }\\n  return keys\\n}\\n</code></pre> <p>To handle the map, we defined two kinds of type parameters. First, the values can be of any type: <code>V any</code>. However, in Go, the map keys can\\u2019t be of any type. For example, we cannot use slices:</p> <pre><code>var m map[[]byte]int\\n</code></pre> <p>This code leads to a compilation error: <code>invalid map key type []byte</code>. Therefore, instead of accepting any key type, we are obliged to restrict type arguments so that the key type meets specific requirements. Here, being comparable (we can use <code>==</code> or <code>!=</code>). Hence, we defined <code>K</code> as <code>comparable</code> instead of <code>any</code>.</p> <p>Restricting type arguments to match specific requirements is called a constraint. A constraint is an interface type that can contain:</p> <ul> <li>A set of behaviors (methods)</li> <li>But also arbitrary type</li> </ul> <p>Let\\u2019s see a concrete example for the latter. Imagine we don\\u2019t want to accept any <code>comparable</code> type for map key type. For instance, we would like to restrict it to either <code>int</code> or <code>string</code> types. We can define a custom constraint this way:</p> <pre><code>type customConstraint interface {\\n   ~int | ~string // Define a custom type that will restrict types to int and string\\n}\\n\\n// Change the type parameter K to be custom\\nfunc getKeys[K customConstraint, V any](m map[K]V) []K {\\n   // Same implementation\\n}\\n</code></pre> <p>First, we define a <code>customConstraint</code> interface to restrict the types to be either <code>int</code> or <code>string</code> using the union operator <code>|</code> (we will discuss the use of <code>~</code> a bit later). Then, <code>K</code> is now a <code>customConstraint</code> instead of a <code>comparable</code> as before.</p> <p>Now, the signature of <code>getKeys</code> enforces that we can call it with a map of any value type, but the key type has to be an <code>int</code> or a <code>string</code>. For example, on the caller-side:</p> <pre><code>m = map[string]int{\\n   \\\"one\\\":   1,\\n   \\\"two\\\":   2,\\n   \\\"three\\\": 3,\\n}\\nkeys := getKeys(m)\\n</code></pre> <p>Note that Go can infer that <code>getKeys</code> is called with a <code>string</code> type argument. The previous call was similar to this:</p> <pre><code>keys := getKeys[string](m)\\n</code></pre> Note <p>What\\u2019s the difference between a constraint using <code>~int</code> or <code>int</code>? Using <code>int</code> restricts it to that type, whereas <code>~int</code> restricts all the types whose underlying type is an <code>int</code>.</p> <p>To illustrate it, let\\u2019s imagine a constraint where we would like to restrict a type to any <code>int</code> type implementing the <code>String() string</code> method:</p> <pre><code>type customConstraint interface {\\n   ~int\\n   String() string\\n}\\n</code></pre> <p>Using this constraint will restrict type arguments to custom types like this one:</p> <pre><code>type customInt int\\n\\nfunc (i customInt) String() string {\\n   return strconv.Itoa(int(i))\\n}\\n</code></pre> <p>As <code>customInt</code> is an <code>int</code> and implements the <code>String() string</code> method, the <code>customInt</code> type satisfies the constraint defined.</p> <p>However, if we change the constraint to contain an <code>int</code> instead of an <code>~int</code>, using <code>customInt</code> would lead to a compilation error because the <code>int</code> type doesn\\u2019t implement <code>String() string</code>.</p> <p>Let\\u2019s also note the <code>constraints</code> package contains a set of common constraints such as <code>Signed</code> that includes all the signed integer types. Let\\u2019s ensure that a constraint doesn\\u2019t already exist in this package before creating a new one.</p> <p>So far, we have discussed examples using generics for functions. However, we can also use generics with data structures.</p> <p>For example, we will create a linked list containing values of any type. Meanwhile, we will write an <code>Add</code> method to append a node:</p> <pre><code>type Node[T any] struct { // Use type parameter\\n   Val  T\\n   next *Node[T]\\n}\\n\\nfunc (n *Node[T]) Add(next *Node[T]) { // Instantiate type receiver\\n   n.next = next\\n}\\n</code></pre> <p>We use type parameters to define <code>T</code> and use both fields in <code>Node</code>. Regarding the method, the receiver is instantiated. Indeed, because <code>Node</code> is generic, it has to follow also the type parameter defined.</p> <p>One last thing to note about type parameters: they can\\u2019t be used on methods, only on functions. For example, the following method wouldn\\u2019t compile:</p> <pre><code>type Foo struct {}\\n\\nfunc (Foo) bar[T any](t T) {}\\n</code></pre> <pre><code>./main.go:29:15: methods cannot have type parameters\\n</code></pre> <p>Now, let\\u2019s delve into concrete cases where we should and shouldn\\u2019t use generics.</p>\"},{\"location\":\"9-generics/#common-uses-and-misuses\",\"title\":\"Common uses and misuses\",\"text\":\"<p>So when are generics useful? Let\\u2019s discuss a couple of common uses where generics are recommended:</p> <ul> <li>Data structures. For example, we can use generics to factor out the element type if we implement a binary tree, a linked list, or a heap.</li> <li>Functions working with slices, maps, and channels of any type. For example, a function to merge two channels would work with any channel type. Hence, we could use type parameters to factor out the channel type:</li> </ul> <pre><code>func merge[T any](ch1, ch2 &lt;-chan T) &lt;-chan T {\\n    // ...\\n}\\n</code></pre> <ul> <li>Meanwhile, instead of factoring out a type, we can factor out behaviors. For example, the <code>sort</code> package contains functions to sort different slice types such as <code>sort.Ints</code> or <code>sort.Float64s</code>. Using type parameters, we can factor out the sorting behaviors that rely on three methods, <code>Len</code>, <code>Less</code>, and <code>Swap</code>:</li> </ul> <pre><code>type sliceFn[T any] struct { // Use type parameter\\n   s       []T\\n   compare func(T, T) bool // Compare two T elements\\n}\\n\\nfunc (s sliceFn[T]) Len() int           { return len(s.s) }\\nfunc (s sliceFn[T]) Less(i, j int) bool { return s.compare(s.s[i], s.s[j]) }\\nfunc (s sliceFn[T]) Swap(i, j int)      { s.s[i], s.s[j] = s.s[j], s.s[i] }\\n</code></pre> <p>Conversely, when is it recommended not to use generics?</p> <ul> <li>When just calling a method of the type argument. For example, consider a function that receives an <code>io.Writer</code> and call the <code>Write</code> method:</li> </ul> <pre><code>func foo[T io.Writer](w T) {\\n   b := getBytes()\\n   _, _ = w.Write(b)\\n}\\n</code></pre> <ul> <li>When it makes our code more complex. Generics are never mandatory, and as Go developers, we have been able to live without them for more than a decade. If writing generic functions or structures we figure out that it doesn\\u2019t make our code clearer, we should probably reconsider our decision for this particular use case.</li> </ul>\"},{\"location\":\"9-generics/#conclusion\",\"title\":\"Conclusion\",\"text\":\"<p>Though generics can be very helpful in particular conditions, we should be cautious about when to use them and not use them.</p> <p>In general, when we want to answer when not to use generics, we can find similarities with when not to use interfaces. Indeed, generics introduce a form of abstraction, and we have to remember that unnecessary abstractions introduce complexity.</p> <p>Let\\u2019s not pollute our code with needless abstractions, and let\\u2019s focus on solving concrete problems for now. It means that we shouldn\\u2019t use type parameters prematurely. Let\\u2019s wait until we are about to write boilerplate code to consider using generics.</p>\"},{\"location\":\"92-false-sharing/\",\"title\":\"Writing concurrent code that leads to false sharing (#92)\",\"text\":\"\"},{\"location\":\"92-false-sharing/#writing-concurrent-code-that-leads-to-false-sharing\",\"title\":\"Writing concurrent code that leads to false sharing\",\"text\":\"<p>In previous sections, we have discussed the fundamental concepts of CPU caching. We have seen that some specific caches (typically, L1 and L2) aren\\u2019t shared among all the logical cores but are specific to a physical core. This specificity has some concrete impacts such as concurrency and the concept of false sharing, which can lead to a significant performance decrease. Let\\u2019s look at what false sharing is via an example and then see how to prevent it.</p> <p>In this example, we use two structs, <code>Input</code> and <code>Result</code>:</p> <pre><code>type Input struct {\\n    a int64\\n    b int64\\n}\\n\\ntype Result struct {\\n    sumA int64\\n    sumB int64\\n}\\n</code></pre> <p>The goal is to implement a <code>count</code> function that receives a slice of <code>Input</code> and computes the following:</p> <ul> <li>The sum of all the <code>Input.a</code> fields into <code>Result.sumA</code></li> <li>The sum of all the <code>Input.b</code> fields into <code>Result.sumB</code></li> </ul> <p>For the sake of the example, we implement a concurrent solution with one goroutine that computes <code>sumA</code> and another that computes <code>sumB</code>:</p> <pre><code>func count(inputs []Input) Result {\\n    wg := sync.WaitGroup{}\\n    wg.Add(2)\\n\\n    result := Result{} // Init the result struct\\n\\n    go func() {\\n        for i := 0; i &lt; len(inputs); i++ {\\n            result.sumA += inputs[i].a // Computes sumA\\n        }\\n        wg.Done()\\n    }()\\n\\n    go func() {\\n        for i := 0; i &lt; len(inputs); i++ {\\n            result.sumB += inputs[i].b // Computes sumB\\n        }\\n        wg.Done()\\n    }()\\n\\n    wg.Wait()\\n    return result\\n}\\n</code></pre> <p>We spin up two goroutines: one that iterates over each a field and another that iterates over each b field. This example is fine from a concurrency perspective. For instance, it doesn\\u2019t lead to a data race, because each goroutine increments its own variable. But this example illustrates the false sharing concept that degrades expected performance.</p> <p>Let\\u2019s look at the main memory. Because <code>sumA</code> and <code>sumB</code> are allocated contiguously, in most cases (seven out of eight), both variables are allocated to the same memory block:</p> <p> </p> In this example, sumA and sumB are part of the same memory block. <p>Now, let\\u2019s assume that the machine contains two cores. In most cases, we should eventually have two threads scheduled on different cores. So if the CPU decides to copy this memory block to a cache line, it is copied twice:</p> <p> </p> Each block is copied to a cache line on both code 0 and core 1. <p>Both cache lines are replicated because L1D (L1 data) is per core. Recall that in our example, each goroutine updates its own variable: <code>sumA</code> on one side, and <code>sumB</code> on the other side:</p> <p> </p> Each goroutine updates its own variable. <p>Because these cache lines are replicated, one of the goals of the CPU is to guarantee cache coherency. For example, if one goroutine updates <code>sumA</code> and another reads <code>sumA</code> (after some synchronization), we expect our application to get the latest value.</p> <p>However, our example doesn\\u2019t do exactly this. Both goroutines access their own variables, not a shared one. We might expect the CPU to know about this and understand that it isn\\u2019t a conflict, but this isn\\u2019t the case. When we write a variable that\\u2019s in a cache, the granularity tracked by the CPU isn\\u2019t the variable: it\\u2019s the cache line.</p> <p>When a cache line is shared across multiple cores and at least one goroutine is a writer, the entire cache line is invalidated. This happens even if the updates are logically independent (for example, <code>sumA</code> and <code>sumB</code>). This is the problem of false sharing, and it degrades performance.</p> Note <p>Internally, a CPU uses the MESI protocol to guarantee cache coherency. It tracks each cache line, marking it modified, exclusive, shared, or invalid (MESI).</p> <p>One of the most important aspects to understand about memory and caching is that sharing memory across cores isn\\u2019t real\\u2014it\\u2019s an illusion. This understanding comes from the fact that we don\\u2019t consider a machine a black box; instead, we try to have mechanical sympathy with underlying levels.</p> <p>So how do we solve false sharing? There are two main solutions.</p> <p>The first solution is to use the same approach we\\u2019ve shown but ensure that <code>sumA</code> and <code>sumB</code> aren\\u2019t part of the same cache line. For example, we can update the <code>Result</code> struct to add padding between the fields. Padding is a technique to allocate extra memory. Because an <code>int64</code> requires an 8-byte allocation and a cache line 64 bytes long, we need 64 \\u2013 8 = 56 bytes of padding:</p> <pre><code>type Result struct {\\n    sumA int64\\n    _    [56]byte // Padding\\n    sumB int64\\n}\\n</code></pre> <p>The next figure shows a possible memory allocation. Using padding, <code>sumA</code> and <code>sumB</code> will always be part of different memory blocks and hence different cache lines.</p> <p> </p> sumA and sumB are part of different memory blocks. <p>If we benchmark both solutions (with and without padding), we see that the padding solution is significantly faster (about 40% on my machine). This is an important improvement that results from the addition of padding between the two fields to prevent false sharing.</p> <p>The second solution is to rework the structure of the algorithm. For example, instead of having both goroutines share the same struct, we can make them communicate their local result via channels. The result benchmark is roughly the same as with padding.</p> <p>In summary, we must remember that sharing memory across goroutines is an illusion at the lowest memory levels. False sharing occurs when a cache line is shared across two cores when at least one goroutine is a writer. If we need to optimize an application that relies on concurrency, we should check whether false sharing applies, because this pattern is known to degrade application performance. We can prevent false sharing with either padding or communication.</p>\"},{\"location\":\"98-profiling-execution-tracing/\",\"title\":\"Not using Go diagnostics tooling (#98)\",\"text\":\"\"},{\"location\":\"98-profiling-execution-tracing/#not-using-go-diagnostics-tooling\",\"title\":\"Not using Go diagnostics tooling\",\"text\":\"<p>Go offers a few excellent diagnostics tools to help us get insights into how an application performs. This post focuses on the most important ones: profiling and the execution tracer. Both tools are so important that they should be part of the core toolset of any Go developer who is interested in optimization. First, let\\u2019s discuss profiling.</p>\"},{\"location\":\"98-profiling-execution-tracing/#profiling\",\"title\":\"Profiling\",\"text\":\"<p>Profiling provides insights into the execution of an application. It allows us to resolve performance issues, detect contention, locate memory leaks, and more. These insights can be collected via several profiles:</p> <ul> <li><code>CPU</code>\\u2014 Determines where an application spends its time</li> <li><code>Goroutine</code>\\u2014 Reports the stack traces of the ongoing goroutines</li> <li><code>Heap</code>\\u2014 Reports heap memory allocation to monitor current memory usage and check for possible memory leaks</li> <li><code>Mutex</code>\\u2014 Reports lock contentions to see the behaviors of the mutexes used in our code and whether an application spends too much time in locking calls</li> <li><code>Block</code>\\u2014 Shows where goroutines block waiting on synchronization primitives</li> </ul> <p>Profiling is achieved via instrumentation using a tool called a profiler, in Go: <code>pprof</code>. First, let\\u2019s understand how and when to enable <code>pprof</code>; then, we discuss the most critical profile types.</p>\"},{\"location\":\"98-profiling-execution-tracing/#enabling-pprof\",\"title\":\"Enabling pprof\",\"text\":\"<p>There are several ways to enable <code>pprof</code>. For example, we can use the <code>net/http/pprof</code> package to serve the profiling data via HTTP:</p> <pre><code>package main\\n\\nimport (\\n    \\\"fmt\\\"\\n    \\\"log\\\"\\n    \\\"net/http\\\"\\n    _ \\\"net/http/pprof\\\" // Blank import to pprof\\n)\\n\\nfunc main() {\\n    // Exposes an HTTP endpoint\\n    http.HandleFunc(\\\"/\\\", func(w http.ResponseWriter, r *http.Request) {\\n        fmt.Fprintf(w, \\\"\\\")\\n    })\\n    log.Fatal(http.ListenAndServe(\\\":80\\\", nil))\\n}\\n</code></pre> <p>Importing <code>net/http/pprof</code> leads to a side effect that allows us to reach the pprof URL: http://host/debug/pprof. Note that enabling <code>pprof</code> is safe even in production (https://go.dev/doc/diagnostics#profiling). The profiles that impact performance, such as CPU profiling, aren\\u2019t enabled by default, nor do they run continuously: they are activated only for a specific period.</p> <p>Now that we have seen how to expose a <code>pprof</code> endpoint, let\\u2019s discuss the most common profiles.</p>\"},{\"location\":\"98-profiling-execution-tracing/#cpu-profiling\",\"title\":\"CPU Profiling\",\"text\":\"<p>The CPU profiler relies on the OS and signaling. When it is activated, the application asks the OS to interrupt it every 10 ms by default via a <code>SIGPROF</code> signal. When the application receives a <code>SIGPROF</code>, it suspends the current activity and transfers the execution to the profiler. The profiler collects data such as the current goroutine activity and aggregates execution statistics that we can retrieve. Then it stops, and the execution resumes until the next <code>SIGPROF</code>.</p> <p>We can access the /debug/pprof/profile endpoint to activate CPU profiling. Accessing this endpoint executes CPU profiling for 30 seconds by default. For 30 seconds, our application is interrupted every 10 ms. Note that we can change these two default values: we can use the <code>seconds</code> parameter to pass to the endpoint how long the profiling should last (for example, /debug/pprof/profile?seconds=15), and we can change the interruption rate (even to less than 10 ms). But in most cases, 10 ms should be enough, and in decreasing this value (meaning increasing the rate), we should be careful not to harm performance. After 30 seconds, we download the results of the CPU profiler.</p> Note <p>We can also enable the CPU profiler using the <code>-cpuprofile</code> flag, such as when running a benchmark. For example, the following command produces the same type of file that can be downloaded via /debug/ pprof/profile.</p> <pre><code>$ go test -bench=. -cpuprofile profile.out\\n</code></pre> <p>From this file, we can navigate to the results using <code>go tool</code>:</p> <pre><code>$ go tool pprof -http=:8080 &lt;file&gt;\\n</code></pre> <p>This command opens a web UI showing the call graph. The next figure shows an example taken from an application. The larger the arrow, the more it was a hot path. We can then navigate into this graph and get execution insights.</p> <p> </p> Figure 1: The call graph of an application during 30 seconds. <p>For example, the graph in the next figure tells us that during 30 seconds, 0.06 seconds were spent in the <code>decode</code> method (<code>*FetchResponse</code> receiver). Of these 0.06 seconds, 0.02 were spent in <code>RecordBatch.decode</code> and 0.01 in <code>makemap</code> (creating a map).</p> <p> </p> Figure 2: Example call graph. <p>We can also access this kind of information from the web UI with different representations. For example, the Top view sorts the functions per execution time, and Flame Graph visualizes the execution time hierarchy. The UI can even display the expensive parts of the source code line by line.</p> Note <p>We can also delve into profiling data via a command line. However, we focus on the web UI in this post.</p> <p>Thanks to this data, we can get a general idea of how an application behaves:</p> <ul> <li>Too many calls to <code>runtime.mallogc</code> can mean an excessive number of small heap allocations that we can try to minimize.</li> <li>Too much time spent in channel operations or mutex locks can indicate excessive contention that is harming the application\\u2019s performance.</li> <li>Too much time spent on <code>syscall.Read</code> or <code>syscall.Write</code> means the application spends a significant amount of time in Kernel mode. Working on I/O buffering may be an avenue for improvement.</li> </ul> <p>These are the kinds of insights we can get from the CPU profiler. It\\u2019s valuable to understand the hottest code path and identify bottlenecks. But it won\\u2019t determine more than the configured rate because the CPU profiler is executed at a fixed pace (by default, 10 ms). To get finer-grained insights, we should use tracing, which we discuss later in this post.</p> Note <p>We can also attach labels to the different functions. For example, imagine a common function called from different clients. To track the time spent for both clients, we can use <code>pprof.Labels</code>.</p>\"},{\"location\":\"98-profiling-execution-tracing/#heap-profiling\",\"title\":\"Heap Profiling\",\"text\":\"<p>Heap profiling allows us to get statistics about the current heap usage. Like CPU profiling, heap profiling is sample-based. We can change this rate, but we shouldn\\u2019t be too granular because the more we decrease the rate, the more effort heap profiling will require to collect data. By default, samples are profiled at one allocation for every 512 KB of heap allocation.</p> <p>If we reach /debug/pprof/heap/, we get raw data that can be hard to read. However, we can download a heap profile using /debug/pprof/heap/?debug=0 and then open it with <code>go tool</code> (the same command as in the previous section) to navigate into the data using the web UI.</p> <p>The next figure shows an example of a heap graph. Calling the <code>MetadataResponse.decode</code> method leads to allocating 1536 KB of heap data (which represents 6.32% of the total heap). However, 0 out of these 1536 KB were allocated by this function directly, so we need to inspect the second call. The <code>TopicMetadata.decode</code> method allocated 512 KB out of the 1536 KB; the rest \\u2014 1024 KB \\u2014 were allocated in another method.</p> <p> </p> Figure 3: A heap graph. <p>This is how we can navigate the call chain to understand what part of an application is responsible for most of the heap allocations. We can also look at different sample types:</p> <ul> <li><code>alloc_objects</code>\\u2014 Total number of objects allocated</li> <li><code>alloc_space</code>\\u2014 Total amount of memory allocated</li> <li><code>inuse_object</code>s \\u2014 Number of objects allocated and not yet released</li> <li><code>inuse_space</code>\\u2014 Amount of memory allocated and not yet released</li> </ul> <p>Another very helpful capability with heap profiling is tracking memory leaks. With a GC-based language, the usual procedure is the following:</p> <ol> <li>Trigger a GC.</li> <li>Download heap data.</li> <li>Wait for a few seconds/minutes.</li> <li>Trigger another GC.</li> <li>Download another heap data.</li> <li>Compare.</li> </ol> <p>Forcing a GC before downloading data is a way to prevent false assumptions. For example, if we see a peak of retained objects without running a GC first, we cannot be sure whether it\\u2019s a leak or objects that the next GC will collect.</p> <p>Using <code>pprof</code>, we can download a heap profile and force a GC in the meantime. The procedure in Go is the following:</p> <ol> <li>Go to /debug/pprof/heap?gc=1 (trigger the GC and download the heap profile).</li> <li>Wait for a few seconds/minutes.</li> <li>Go to /debug/pprof/heap?gc=1 again.</li> <li>Use go tool to compare both heap profiles:</li> </ol> <pre><code>$ go tool pprof -http=:8080 -diff_base &lt;file2&gt; &lt;file1&gt;\\n</code></pre> <p>The next figure shows the kind of data we can access. For example, the amount of heap memory held by the newTopicProducer method (top left) has decreased (\\u2013513 KB). In contrast, the amount held by updateMetadata (bottom right) has increased (+512 KB). Slow increases are normal. The second heap profile may have been calculated in the middle of a service call, for example. We can repeat this process or wait longer; the important part is to track steady increases in allocations of a specific object.</p> <p> </p> Figure 4: The differences between the two heap profiles. Note <p>Another type of profiling related to the heap is <code>allocs</code>, which reports allocations. Heap profiling shows the current state of the heap memory. To get insights about past memory allocations since the application started, we can use allocations profiling. As discussed, because stack allocations are cheap, they aren\\u2019t part of this profiling, which only focuses on the heap.</p>\"},{\"location\":\"98-profiling-execution-tracing/#goroutine-profiling\",\"title\":\"Goroutine Profiling\",\"text\":\"<p>The <code>goroutine</code> profile reports the stack trace of all the current goroutines in an application. We can download a file using /debug/pprof/goroutine/?debug=0 and use go tool again. The next figure shows the kind of information we can get.</p> <p> </p> Figure 5: Goroutine graph. <p>We can see the current state of the application and how many goroutines were created per function. In this case, <code>withRecover</code> has created 296 ongoing goroutines (63%), and 29 were related to a call to <code>responseFeeder</code>.</p> <p>This kind of information is also beneficial if we suspect goroutine leaks. We can look at goroutine profiler data to know which part of a system is the suspect.</p>\"},{\"location\":\"98-profiling-execution-tracing/#block-profiling\",\"title\":\"Block Profiling\",\"text\":\"<p>The <code>block</code> profile reports where ongoing goroutines block waiting on synchronization primitives. Possibilities include</p> <ul> <li>Sending or receiving on an unbuffered channel</li> <li>Sending to a full channel</li> <li>Receiving from an empty channel</li> <li>Mutex contention</li> <li>Network or filesystem waits</li> </ul> <p>Block profiling also records the amount of time a goroutine has been waiting and is accessible via /debug/pprof/block. This profile can be extremely helpful if we suspect that performance is being harmed by blocking calls.</p> <p>The <code>block</code> profile isn\\u2019t enabled by default: we have to call <code>runtime.SetBlockProfileRate</code> to enable it. This function controls the fraction of goroutine blocking events that are reported. Once enabled, the profiler will keep collecting data in the background even if we don\\u2019t call the /debug/pprof/block endpoint. Let\\u2019s be cautious if we want to set a high rate so we don\\u2019t harm performance.</p> Note <p>If we face a deadlock or suspect that goroutines are in a blocked state, the full goroutine stack dump (/debug/pprof/goroutine/?debug=2) creates a dump of all the current goroutine stack traces. This can be helpful as a first analysis step. For example, the following dump shows a Sarama goroutine blocked for 1,420 minutes on a channel-receive operation:</p> <pre><code>goroutine 2494290 [chan receive, 1420 minutes]:\\ngithub.com/Shopify/sarama.(*syncProducer).SendMessages(0xc00071a090,\\n[CA]{0xc0009bb800, 0xfb, 0xfb})\\n/app/vendor/github.com/Shopify/sarama/sync_producer.go:117 +0x149\\n</code></pre>\"},{\"location\":\"98-profiling-execution-tracing/#mutex-profiling\",\"title\":\"Mutex Profiling\",\"text\":\"<p>The last profile type is related to blocking but only regarding mutexes. If we suspect that our application spends significant time waiting for locking mutexes, thus harming execution, we can use mutex profiling. It\\u2019s accessible via /debug/pprof/mutex.</p> <p>This profile works in a manner similar to that for blocking. It\\u2019s disabled by default: we have to enable it using <code>runtime.SetMutexProfileFraction</code>, which controls the fraction of mutex contention events reported.</p> <p>Following are a few additional notes about profiling:</p> <ul> <li>We haven\\u2019t mentioned the <code>threadcreate</code> profile because it\\u2019s been broken since 2013 (https://github.com/golang/go/issues/6104).</li> <li>Be sure to enable only one profiler at a time: for example, do not enable CPU and heap profiling simultaneously. Doing so can lead to erroneous observations.</li> <li><code>pprof</code> is extensible, and we can create our own custom profiles using <code>pprof.Profile</code>.</li> </ul> <p>We have seen the most important profiles that we can enable to help us understand how an application performs and possible avenues for optimization. In general, enabling <code>pprof</code> is recommended, even in production, because in most cases it offers an excellent balance between its footprint and the amount of insight we can get from it. Some profiles, such as the CPU profile, lead to performance penalties but only during the time they are enabled.</p> <p>Let\\u2019s now look at the execution tracer.</p>\"},{\"location\":\"98-profiling-execution-tracing/#execution-tracer\",\"title\":\"Execution Tracer\",\"text\":\"<p>The execution tracer is a tool that captures a wide range of runtime events with <code>go tool</code> to make them available for visualization. It is helpful for the following:</p> <ul> <li>Understanding runtime events such as how the GC performs</li> <li>Understanding how goroutines execute</li> <li>Identifying poorly parallelized execution</li> </ul> <p>Let\\u2019s try it with an example given the Concurrency isn\\u2019t Always Faster in Go section. We discussed two parallel versions of the merge sort algorithm. The issue with the first version was poor parallelization, leading to the creation of too many goroutines. Let\\u2019s see how the tracer can help us in validating this statement.</p> <p>We will write a benchmark for the first version and execute it with the -trace flag to enable the execution tracer:</p> <pre><code>$ go test -bench=. -v -trace=trace.out\\n</code></pre> Note <p>We can also download a remote trace file using the /debug/pprof/ trace?debug=0 pprof endpoint.</p> <p>This command creates a trace.out file that we can open using go tool:</p> <pre><code>$ go tool trace trace.out\\n2021/11/26 21:36:03 Parsing trace...\\n2021/11/26 21:36:31 Splitting trace...\\n2021/11/26 21:37:00 Opening browser. Trace viewer is listening on\\n    http://127.0.0.1:54518\\n</code></pre> <p>The web browser opens, and we can click View Trace to see all the traces during a specific timeframe, as shown in the next figure. This figure represents about 150 ms. We can see multiple helpful metrics, such as the goroutine count and the heap size. The heap size grows steadily until a GC is triggered. We can also observe the activity of the Go application per CPU core. The timeframe starts with user-level code; then a \\u201cstop the world\\u201d is executed, which occupies the four CPU cores for approximately 40 ms.</p> <p> </p> Figure 6: Showing goroutine activity and runtime events such as a GC phase. <p>Regarding concurrency, we can see that this version uses all the available CPU cores on the machine. However, the next figure zooms in on a portion of 1 ms. Each bar corresponds to a single goroutine execution. Having too many small bars doesn\\u2019t look right: it means execution that is poorly parallelized.</p> <p> </p> Figure 7: Too many small bars mean poorly parallelized execution. <p>The next figure zooms even closer to see how these goroutines are orchestrated. Roughly 50% of the CPU time isn\\u2019t spent executing application code. The white spaces represent the time the Go runtime takes to spin up and orchestrate new goroutines.</p> <p> </p> Figure 8: About 50% of CPU time is spent handling goroutine switches. <p>Let\\u2019s compare this with the second parallel implementation, which was about an order of magnitude faster. The next figure again zooms to a 1 ms timeframe.</p> <p> </p> Figure 9: The number of white spaces has been significantly reduced, proving that the CPU is more fully occupied. <p>Each goroutine takes more time to execute, and the number of white spaces has been significantly reduced. Hence, the CPU is much more occupied executing application code than it was in the first version. Each millisecond of CPU time is spent more efficiently, explaining the benchmark differences.</p> <p>Note that the granularity of the traces is per goroutine, not per function like CPU profiling. However, it\\u2019s possible to define user-level tasks to get insights per function or group of functions using the <code>runtime/trace</code> package.</p> <p>For example, imagine a function that computes a Fibonacci number and then writes it to a global variable using atomic. We can define two different tasks:</p> <pre><code>var v int64\\n// Creates a fibonacci task\\nctx, fibTask := trace.NewTask(context.Background(), \\\"fibonacci\\\")\\ntrace.WithRegion(ctx, \\\"main\\\", func() {\\n    v = fibonacci(10)\\n})\\nfibTask.End()\\n\\n// Creates a store task\\nctx, fibStore := trace.NewTask(ctx, \\\"store\\\")\\ntrace.WithRegion(ctx, \\\"main\\\", func() {\\n    atomic.StoreInt64(&amp;result, v)\\n})\\nfibStore.End()\\n</code></pre> <p>Using <code>go tool</code>, we can get more precise information about how these two tasks perform. In the previous trace UI, we can see the boundaries for each task per goroutine. In User-Defined Tasks, we can follow the duration distribution:</p> <p> </p> Figure 10: Distribution of user-level tasks. <p>We see that in most cases, the <code>fibonacci</code> task is executed in less than 15 microseconds, whereas the <code>store</code> task takes less than 6309 nanoseconds.</p> <p>In the previous section, we discussed the kinds of information we can get from CPU profiling. What are the main differences compared to the data we can get from user-level traces?</p> <ul> <li>CPU profiling:<ul> <li>Sample-based</li> <li>Per function</li> <li>Doesn\\u2019t go below the sampling rate (10 ms by default)</li> </ul> </li> <li>User-level traces:<ul> <li>Not sample-based</li> <li>Per-goroutine execution (unless we use the <code>runtime/trace</code> package)</li> <li>Time executions aren\\u2019t bound by any rate</li> </ul> </li> </ul> <p>In summary, the execution tracer is a powerful tool for understanding how an application performs. As we have seen with the merge sort example, we can identify poorly parallelized execution. However, the tracer\\u2019s granularity remains per goroutine unless we manually use <code>runtime/trace</code> compared to a CPU profile, for example. We can use both profiling and the execution tracer to get the most out of the standard Go diagnostics tools when optimizing an application.</p>\"},{\"location\":\"book/\",\"title\":\"100 Go Mistakes and How to Avoid Them\",\"text\":\"\"},{\"location\":\"book/#100-go-mistakes-and-how-to-avoid-them\",\"title\":\"100 Go Mistakes and How to Avoid Them\",\"text\":\"\"},{\"location\":\"book/#description\",\"title\":\"Description\",\"text\":\"<p>If you're a Go developer looking to improve your skills, the 100 Go Mistakes and How to Avoid Them book is for you. With a focus on practical examples, this book covers a wide range of topics from concurrency and error handling to testing and code organization. You'll learn to write more idiomatic, efficient, and maintainable code and become a proficient Go developer.</p> <p>Read a summary of the 100 mistakes or the first chapter.</p>\"},{\"location\":\"book/#quotes-and-ratings\",\"title\":\"Quotes and Ratings\",\"text\":\"<p>Krystian (Goodreads user)</p> <p>This is an exceptional book. Usually, if a book contains either high-quality explanations or is written succinctly, I consider myself lucky to have found it. This one combines these two characteristics, which is super rare. It's another Go book for me and I still had quite a lot of \\\"a-ha!\\\" moments while reading it, and all of that without the unnecessary fluff, just straight to the point.</p> <p>Akash Chetty</p> <p>The book is completely exceptional, especially the examples carved out for each topic are really great. There is one topic that I struggled to understand is Concurrency but the way it is explained in this book is truly an art of genius.</p> <p>Neeraj Shah</p> <p>This should be the required reading for all Golang developers before they touch code in Production... It's the Golang equivalent of the legendary 'Effective Java' by Joshua Bloch.</p> <p>Anupam Sengupta</p> <p>Not having this will be the 101st mistake a Go programmer could make.</p> <p> </p> Manning, Goodreads, and Amazon reviews: 4.7/5 avg rating\"},{\"location\":\"book/#where-to-buy\",\"title\":\"Where to Buy?\",\"text\":\"<ul> <li> <p>100 Go Mistakes and How to Avoid Them (\\ud83c\\uddec\\ud83c\\udde7 edition: paper, digital, or audiobook)</p> <ul> <li>Manning (please make sure to use my personal discount code for -35%: <code>au35har</code>)</li> <li>O\\u2019Reilly</li> <li>Amazon: .com, .co.uk, .de, .fr, .in, .co.jp, .es, .it, .com.br</li> </ul> </li> <li> <p>Go\\u8a00\\u8a9e100Tips \\u958b\\u767a\\u8005\\u306b\\u3042\\u308a\\u304c\\u3061\\u306a\\u9593\\u9055\\u3044\\u3078\\u306e\\u5bfe\\u51e6\\u6cd5 (\\ud83c\\uddef\\ud83c\\uddf5 edition: paper or digital)</p> <ul> <li>Amazon: .co.jp</li> </ul> </li> <li> <p>100\\u4e2aGo\\u8bed\\u8a00\\u5178\\u578b\\u9519\\u8bef (\\ud83c\\udde8\\ud83c\\uddf3 edition: paper or digital)</p> <ul> <li>Douban.com</li> </ul> </li> <li> <p>Go 100\\uac00\\uc9c0 \\uc2e4\\uc218 \\ud328\\ud134\\uacfc \\uc194\\ub8e8\\uc158 (\\ud83c\\uddf0\\ud83c\\uddf7 edition: paper or digital)</p> <ul> <li>Yes24.com</li> </ul> </li> </ul> <p> </p> Covers (English, Japanese, Chinese, and Korean)\"},{\"location\":\"book/#about-the-author\",\"title\":\"About the Author\",\"text\":\"<p>Teiva Harsanyi is a senior software engineer at Google. He has worked in various domains, including insurance, transportation, and safety-critical industries like air traffic management. He is passionate about Go and how to design and implement reliable systems.</p>\"},{\"location\":\"chapter-1/\",\"title\":\"Read the First Chapter\",\"text\":\"\"},{\"location\":\"chapter-1/#go-simple-to-learn-but-hard-to-master\",\"title\":\"Go: Simple to learn but hard to master\",\"text\":\"<p>This chapter covers</p> <ul> <li>What makes Go an efficient, scalable, and productive language</li> <li>Exploring why Go is simple to learn but hard to master</li> <li>Presenting the common types of mistakes made by developers</li> </ul> <p>Making mistakes is part of everyone\\u2019s life. As Albert Einstein once said,</p> <p>Albert Einstein</p> <p>A person who never made a mistake never tried anything new.</p> <p>What matters in the end isn\\u2019t the number of mistakes we make, but our capacity to learn from them. This assertion also applies to programming. The seniority we acquire in a language isn\\u2019t a magical process; it involves making many mistakes and learning from them. The purpose of this book is centered around this idea. It will help you, the reader, become a more proficient Go developer by looking at and learning from 100 common mistakes people make in many areas of the language.</p> <p>This chapter presents a quick refresher as to why Go has become mainstream over the years. We\\u2019ll discuss why, despite Go being considered simple to learn, mastering its nuances can be challenging. Finally, we\\u2019ll introduce the concepts this book covers.</p>\"},{\"location\":\"chapter-1/#go-outline\",\"title\":\"Go outline\",\"text\":\"<p>If you are reading this book, it\\u2019s likely that you\\u2019re already sold on Go. Therefore, this section provides a brief reminder about what makes Go such a powerful language.</p> <p>Software engineering has evolved considerably during the past decades. Most modern systems are no longer written by a single person but by teams consisting of multiple programmers\\u2014sometimes even hundreds, if not thousands. Nowadays, code must be readable, expressive, and maintainable to guarantee a system\\u2019s durability over the years. Meanwhile, in our fast-moving world, maximizing agility and reducing the time to market is critical for most organizations. Programming should also follow this trend, and companies strive to ensure that software engineers are as productive as possible when reading, writing, and maintaining code.</p> <p>In response to these challenges, Google created the Go programming language in 2007. Since then, many organizations have adopted the language to support various use cases: APIs, automation, databases, CLIs (command-line interfaces), and so on. Many today consider Go the language of the cloud.</p> <p>Feature-wise, Go has no type inheritance, no exceptions, no macros, no partial functions, no support for lazy variable evaluation or immutability, no operator overloading, no pattern matching, and on and on. Why are these features missing from the language? The official Go FAQ gives us some insight:</p> <p>Go FAQ</p> <p>Why does Go not have feature X? Your favorite feature may be missing because it doesn\\u2019t fit, because it affects compilation speed or clarity of design, or because it would make the fundamental system model too difficult.</p> <p>Judging the quality of a programming language via its number of features is probably not an accurate metric. At least, it\\u2019s not an objective of Go. Instead, Go utilizes a few essential characteristics when adopting a language at scale for an organization. These include the following:</p> <ul> <li>Stability\\u2014Even though Go receives frequent updates (including improvements and security patches), it remains a stable language. Some may even consider this one of the best features of the language.</li> <li>Expressivity\\u2014We can define expressivity in a programming language by how naturally and intuitively we can write and read code. A reduced number of keywords and limited ways to solve common problems make Go an expressive language for large codebases.</li> <li>Compilation\\u2014As developers, what can be more exasperating than having to wait for a build to test our application? Targeting fast compilation times has always been a conscious goal for the language designers. This, in turn, enables productivity.</li> <li>Safety\\u2014Go is a strong, statically typed language. Hence, it has strict compiletime rules, which ensure the code is type-safe in most cases.</li> </ul> <p>Go was built from the ground up with solid features such as outstanding concurrency primitives with goroutines and channels. There\\u2019s not a strong need to rely on external libraries to build efficient concurrent applications. Observing how important concurrency is these days also demonstrates why Go is such a suitable language for the present and probably for the foreseeable future.</p> <p>Some also consider Go a simple language. And, in a sense, this isn\\u2019t necessarily wrong. For example, a newcomer can learn the language\\u2019s main features in less than a day. So why read a book centered on the concept of mistakes if Go is simple?</p>\"},{\"location\":\"chapter-1/#simple-doesnt-mean-easy\",\"title\":\"Simple doesn\\u2019t mean easy\",\"text\":\"<p>There is a subtle difference between simple and easy. Simple, applied to a technology, means not complicated to learn or understand. However, easy means that we can achieve anything without much effort. Go is simple to learn but not necessarily easy to master.</p> <p>Let\\u2019s take concurrency, for example. In 2019, a study focusing on concurrency bugs was published: Understanding Real-World Concurrency Bugs in Go. This study was the first systematic analysis of concurrency bugs. It focused on multiple popular Go repositories such as Docker, gRPC, and Kubernetes. One of the most important takeaways from this study is that most of the blocking bugs are caused by inaccurate use of the message-passing paradigm via channels, despite the belief that message passing is easier to handle and less error-prone than sharing memory.</p> <p>What should be an appropriate reaction to such a takeaway? Should we consider that the language designers were wrong about message passing? Should we reconsider how we deal with concurrency in our project? Of course not.</p> <p>It\\u2019s not a question of confronting message passing versus sharing memory and determining the winner. However, it\\u2019s up to us as Go developers to thoroughly understand how to use concurrency, its implications on modern processors, when to favor one approach over the other, and how to avoid common traps. This example highlights that although a concept such as channels and goroutines can be simple to learn, it isn\\u2019t an easy topic in practice.</p> <p>This leitmotif\\u2014simple doesn\\u2019t mean easy\\u2014can be generalized to many aspects of Go, not only concurrency. Hence, to be proficient Go developers, we must have a thorough understanding of many aspects of the language, which requires time, effort, and mistakes.</p> <p>This book aims to help accelerate our journey toward proficiency by delving into 100 Go mistakes.</p>\"},{\"location\":\"chapter-1/#100-go-mistakes\",\"title\":\"100 Go mistakes\",\"text\":\"<p>Why should we read a book about common Go mistakes? Why not deepen our knowledge with an ordinary book that would dig into different topics?</p> <p>In a 2011 article, neuroscientists proved that the best time for brain growth is when we\\u2019re facing mistakes. <sup>1</sup> Haven\\u2019t we all experienced the process of learning from a mistake and recalling that occasion after months or even years, when some context related to it? As presented in another article, by Janet Metcalfe, this happens because mistakes have a facilitative effect. <sup>2</sup> The main idea is that we can remember not only the error but also the context surrounding the mistake. This is one of the reasons why learning from mistakes is so efficient.</p> <p>To strengthen this facilitative effect, this book accompanies each mistake as much as possible with real-world examples. This book isn\\u2019t only about theory; it also helps us get better at avoiding mistakes and making more well-informed, conscious decisions because we now understand the rationale behind them.</p> <p>Unknown</p> <p>Tell me and I forget. Teach me and I remember. Involve me and I learn.</p> <p>This book presents seven main categories of mistakes. Overall, the mistakes can be classified as</p> <ul> <li>Bugs</li> <li>Needless complexity</li> <li>Weaker readability</li> <li>Suboptimal or unidiomatic organization </li> <li>Lack of API convenience</li> <li>Under-optimized code</li> <li>Lack of productivity</li> </ul> <p>We introduce each mistake category next.</p>\"},{\"location\":\"chapter-1/#bugs\",\"title\":\"Bugs\",\"text\":\"<p>The first type of mistake and probably the most obvious is software bugs. In 2020, a study conducted by Synopsys estimated the cost of software bugs in the U.S. alone to be over $2 trillion. <sup>3</sup></p> <p>Furthermore, bugs can also lead to tragic impacts. We can, for example, mention cases such as Therac-25, a radiation therapy machine produced by Atomic Energy of Canada Limited (AECL). Because of a race condition, the machine gave its patients radiation doses that were hundreds of times greater than expected, leading to the death of three patients. Hence, software bugs aren\\u2019t only about money. As developers, we should remember how impactful our jobs are.</p> <p>This book covers plenty of cases that could lead to various software bugs, including data races, leaks, logic errors, and other defects. Although accurate tests should be a way to discover such bugs as early as possible, we may sometimes miss cases because of different factors such as time constraints or complexity. Therefore, as a Go developer, it\\u2019s essential to make sure we avoid common bugs.</p>\"},{\"location\":\"chapter-1/#needless-complexity\",\"title\":\"Needless complexity\",\"text\":\"<p>The next category of mistakes is related to unnecessary complexity. A significant part of software complexity comes from the fact that, as developers, we strive to think about imaginary futures. Instead of solving concrete problems right now, it can be tempting to build evolutionary software that could tackle whatever future use case arises. However, this leads to more drawbacks than benefits in most cases because it can make a codebase more complex to understand and reason about.</p> <p>Getting back to Go, we can think of plenty of use cases where developers might be tempted to design abstractions for future needs, such as interfaces or generics. This book discusses topics where we should remain careful not to harm a codebase with needless complexity.</p>\"},{\"location\":\"chapter-1/#weaker-readability\",\"title\":\"Weaker readability\",\"text\":\"<p>Another kind of mistake is to weaken readability. As Robert C. Martin wrote in his book Clean Code: A Handbook of Agile Software Craftsmanship, the ratio of time spent reading versus writing is well over 10 to 1. Most of us started to program on solo projects where readability wasn\\u2019t that important. However, today\\u2019s software engineering is programming with a time dimension: making sure we can still work with and maintain an application months, years, or perhaps even decades later.</p> <p>When programming in Go, we can make many mistakes that can harm readability. These mistakes may include nested code, data type representations, or not using named result parameters in some cases. Throughout this book, we will learn how to write readable code and care for future readers (including our future selves).</p>\"},{\"location\":\"chapter-1/#suboptimal-or-unidiomatic-organization\",\"title\":\"Suboptimal or unidiomatic organization\",\"text\":\"<p>Be it while working on a new project or because we acquire inaccurate reflexes, another type of mistake is organizing our code and a project suboptimally and unidiomatically. Such issues can make a project harder to reason about and maintain. This book covers some of these common mistakes in Go. For example, we\\u2019ll look at how to structure a project and deal with utility packages or init functions. All in all, looking at these mistakes should help us organize our code and projects more efficiently and idiomatically.</p>\"},{\"location\":\"chapter-1/#lack-of-api-convenience\",\"title\":\"Lack of API convenience\",\"text\":\"<p>Making common mistakes that weaken how convenient an API is for our clients is another type of mistake. If an API isn\\u2019t user-friendly, it will be less expressive and, hence, harder to understand and more error-prone.</p> <p>We can think about many situations such as overusing any types, using the wrong creational pattern to deal with options, or blindly applying standard practices from object-oriented programming that affect the usability of our APIs. This book covers common mistakes that prevent us from exposing convenient APIs for our users.</p>\"},{\"location\":\"chapter-1/#under-optimized-code\",\"title\":\"Under-optimized code\",\"text\":\"<p>Under-optimized code is another type of mistake made by developers. It can happen for various reasons, such as not understanding language features or even a lack of fundamental knowledge. Performance is one of the most obvious impacts of this mistake, but not the only one.</p> <p>We can think about optimizing code for other goals, such as accuracy. For example, this book provides some common techniques to ensure that floating-point operations are accurate. Meanwhile, we will cover plenty of cases that can negatively impact performance code because of poorly parallelized executions, not knowing how to reduce allocations, or the impacts of data alignment, for example. We will tackle optimization via different prisms.</p>\"},{\"location\":\"chapter-1/#lack-of-productivity\",\"title\":\"Lack of productivity\",\"text\":\"<p>In most cases, what\\u2019s the best language we can choose when working on a new project? The one we\\u2019re the most productive with. Being comfortable with how a language works and exploiting it to get the best out of it is crucial to reach proficiency.</p> <p>In this book, we will cover many cases and concrete examples that will help us to be more productive while working in Go. For instance, we\\u2019ll look at writing efficient tests to ensure that our code works, relying on the standard library to be more effective, and getting the best out of the profiling tools and linters. Now, it\\u2019s time to delve into those 100 common Go mistakes.</p>\"},{\"location\":\"chapter-1/#summary\",\"title\":\"Summary\",\"text\":\"<ul> <li>Go is a modern programming language that enables developer productivity, which is crucial for most companies today.</li> <li>Go is simple to learn but not easy to master. This is why we need to deepen our knowledge to make the most effective use of the language.</li> <li>Learning via mistakes and concrete examples is a powerful way to be proficient in a language. This book will accelerate our path to proficiency by exploring 100 common mistakes.</li> </ul> <ol> <li> <p>J. S. Moser, H. S. Schroder, et al., \\u201cMind Your Errors: Evidence for a Neural Mechanism Linking Growth Mindset to Adaptive Posterror Adjustments,\\u201d Psychological Science, vol. 22, no. 12, pp. 1484\\u20131489, Dec. 2011.\\u00a0\\u21a9</p> </li> <li> <p>J. Metcalfe, \\u201cLearning from Errors,\\u201d Annual Review of Psychology, vol. 68, pp. 465\\u2013489, Jan. 2017.\\u00a0\\u21a9</p> </li> <li> <p>Synopsys, \\u201cThe Cost of Poor Software Quality in the US: A 2020 Report.\\u201d 2020. https://news.synopsys.com/2021-01-06-Synopsys-Sponsored-CISQ-Research-Estimates-Cost-of-Poor-Software-Quality-in-the-US-2-08-Trillion-in-2020.\\u00a0\\u21a9</p> </li> </ol>\"},{\"location\":\"external/\",\"title\":\"External Resources\",\"text\":\"\"},{\"location\":\"external/#external-resources\",\"title\":\"External Resources\",\"text\":\"\"},{\"location\":\"external/#english\",\"title\":\"English\",\"text\":\"\"},{\"location\":\"external/#the-best-golang-book-prime-reacts\",\"title\":\"The Best Golang Book | Prime Reacts\",\"text\":\"\"},{\"location\":\"external/#book-review-100-go-mistakes-and-how-to-avoid-them\",\"title\":\"Book Review: 100 Go Mistakes (And How to Avoid Them)\",\"text\":\"<p>Post</p>\"},{\"location\":\"external/#the-most-useful-book-for-a-go-programmer\",\"title\":\"The Most Useful Book for a Go Programmer?\",\"text\":\"\"},{\"location\":\"external/#how-to-make-mistakes-in-go-go-time-190\",\"title\":\"How to make mistakes in Go - Go Time #190\",\"text\":\"<ul> <li>Episode</li> <li>Spotify</li> </ul>\"},{\"location\":\"external/#go-is-amazing\",\"title\":\"Go is AMAZING\",\"text\":\"\"},{\"location\":\"external/#8lu-100-test-coverage\",\"title\":\"8LU - 100% Test Coverage\",\"text\":\"\"},{\"location\":\"external/#some-tips-i-learned-from-100-mistakes-in-go\",\"title\":\"Some Tips I learned from 100 Mistakes in Go\",\"text\":\"<p>Post</p>\"},{\"location\":\"external/#what-can-be-summarized-from-100-go-mistakes\",\"title\":\"What can be summarized from 100 Go Mistakes?\",\"text\":\"<p>Post</p>\"},{\"location\":\"external/#book-review-100-go-mistakes-and-how-to-avoid-them_1\",\"title\":\"Book review: 100 Go Mistakes and How to Avoid Them\",\"text\":\"<p>Post</p>\"},{\"location\":\"external/#chinese\",\"title\":\"Chinese\",\"text\":\"\"},{\"location\":\"external/#100-go-mistakes-and-how-to-avoid-them\",\"title\":\"\\u6df1\\u5ea6\\u9605\\u8bfb\\u4e4b\\u300a100 Go Mistakes and How to Avoid Them\",\"text\":\"<p>Post</p>\"},{\"location\":\"external/#100-go-mistakes\",\"title\":\"100 Go Mistakes \\u968f\\u8bb0\",\"text\":\"<p>Post</p>\"},{\"location\":\"external/#go\",\"title\":\"\\u6211\\u4e3a\\u4ec0\\u4e48\\u653e\\u5f03Go\\u8bed\\u8a00\\uff1f\",\"text\":\"<p>Post</p>\"},{\"location\":\"external/#japanese\",\"title\":\"Japanese\",\"text\":\"\"},{\"location\":\"external/#go100-go-mistakes-and-how-to-avoid-them\",\"title\":\"\\u6700\\u8fd1\\u8aad\\u3093\\u3060Go\\u8a00\\u8a9e\\u306e\\u672c\\u306e\\u7d39\\u4ecb\\uff1a100 Go Mistakes and How to Avoid Them\",\"text\":\"<p>Post</p>\"},{\"location\":\"external/#100-go-mistakes-and-how-to-avoid-them_1\",\"title\":\"\\u300e100 Go Mistakes and How to Avoid Them\\u300f\\u3092\\u8aad\\u3080\",\"text\":\"<p>Post</p>\"},{\"location\":\"external/#portuguese\",\"title\":\"Portuguese\",\"text\":\"\"},{\"location\":\"external/#um-otimo-livro-para-programadores-go\",\"title\":\"Um \\u00d3TIMO livro para programadores Go\",\"text\":\"\"},{\"location\":\"ja/\",\"title\":\"Japanese Version\",\"text\":\"\"},{\"location\":\"ja/#go\",\"title\":\"Go\\u8a00\\u8a9e\\u3067\\u3042\\u308a\\u304c\\u3061\\u306a\\u9593\\u9055\\u3044\",\"text\":\"The Coder Cafe <p>\\u3082\\u3057\\u79c1\\u306e\\u672c\\u3092\\u697d\\u3057\\u3093\\u3067\\u3044\\u305f\\u3060\\u3051\\u305f\\u306a\\u3089\\u3001\\u79c1\\u306e\\u6700\\u65b0\\u30d7\\u30ed\\u30b8\\u30a7\\u30af\\u30c8\\u306b\\u3082\\u3054\\u8208\\u5473\\u304c\\u3042\\u308b\\u304b\\u3082\\u3057\\u308c\\u307e\\u305b\\u3093\\u3002The Coder Cafe\\u306f\\u3001\\u30b3\\u30fc\\u30c0\\u30fc\\u5411\\u3051\\u306e\\u65e5\\u520a\\u30cb\\u30e5\\u30fc\\u30b9\\u30ec\\u30bf\\u30fc\\u3067\\u3059\\u3002</p> <p>Feeling overwhelmed by the endless stream of tech content? At The Coder Cafe, we serve one essential concept for coders. Written by a senior software engineer at Google, it's perfectly brewed for your morning coffee, helping you grow your skills deeply.</p> <p></p><p></p> <p>\\u3053\\u306e\\u30da\\u30fc\\u30b8\\u306f\\u300e100 Go Mistakes\\u300f\\u306e\\u5185\\u5bb9\\u3092\\u307e\\u3068\\u3081\\u305f\\u3082\\u306e\\u3067\\u3059\\u3002\\u4e00\\u65b9\\u3067\\u3001\\u30b3\\u30df\\u30e5\\u30cb\\u30c6\\u30a3\\u306b\\u958b\\u304b\\u308c\\u305f\\u30da\\u30fc\\u30b8\\u3067\\u3082\\u3042\\u308a\\u307e\\u3059\\u3002\\u300c\\u3042\\u308a\\u304c\\u3061\\u306a\\u9593\\u9055\\u3044\\u300d\\u304c\\u65b0\\u305f\\u306b\\u8ffd\\u52a0\\u3055\\u308c\\u308b\\u3079\\u304d\\u3060\\u3068\\u304a\\u8003\\u3048\\u3067\\u3057\\u305f\\u3089 community mistake issue \\u3092\\u4f5c\\u6210\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p></p> \\u6ce8\\u610f <p>\\u73fe\\u5728\\u3001\\u5927\\u5e45\\u306b\\u591a\\u304f\\u306e\\u30b3\\u30f3\\u30c6\\u30f3\\u30c4\\u3092\\u8ffd\\u52a0\\u3057\\u3066\\u5f37\\u5316\\u3057\\u3066\\u3044\\u308b\\u65b0\\u3057\\u3044\\u30d0\\u30fc\\u30b8\\u30e7\\u30f3\\u3092\\u95b2\\u89a7\\u3057\\u3066\\u3044\\u307e\\u3059\\u3002\\u3053\\u306e\\u30d0\\u30fc\\u30b8\\u30e7\\u30f3\\u306f\\u307e\\u3060\\u958b\\u767a\\u4e2d\\u3067\\u3059\\u3002\\u554f\\u984c\\u3092\\u898b\\u3064\\u3051\\u305f\\u5834\\u5408\\u306f\\u3069\\u3046\\u305e\\u6c17\\u8efd\\u306bPR\\u3092\\u4f5c\\u6210\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p>\"},{\"location\":\"ja/#_1\",\"title\":\"\\u30b3\\u30fc\\u30c9\\u3068\\u30d7\\u30ed\\u30b8\\u30a7\\u30af\\u30c8\\u69cb\\u6210\",\"text\":\"\"},{\"location\":\"ja/#1\",\"title\":\"\\u610f\\u56f3\\u7684\\u3067\\u306a\\u3044\\u5909\\u6570\\u306e\\u30b7\\u30e3\\u30c9\\u30fc\\u30a4\\u30f3\\u30b0 (#1)\",\"text\":\"\\u8981\\u7d04 <p>\\u5909\\u6570\\u306e\\u30b7\\u30e3\\u30c9\\u30fc\\u30a4\\u30f3\\u30b0\\u3092\\u907f\\u3051\\u308b\\u3053\\u3068\\u306f\\u3001\\u8aa4\\u3063\\u305f\\u5909\\u6570\\u306e\\u53c2\\u7167\\u3084\\u8aad\\u307f\\u624b\\u306e\\u6df7\\u4e71\\u3092\\u9632\\u304e\\u307e\\u3059\\u3002</p> <p>\\u5909\\u6570\\u306e\\u30b7\\u30e3\\u30c9\\u30fc\\u30a4\\u30f3\\u30b0\\u306f\\u3001\\u5909\\u6570\\u540d\\u304c\\u30d6\\u30ed\\u30c3\\u30af\\u5185\\u3067\\u518d\\u5ba3\\u8a00\\u3055\\u308c\\u308b\\u3053\\u3068\\u3067\\u751f\\u3058\\u307e\\u3059\\u304c\\u3001\\u3053\\u308c\\u306f\\u9593\\u9055\\u3044\\u3092\\u5f15\\u304d\\u8d77\\u3053\\u3057\\u3084\\u3059\\u304f\\u3057\\u307e\\u3059\\u3002\\u5909\\u6570\\u306e\\u30b7\\u30e3\\u30c9\\u30fc\\u30a4\\u30f3\\u30b0\\u3092\\u7981\\u6b62\\u3059\\u308b\\u304b\\u3069\\u3046\\u304b\\u306f\\u500b\\u4eba\\u306e\\u597d\\u307f\\u306b\\u3088\\u308a\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001\\u30a8\\u30e9\\u30fc\\u306b\\u5bfe\\u3057\\u3066 <code>err</code> \\u306e\\u3088\\u3046\\u306a\\u65e2\\u5b58\\u306e\\u5909\\u6570\\u540d\\u3092\\u518d\\u5229\\u7528\\u3059\\u308b\\u3068\\u4fbf\\u5229\\u306a\\u5834\\u5408\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3068\\u306f\\u3044\\u3048\\u3001\\u30b3\\u30fc\\u30c9\\u306f\\u30b3\\u30f3\\u30d1\\u30a4\\u30eb\\u3055\\u308c\\u305f\\u3082\\u306e\\u306e\\u3001\\u5024\\u3092\\u53d7\\u3051\\u53d6\\u3063\\u305f\\u5909\\u6570\\u304c\\u4e88\\u671f\\u3057\\u305f\\u3082\\u306e\\u3067\\u306f\\u306a\\u3044\\u3068\\u3044\\u3046\\u30b7\\u30ca\\u30ea\\u30aa\\u306b\\u76f4\\u9762\\u3059\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u305f\\u3081\\u3001\\u539f\\u5247\\u3068\\u3057\\u3066\\u5f15\\u304d\\u7d9a\\u304d\\u6ce8\\u610f\\u3092\\u6255\\u3046\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#2\",\"title\":\"\\u4e0d\\u5fc5\\u8981\\u306b\\u30cd\\u30b9\\u30c8\\u3055\\u308c\\u305f\\u30b3\\u30fc\\u30c9 (#2)\",\"text\":\"\\u8981\\u7d04 <p>\\u30cd\\u30b9\\u30c8\\u304c\\u6df1\\u304f\\u306a\\u3089\\u306a\\u3044\\u3088\\u3046\\u306b\\u3057\\u3001\\u30cf\\u30c3\\u30d4\\u30fc\\u30d1\\u30b9\\u3092\\u5de6\\u5074\\u306b\\u63c3\\u3048\\u308b\\u3053\\u3068\\u3067\\u30e1\\u30f3\\u30bf\\u30eb\\u30b3\\u30fc\\u30c9\\u30e2\\u30c7\\u30eb\\u3092\\u69cb\\u7bc9\\u3059\\u308b\\u3053\\u3068\\u304c\\u5bb9\\u6613\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002</p> <p>\\u4e00\\u822c\\u7684\\u306b\\u3001\\u95a2\\u6570\\u304c\\u3088\\u308a\\u6df1\\u3044\\u30cd\\u30b9\\u30c8\\u3092\\u8981\\u6c42\\u3059\\u308b\\u307b\\u3069\\u3001\\u8aad\\u3093\\u3067\\u7406\\u89e3\\u3059\\u308b\\u3053\\u3068\\u304c\\u3088\\u308a\\u8907\\u96d1\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002\\u79c1\\u305f\\u3061\\u306e\\u30b3\\u30fc\\u30c9\\u306e\\u53ef\\u8aad\\u6027\\u3092\\u6700\\u9069\\u5316\\u3059\\u308b\\u305f\\u3081\\u306b\\u3001\\u3053\\u306e\\u30eb\\u30fc\\u30eb\\u306e\\u9069\\u7528\\u65b9\\u6cd5\\u3092\\u898b\\u3066\\u3044\\u304d\\u307e\\u3057\\u3087\\u3046\\u3002</p> <ul> <li><code>if</code> \\u30d6\\u30ed\\u30c3\\u30af\\u304c\\u8fd4\\u3055\\u308c\\u308b\\u3068\\u304d\\u3001\\u3059\\u3079\\u3066\\u306e\\u5834\\u5408\\u306b\\u304a\\u3044\\u3066 <code>else</code> \\u30d6\\u30ed\\u30c3\\u30af\\u3092\\u7701\\u7565\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002 \\u305f\\u3068\\u3048\\u3070\\u3001\\u6b21\\u306e\\u3088\\u3046\\u306b\\u66f8\\u304f\\u3079\\u304d\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002</li> </ul> <pre><code>if foo() {\\n    // ...\\n    return true\\n} else {\\n    // ...\\n}\\n</code></pre> <p>\\u4ee3\\u308f\\u308a\\u306b\\u3001\\u6b21\\u306e\\u3088\\u3046\\u306b <code>else</code> \\u30d6\\u30ed\\u30c3\\u30af\\u3092\\u7701\\u7565\\u3057\\u307e\\u3059\\u3002</p> <pre><code>if foo() {\\n    // ...\\n    return true\\n}\\n// ...\\n</code></pre> <ul> <li>\\u30ce\\u30f3\\u30cf\\u30c3\\u30d4\\u30fc\\u30d1\\u30b9\\u3067\\u3082\\u3053\\u306e\\u30ed\\u30b8\\u30c3\\u30af\\u306b\\u5f93\\u3046\\u3053\\u3068\\u304c\\u53ef\\u80fd\\u3067\\u3059\\u3002</li> </ul> <pre><code>if s != \\\"\\\" {\\n    // ...\\n} else {\\n    return errors.New(\\\"empty string\\\")\\n}\\n</code></pre> <p>\\u3053\\u3053\\u3067\\u306f\\u3001\\u7a7a\\u306e <code>s</code> \\u304c\\u30ce\\u30f3\\u30cf\\u30c3\\u30d4\\u30fc\\u30d1\\u30b9\\u3092\\u8868\\u3057\\u307e\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u6b21\\u306e\\u3088\\u3046\\u306b\\u6761\\u4ef6\\u3092\\u3072\\u3063\\u304f\\u308a\\u8fd4\\u3059\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <pre><code>if s == \\\"\\\" {\\n    return errors.New(\\\"empty string\\\")\\n}\\n// ...\\n</code></pre> <p>\\u8aad\\u307f\\u3084\\u3059\\u3044\\u30b3\\u30fc\\u30c9\\u3092\\u66f8\\u304f\\u3053\\u3068\\u306f\\u3001\\u3059\\u3079\\u3066\\u306e\\u958b\\u767a\\u8005\\u306b\\u3068\\u3063\\u3066\\u91cd\\u8981\\u306a\\u8ab2\\u984c\\u3067\\u3059\\u3002\\u30cd\\u30b9\\u30c8\\u3055\\u308c\\u305f\\u30d6\\u30ed\\u30c3\\u30af\\u306e\\u6570\\u3092\\u6e1b\\u3089\\u3059\\u3088\\u3046\\u52aa\\u3081\\u3001\\u30cf\\u30c3\\u30d4\\u30fc\\u30d1\\u30b9\\u3092\\u5de6\\u5074\\u306b\\u63c3\\u3048\\u3001\\u3067\\u304d\\u308b\\u3060\\u3051\\u65e9\\u304f\\u623b\\u308b\\u3053\\u3068\\u304c\\u3001\\u30b3\\u30fc\\u30c9\\u306e\\u53ef\\u8aad\\u6027\\u3092\\u5411\\u4e0a\\u3055\\u305b\\u308b\\u5177\\u4f53\\u7684\\u306a\\u624b\\u6bb5\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#init-3\",\"title\":\"init\\u95a2\\u6570\\u306e\\u8aa4\\u7528 (#3)\",\"text\":\"\\u8981\\u7d04 <p>\\u5909\\u6570\\u3092\\u521d\\u671f\\u5316\\u3059\\u308b\\u3068\\u304d\\u306f\\u3001init\\u95a2\\u6570\\u306e\\u30a8\\u30e9\\u30fc\\u51e6\\u7406\\u304c\\u5236\\u9650\\u3055\\u308c\\u3066\\u304a\\u308a\\u3001\\u30b9\\u30c6\\u30fc\\u30c8\\u306e\\u51e6\\u7406\\u3068\\u30c6\\u30b9\\u30c8\\u304c\\u3088\\u308a\\u8907\\u96d1\\u306b\\u306a\\u308b\\u3053\\u3068\\u306b\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u307b\\u3068\\u3093\\u3069\\u306e\\u5834\\u5408\\u3001\\u521d\\u671f\\u5316\\u306f\\u7279\\u5b9a\\u306e\\u95a2\\u6570\\u3068\\u3057\\u3066\\u51e6\\u7406\\u3055\\u308c\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002</p> <p>init\\u95a2\\u6570\\u306f\\u3001\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u306e\\u30b9\\u30c6\\u30fc\\u30c8\\u3092\\u521d\\u671f\\u5316\\u3059\\u308b\\u305f\\u3081\\u306b\\u4f7f\\u7528\\u3055\\u308c\\u308b\\u95a2\\u6570\\u3067\\u3059\\u3002\\u5f15\\u6570\\u3092\\u53d6\\u3089\\u305a\\u3001\\u7d50\\u679c\\u3082\\u8fd4\\u3057\\u307e\\u305b\\u3093\\uff08 <code>func()</code> \\u95a2\\u6570\\uff09\\u3002\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u304c\\u521d\\u671f\\u5316\\u3055\\u308c\\u308b\\u3068\\u3001\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u5185\\u306e\\u3059\\u3079\\u3066\\u306e\\u5b9a\\u6570\\u304a\\u3088\\u3073\\u5909\\u6570\\u306e\\u5ba3\\u8a00\\u304c\\u8a55\\u4fa1\\u3055\\u308c\\u307e\\u3059\\u3002\\u6b21\\u306b\\u3001init\\u95a2\\u6570\\u304c\\u5b9f\\u884c\\u3055\\u308c\\u307e\\u3059\\u3002</p> <p>init\\u95a2\\u6570\\u306f\\u3044\\u304f\\u3064\\u304b\\u306e\\u554f\\u984c\\u3092\\u5f15\\u304d\\u8d77\\u3053\\u3059\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <ul> <li>\\u30a8\\u30e9\\u30fc\\u51e6\\u7406\\u304c\\u5236\\u9650\\u3055\\u308c\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</li> <li>\\u30c6\\u30b9\\u30c8\\u306e\\u5b9f\\u88c5\\u65b9\\u6cd5\\u304c\\u8907\\u96d1\\u306b\\u306a\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\uff08\\u305f\\u3068\\u3048\\u3070\\u3001\\u5916\\u90e8\\u4f9d\\u5b58\\u95a2\\u4fc2\\u3092\\u8a2d\\u5b9a\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u304c\\u3001\\u5358\\u4f53\\u30c6\\u30b9\\u30c8\\u306e\\u7bc4\\u56f2\\u3067\\u306f\\u5fc5\\u8981\\u306a\\u3044\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\uff09\\u3002</li> <li>\\u521d\\u671f\\u5316\\u3067\\u30b9\\u30c6\\u30fc\\u30c8\\u3092\\u8a2d\\u5b9a\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u5834\\u5408\\u306f\\u3001\\u30b0\\u30ed\\u30fc\\u30d0\\u30eb\\u5909\\u6570\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u884c\\u3046\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</li> </ul> <p>init\\u95a2\\u6570\\u306b\\u306f\\u6ce8\\u610f\\u304c\\u5fc5\\u8981\\u3067\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u9759\\u7684\\u69cb\\u6210\\u306e\\u5b9a\\u7fa9\\u306a\\u3069\\u3001\\u72b6\\u6cc1\\u306b\\u3088\\u3063\\u3066\\u306f\\u5f79\\u7acb\\u3064\\u5834\\u5408\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305d\\u308c\\u4ee5\\u5916\\u306e\\u307b\\u3068\\u3093\\u3069\\u306e\\u5834\\u5408\\u3001\\u521d\\u671f\\u5316\\u51e6\\u7406\\u306f\\u7279\\u5b9a\\u306e\\u95a2\\u6570\\u3092\\u901a\\u3058\\u3066\\u884c\\u308f\\u308c\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#4\",\"title\":\"\\u30b2\\u30c3\\u30bf\\u30fc\\u3068\\u30bb\\u30c3\\u30bf\\u30fc\\u306e\\u4e71\\u7528 (#4)\",\"text\":\"\\u8981\\u7d04 <p>Go\\u8a00\\u8a9e\\u3067\\u306f\\u3001\\u6163\\u7528\\u7684\\u306b\\u30b2\\u30c3\\u30bf\\u30fc\\u3068\\u30bb\\u30c3\\u30bf\\u30fc\\u306e\\u4f7f\\u7528\\u3092\\u5f37\\u5236\\u3059\\u308b\\u3053\\u3068\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u5b9f\\u5229\\u3092\\u91cd\\u8996\\u3057\\u3001\\u52b9\\u7387\\u6027\\u3068\\u7279\\u5b9a\\u306e\\u6163\\u7fd2\\u306b\\u5f93\\u3046\\u3053\\u3068\\u3068\\u306e\\u9593\\u306e\\u9069\\u5207\\u306a\\u30d0\\u30e9\\u30f3\\u30b9\\u3092\\u898b\\u3064\\u3051\\u308b\\u3053\\u3068\\u304c\\u3001\\u9032\\u3080\\u3079\\u304d\\u9053\\u3067\\u3042\\u308b\\u306f\\u305a\\u3067\\u3059\\u3002</p> <p>\\u30c7\\u30fc\\u30bf\\u306e\\u30ab\\u30d7\\u30bb\\u30eb\\u5316\\u3068\\u306f\\u3001\\u30aa\\u30d6\\u30b8\\u30a7\\u30af\\u30c8\\u306e\\u5024\\u307e\\u305f\\u306f\\u72b6\\u614b\\u3092\\u96a0\\u3059\\u3053\\u3068\\u3092\\u6307\\u3057\\u307e\\u3059\\u3002\\u30b2\\u30c3\\u30bf\\u30fc\\u3068\\u30bb\\u30c3\\u30bf\\u30fc\\u306f\\u3001\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3055\\u308c\\u3066\\u3044\\u306a\\u3044\\u30aa\\u30d6\\u30b8\\u30a7\\u30af\\u30c8\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u306e\\u4e0a\\u306b\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3055\\u308c\\u305f\\u30e1\\u30bd\\u30c3\\u30c9\\u3092\\u63d0\\u4f9b\\u3059\\u308b\\u3053\\u3068\\u3067\\u30ab\\u30d7\\u30bb\\u30eb\\u5316\\u3092\\u53ef\\u80fd\\u306b\\u3059\\u308b\\u624b\\u6bb5\\u3067\\u3059\\u3002</p> <p>Go\\u8a00\\u8a9e\\u3067\\u306f\\u3001\\u4e00\\u90e8\\u306e\\u8a00\\u8a9e\\u3067\\u898b\\u3089\\u308c\\u308b\\u3088\\u3046\\u306a\\u30b2\\u30c3\\u30bf\\u30fc\\u3068\\u30bb\\u30c3\\u30bf\\u30fc\\u306e\\u81ea\\u52d5\\u30b5\\u30dd\\u30fc\\u30c8\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u307e\\u305f\\u3001\\u30b2\\u30c3\\u30bf\\u30fc\\u3068\\u30bb\\u30c3\\u30bf\\u30fc\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u69cb\\u9020\\u4f53\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u306b\\u30a2\\u30af\\u30bb\\u30b9\\u3059\\u308b\\u3053\\u3068\\u306f\\u5fc5\\u9808\\u3067\\u3082\\u6163\\u7528\\u7684\\u3067\\u3082\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u5024\\u3092\\u3082\\u305f\\u3089\\u3055\\u306a\\u3044\\u69cb\\u9020\\u4f53\\u306e\\u30b2\\u30c3\\u30bf\\u30fc\\u3068\\u30bb\\u30c3\\u30bf\\u30fc\\u3067\\u30b3\\u30fc\\u30c9\\u3092\\u57cb\\u3081\\u308b\\u3079\\u304d\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u5b9f\\u5229\\u3092\\u91cd\\u8996\\u3057\\u3001\\u4ed6\\u306e\\u30d7\\u30ed\\u30b0\\u30e9\\u30df\\u30f3\\u30b0\\u30d1\\u30e9\\u30c0\\u30a4\\u30e0\\u3067\\u6642\\u306b\\u306f\\u8b70\\u8ad6\\u306e\\u4f59\\u5730\\u304c\\u306a\\u3044\\u3068\\u8003\\u3048\\u3089\\u308c\\u3066\\u3044\\u308b\\u6163\\u7fd2\\u306b\\u5f93\\u3046\\u3053\\u3068\\u3068\\u3001\\u52b9\\u7387\\u6027\\u3068\\u306e\\u9593\\u306e\\u9069\\u5207\\u306a\\u30d0\\u30e9\\u30f3\\u30b9\\u3092\\u898b\\u3064\\u3051\\u308b\\u3088\\u3046\\u52aa\\u3081\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002</p> <p>Go\\u8a00\\u8a9e\\u306f\\u3001\\u30b7\\u30f3\\u30d7\\u30eb\\u3055\\u3092\\u542b\\u3080\\u591a\\u304f\\u306e\\u7279\\u6027\\u3092\\u8003\\u616e\\u3057\\u3066\\u8a2d\\u8a08\\u3055\\u308c\\u305f\\u72ec\\u81ea\\u306e\\u8a00\\u8a9e\\u3067\\u3042\\u308b\\u3053\\u3068\\u3092\\u5fd8\\u308c\\u306a\\u3044\\u3067\\u304f\\u3060\\u3055\\u3044\\u3002\\u305f\\u3060\\u3057\\u3001\\u30b2\\u30c3\\u30bf\\u30fc\\u3068\\u30bb\\u30c3\\u30bf\\u30fc\\u306e\\u5fc5\\u8981\\u6027\\u304c\\u898b\\u3064\\u304b\\u3063\\u305f\\u5834\\u5408\\u3001\\u307e\\u305f\\u306f\\u524d\\u8ff0\\u306e\\u3088\\u3046\\u306b\\u3001\\u524d\\u65b9\\u4e92\\u63db\\u6027\\u3092\\u4fdd\\u8a3c\\u3057\\u306a\\u304c\\u3089\\u5c06\\u6765\\u306e\\u5fc5\\u8981\\u6027\\u304c\\u4e88\\u6e2c\\u3055\\u308c\\u308b\\u5834\\u5408\\u306f\\u3001\\u305d\\u308c\\u3089\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u306b\\u554f\\u984c\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002</p>\"},{\"location\":\"ja/#5\",\"title\":\"\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u6c5a\\u67d3 (#5)\",\"text\":\"\\u8981\\u7d04 <p>\\u62bd\\u8c61\\u5316\\u306f\\u4f5c\\u6210\\u3055\\u308c\\u308b\\u3079\\u304d\\u3082\\u306e\\u3067\\u306f\\u306a\\u304f\\u3001\\u767a\\u898b\\u3055\\u308c\\u308b\\u3079\\u304d\\u3082\\u306e\\u3067\\u3059\\u3002\\u4e0d\\u5fc5\\u8981\\u306a\\u8907\\u96d1\\u3055\\u3092\\u907f\\u3051\\u308b\\u305f\\u3081\\u306b\\u3001\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u306f\\u3001\\u5fc5\\u8981\\u306b\\u306a\\u308b\\u3068\\u4e88\\u6e2c\\u3057\\u305f\\u3068\\u304d\\u3067\\u306f\\u306a\\u304f\\u3001\\u5fc5\\u8981\\u306b\\u306a\\u3063\\u305f\\u3068\\u304d\\u306b\\u4f5c\\u6210\\u3059\\u308b\\u304b\\u3001\\u5c11\\u306a\\u304f\\u3068\\u3082\\u62bd\\u8c61\\u5316\\u304c\\u6709\\u52b9\\u3067\\u3042\\u308b\\u3053\\u3068\\u3092\\u8a3c\\u660e\\u3067\\u304d\\u308b\\u5834\\u5408\\u306b\\u4f5c\\u6210\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u306f\\u3001\\u30aa\\u30d6\\u30b8\\u30a7\\u30af\\u30c8\\u306e\\u52d5\\u4f5c\\u3092\\u6307\\u5b9a\\u3059\\u308b\\u65b9\\u6cd5\\u3092\\u63d0\\u4f9b\\u3057\\u307e\\u3059\\u3002\\u8907\\u6570\\u306e\\u30aa\\u30d6\\u30b8\\u30a7\\u30af\\u30c8\\u304c\\u5b9f\\u88c5\\u3067\\u304d\\u308b\\u5171\\u901a\\u9805\\u3092\\u62bd\\u51fa\\u3059\\u308b\\u305f\\u3081\\u306b\\u3001\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u306f\\u4f7f\\u7528\\u3055\\u308c\\u307e\\u3059\\u3002Go\\u8a00\\u8a9e\\u306e\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u304c\\u5927\\u304d\\u304f\\u7570\\u306a\\u308b\\u306e\\u306f\\u3001\\u6697\\u9ed9\\u7684\\u306b\\u6e80\\u305f\\u3055\\u308c\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002\\u30aa\\u30d6\\u30b8\\u30a7\\u30af\\u30c8 <code>X</code> \\u304c\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9 <code>Y</code> \\u3092\\u5b9f\\u88c5\\u3057\\u3066\\u3044\\u308b\\u3053\\u3068\\u3092\\u793a\\u3059 <code>implements</code> \\u306e\\u3088\\u3046\\u306a\\u660e\\u793a\\u7684\\u306a\\u30ad\\u30fc\\u30ef\\u30fc\\u30c9\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002</p> <p>\\u4e00\\u822c\\u306b\\u3001\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u304c\\u4fa1\\u5024\\u3092\\u3082\\u305f\\u3089\\u3059\\u3068\\u8003\\u3048\\u3089\\u308c\\u308b\\u4e3b\\u8981\\u306a\\u4f7f\\u7528\\u4f8b\\u306f\\uff13\\u3064\\u3042\\u308a\\u307e\\u3059\\u3002\\u305d\\u308c\\u306f\\u3001\\u5171\\u901a\\u306e\\u52d5\\u4f5c\\u3092\\u9664\\u5916\\u3059\\u308b\\u3001\\u4f55\\u3089\\u304b\\u306e\\u5206\\u96e2\\u3092\\u4f5c\\u6210\\u3059\\u308b\\u3001\\u304a\\u3088\\u3073\\u578b\\u3092\\u7279\\u5b9a\\u306e\\u52d5\\u4f5c\\u306b\\u5236\\u9650\\u3059\\u308b\\u3068\\u3044\\u3046\\u3082\\u306e\\u3067\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u3053\\u306e\\u30ea\\u30b9\\u30c8\\u306f\\u3059\\u3079\\u3066\\u3092\\u7db2\\u7f85\\u3057\\u3066\\u3044\\u308b\\u308f\\u3051\\u3067\\u306f\\u306a\\u304f\\u3001\\u76f4\\u9762\\u3059\\u308b\\u72b6\\u6cc1\\u306b\\u3088\\u3063\\u3066\\u3082\\u7570\\u306a\\u308a\\u307e\\u3059\\u3002</p> <p>\\u591a\\u304f\\u306e\\u5834\\u5408\\u3001\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u306f\\u62bd\\u8c61\\u5316\\u3059\\u308b\\u305f\\u3081\\u306b\\u4f5c\\u6210\\u3055\\u308c\\u307e\\u3059\\u3002\\u305d\\u3057\\u3066\\u3001\\u30d7\\u30ed\\u30b0\\u30e9\\u30df\\u30f3\\u30b0\\u3067\\u62bd\\u8c61\\u5316\\u3059\\u308b\\u3068\\u304d\\u306e\\u4e3b\\u306a\\u6ce8\\u610f\\u70b9\\u306f\\u3001\\u62bd\\u8c61\\u5316\\u306f\\u4f5c\\u6210\\u3055\\u308c\\u308b\\u3079\\u304d\\u3067\\u306f\\u306a\\u304f\\u3001\\u767a\\u898b\\u3055\\u308c\\u308b\\u3079\\u304d\\u3067\\u3042\\u308b\\u3068\\u3044\\u3046\\u3053\\u3068\\u3092\\u899a\\u3048\\u3066\\u304a\\u304f\\u3053\\u3068\\u3067\\u3059\\u3002\\u3059\\u306a\\u308f\\u3061\\u3001\\u305d\\u3046\\u3059\\u308b\\u76f4\\u63a5\\u306e\\u7406\\u7531\\u304c\\u306a\\u3044\\u9650\\u308a\\u3001\\u30b3\\u30fc\\u30c9\\u5185\\u3067\\u62bd\\u8c61\\u5316\\u3059\\u3079\\u304d\\u3067\\u306f\\u306a\\u3044\\u3068\\u3044\\u3046\\u3053\\u3068\\u3067\\u3059\\u3002\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3092\\u4f7f\\u3063\\u3066\\u8a2d\\u8a08\\u3059\\u308b\\u306e\\u3067\\u306f\\u306a\\u304f\\u3001\\u5177\\u4f53\\u7684\\u306a\\u30cb\\u30fc\\u30ba\\u3092\\u5f85\\u3064\\u3079\\u304d\\u3067\\u3059\\u3002\\u5225\\u306e\\u8a00\\u3044\\u65b9\\u3092\\u3059\\u308c\\u3070\\u3001\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u306f\\u5fc5\\u8981\\u306b\\u306a\\u308b\\u3068\\u4e88\\u6e2c\\u3057\\u305f\\u3068\\u304d\\u3067\\u306f\\u306a\\u304f\\u3001\\u5fc5\\u8981\\u306b\\u306a\\u3063\\u305f\\u3068\\u304d\\u306b\\u4f5c\\u6210\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002 \\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u306e\\u904e\\u5ea6\\u306a\\u4f7f\\u7528\\u3092\\u3057\\u305f\\u5834\\u5408\\u306e\\u4e3b\\u306a\\u554f\\u984c\\u306f\\u4f55\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002\\u7b54\\u3048\\u306f\\u3001\\u30b3\\u30fc\\u30c9\\u30d5\\u30ed\\u30fc\\u304c\\u3088\\u308a\\u8907\\u96d1\\u306b\\u306a\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002\\u5f79\\u306b\\u7acb\\u305f\\u306a\\u3044\\u9593\\u63a5\\u53c2\\u7167\\u3092\\u8ffd\\u52a0\\u3057\\u3066\\u3082\\u4f55\\u306e\\u4fa1\\u5024\\u3082\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u305d\\u308c\\u306f\\u4fa1\\u5024\\u306e\\u306a\\u3044\\u62bd\\u8c61\\u5316\\u3092\\u3059\\u308b\\u3053\\u3068\\u3067\\u3001\\u30b3\\u30fc\\u30c9\\u3092\\u8aad\\u307f\\u3001\\u7406\\u89e3\\u3057\\u3001\\u63a8\\u8ad6\\u3059\\u308b\\u3053\\u3068\\u3092\\u3055\\u3089\\u306b\\u56f0\\u96e3\\u306b\\u3057\\u307e\\u3059\\u3002\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3092\\u8ffd\\u52a0\\u3059\\u308b\\u660e\\u78ba\\u306a\\u7406\\u7531\\u304c\\u306a\\u304f\\u3001\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u306b\\u3088\\u3063\\u3066\\u30b3\\u30fc\\u30c9\\u304c\\u3069\\u306e\\u3088\\u3046\\u306b\\u6539\\u5584\\u3055\\u308c\\u308b\\u304b\\u304c\\u4e0d\\u660e\\u77ad\\u306a\\u5834\\u5408\\u306f\\u3001\\u305d\\u306e\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u306e\\u76ee\\u7684\\u306b\\u7570\\u8b70\\u3092\\u5531\\u3048\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u5b9f\\u88c5\\u3092\\u76f4\\u63a5\\u547c\\u3073\\u51fa\\u3059\\u306e\\u3082\\u4e00\\u3064\\u306e\\u624b\\u3067\\u3059\\u3002</p> <p>\\u30b3\\u30fc\\u30c9\\u5185\\u3067\\u62bd\\u8c61\\u5316\\u3059\\u308b\\u3068\\u304d\\u306f\\u6ce8\\u610f\\u304c\\u5fc5\\u8981\\u3067\\u3059\\uff08\\u62bd\\u8c61\\u5316\\u306f\\u4f5c\\u6210\\u3059\\u308b\\u306e\\u3067\\u306f\\u306a\\u304f\\u3001\\u767a\\u898b\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\uff09\\u3002\\u5f8c\\u3067\\u5fc5\\u8981\\u306b\\u306a\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u3082\\u306e\\u3092\\u8003\\u616e\\u3057\\u3001\\u5b8c\\u74a7\\u306a\\u62bd\\u8c61\\u5316\\u30ec\\u30d9\\u30eb\\u3092\\u63a8\\u6e2c\\u3057\\u3066\\u3001\\u79c1\\u305f\\u3061\\u30bd\\u30d5\\u30c8\\u30a6\\u30a7\\u30a2\\u958b\\u767a\\u8005\\u306f\\u30b3\\u30fc\\u30c9\\u3092\\u30aa\\u30fc\\u30d0\\u30fc\\u30a8\\u30f3\\u30b8\\u30cb\\u30a2\\u30ea\\u30f3\\u30b0\\u3059\\u308b\\u3053\\u3068\\u304c\\u3088\\u304f\\u3042\\u308a\\u307e\\u3059\\u3002\\u307b\\u3068\\u3093\\u3069\\u306e\\u5834\\u5408\\u3001\\u30b3\\u30fc\\u30c9\\u304c\\u4e0d\\u5fc5\\u8981\\u306a\\u62bd\\u8c61\\u5316\\u3067\\u6c5a\\u67d3\\u3055\\u308c\\u3001\\u8aad\\u307f\\u306b\\u304f\\u304f\\u306a\\u308b\\u305f\\u3081\\u3001\\u3053\\u306e\\u30d7\\u30ed\\u30bb\\u30b9\\u306f\\u907f\\u3051\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002</p> <p>\\u30ed\\u30d6\\u30fb\\u30d1\\u30a4\\u30af</p> <p>\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3067\\u30c7\\u30b6\\u30a4\\u30f3\\u3059\\u308b\\u306a\\u3002\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3092\\u898b\\u3064\\u3051\\u51fa\\u305b\\u3002</p> <p>\\u62bd\\u8c61\\u7684\\u306b\\u554f\\u984c\\u3092\\u89e3\\u6c7a\\u3057\\u3088\\u3046\\u3068\\u3059\\u308b\\u306e\\u3067\\u306f\\u306a\\u304f\\u3001\\u4eca\\u89e3\\u6c7a\\u3059\\u3079\\u304d\\u3053\\u3068\\u3092\\u89e3\\u6c7a\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002\\u6700\\u5f8c\\u306b\\u91cd\\u8981\\u306a\\u3053\\u3068\\u3067\\u3059\\u304c\\u3001\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u306b\\u3088\\u3063\\u3066\\u30b3\\u30fc\\u30c9\\u304c\\u3069\\u306e\\u3088\\u3046\\u306b\\u6539\\u5584\\u3055\\u308c\\u308b\\u304b\\u304c\\u4e0d\\u660e\\u77ad\\u306a\\u5834\\u5408\\u306f\\u3001\\u30b3\\u30fc\\u30c9\\u3092\\u7c21\\u7d20\\u5316\\u3059\\u308b\\u305f\\u3081\\u306b\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3092\\u524a\\u9664\\u3059\\u308b\\u3053\\u3068\\u3092\\u691c\\u8a0e\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u3067\\u3057\\u3087\\u3046\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#6\",\"title\":\"\\u751f\\u7523\\u8005\\u5074\\u306e\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9 (#6)\",\"text\":\"\\u8981\\u7d04 <p>\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3092\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u5074\\u3067\\u4fdd\\u6301\\u3059\\u308b\\u3053\\u3068\\u3067\\u4e0d\\u5fc5\\u8981\\u306a\\u62bd\\u8c61\\u5316\\u3092\\u56de\\u907f\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>Go\\u8a00\\u8a9e\\u3067\\u306f\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u304c\\u6697\\u9ed9\\u7684\\u306b\\u6e80\\u305f\\u3055\\u308c\\u307e\\u3059\\u3002\\u3053\\u308c\\u306f\\u3001\\u660e\\u793a\\u7684\\u306a\\u5b9f\\u88c5\\u3092\\u6301\\u3064\\u8a00\\u8a9e\\u3068\\u6bd4\\u8f03\\u3057\\u3066\\u5927\\u304d\\u306a\\u5909\\u5316\\u3092\\u3082\\u305f\\u3089\\u3059\\u50be\\u5411\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u307b\\u3068\\u3093\\u3069\\u306e\\u5834\\u5408\\u3001\\u5f93\\u3046\\u3079\\u304d\\u30a2\\u30d7\\u30ed\\u30fc\\u30c1\\u306f\\u524d\\u306e\\u30bb\\u30af\\u30b7\\u30e7\\u30f3\\u3067\\u8aac\\u660e\\u3057\\u305f\\u3082\\u306e\\u2015\\u2015\\u62bd\\u8c61\\u5316\\u306f\\u4f5c\\u6210\\u3059\\u308b\\u306e\\u3067\\u306f\\u306a\\u304f\\u3001\\u767a\\u898b\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u2015\\u2015\\u306b\\u4f3c\\u3066\\u3044\\u307e\\u3059\\u3002\\u3053\\u308c\\u306f\\u3001\\u3059\\u3079\\u3066\\u306e\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u306b\\u5bfe\\u3057\\u3066\\u7279\\u5b9a\\u306e\\u62bd\\u8c61\\u5316\\u3092\\u5f37\\u5236\\u3059\\u308b\\u306e\\u306f\\u751f\\u7523\\u8005\\u306e\\u5f79\\u5272\\u3067\\u306f\\u306a\\u3044\\u3053\\u3068\\u3092\\u610f\\u5473\\u3057\\u307e\\u3059\\u3002\\u4ee3\\u308f\\u308a\\u306b\\u3001\\u4f55\\u3089\\u304b\\u306e\\u5f62\\u5f0f\\u306e\\u62bd\\u8c61\\u5316\\u304c\\u5fc5\\u8981\\u304b\\u3069\\u3046\\u304b\\u3092\\u5224\\u65ad\\u3057\\u3001\\u305d\\u306e\\u30cb\\u30fc\\u30ba\\u306b\\u6700\\u9069\\u306a\\u62bd\\u8c61\\u5316\\u30ec\\u30d9\\u30eb\\u3092\\u6c7a\\u5b9a\\u3059\\u308b\\u306e\\u306f\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u306e\\u8cac\\u4efb\\u3067\\u3059\\u3002</p> <p>\\u307b\\u3068\\u3093\\u3069\\u306e\\u5834\\u5408\\u3001\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u306f\\u6d88\\u8cbb\\u8005\\u5074\\u306b\\u5b58\\u5728\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u7279\\u5b9a\\u306e\\u72b6\\u6cc1\\uff08\\u305f\\u3068\\u3048\\u3070\\u3001\\u62bd\\u8c61\\u5316\\u304c\\u6d88\\u8cbb\\u8005\\u306b\\u3068\\u3063\\u3066\\u5f79\\u7acb\\u3064\\u3053\\u3068\\u304c\\u308f\\u304b\\u3063\\u3066\\u3044\\u308b\\u2015\\u2015\\u4e88\\u6e2c\\u306f\\u3057\\u3066\\u3044\\u306a\\u3044\\u2015\\u2015\\u5834\\u5408\\uff09\\u3067\\u306f\\u3001\\u305d\\u308c\\u3092\\u751f\\u7523\\u8005\\u5074\\u3067\\u4f7f\\u7528\\u3057\\u305f\\u3044\\u5834\\u5408\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305d\\u3046\\u3057\\u305f\\u5834\\u5408\\u3001\\u53ef\\u80fd\\u306a\\u9650\\u308a\\u6700\\u5c0f\\u9650\\u306b\\u6291\\u3048\\u3001\\u518d\\u5229\\u7528\\u53ef\\u80fd\\u6027\\u3092\\u9ad8\\u3081\\u3001\\u3088\\u308a\\u7c21\\u5358\\u306b\\u69cb\\u6210\\u3067\\u304d\\u308b\\u3088\\u3046\\u306b\\u52aa\\u3081\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#7\",\"title\":\"\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3092\\u8fd4\\u3059 (#7)\",\"text\":\"\\u8981\\u7d04 <p>\\u67d4\\u8edf\\u6027\\u306b\\u554f\\u984c\\u304c\\u306a\\u3044\\u3088\\u3046\\u306b\\u3059\\u308b\\u305f\\u3081\\u306b\\u3001\\u95a2\\u6570\\u306f\\u307b\\u3068\\u3093\\u3069\\u306e\\u5834\\u5408\\u3001\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3067\\u306f\\u306a\\u304f\\u5177\\u4f53\\u7684\\u200b\\u200b\\u306a\\u5b9f\\u88c5\\u3092\\u8fd4\\u3059\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u9006\\u306b\\u3001\\u95a2\\u6570\\u306f\\u53ef\\u80fd\\u306a\\u9650\\u308a\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3092\\u53d7\\u3051\\u5165\\u308c\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p>\\u307b\\u3068\\u3093\\u3069\\u306e\\u5834\\u5408\\u3001\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3067\\u306f\\u306a\\u304f\\u5177\\u4f53\\u7684\\u306a\\u5b9f\\u88c5\\u3092\\u8fd4\\u3059\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305d\\u3046\\u3067\\u306a\\u3044\\u3068\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306e\\u4f9d\\u5b58\\u95a2\\u4fc2\\u306b\\u3088\\u308a\\u8a2d\\u8a08\\u304c\\u3044\\u3063\\u305d\\u3046\\u8907\\u96d1\\u306b\\u306a\\u308a\\u3001\\u3059\\u3079\\u3066\\u306e\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u304c\\u540c\\u3058\\u62bd\\u8c61\\u5316\\u306b\\u4f9d\\u5b58\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u305f\\u3081\\u3001\\u67d4\\u8edf\\u6027\\u306b\\u6b20\\u3051\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u7d50\\u8ad6\\u306f\\u524d\\u306e\\u30bb\\u30af\\u30b7\\u30e7\\u30f3\\u3068\\u4f3c\\u3066\\u3044\\u307e\\u3059\\u3002\\u62bd\\u8c61\\u5316\\u304c\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u306b\\u3068\\u3063\\u3066\\u5f79\\u7acb\\u3064\\u3053\\u3068\\u304c\\uff08\\u4e88\\u6e2c\\u3055\\u308c\\u308b\\u3067\\u306f\\u306a\\u304f\\uff09\\u308f\\u304b\\u3063\\u3066\\u3044\\u308b\\u5834\\u5408\\u306f\\u3001\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3092\\u8fd4\\u3059\\u3053\\u3068\\u3092\\u691c\\u8a0e\\u3057\\u3066\\u3082\\u3088\\u3044\\u3067\\u3057\\u3087\\u3046\\u3002\\u305d\\u308c\\u4ee5\\u5916\\u306e\\u5834\\u5408\\u306f\\u3001\\u62bd\\u8c61\\u5316\\u3092\\u5f37\\u5236\\u3059\\u3079\\u304d\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u305d\\u308c\\u3089\\u306f\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u306b\\u3088\\u3063\\u3066\\u767a\\u898b\\u3055\\u308c\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u4f55\\u3089\\u304b\\u306e\\u7406\\u7531\\u3067\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u304c\\u5b9f\\u88c5\\u3092\\u62bd\\u8c61\\u5316\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u5834\\u5408\\u3067\\u3082\\u3001\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u5074\\u3067\\u305d\\u308c\\u3092\\u884c\\u3046\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002</p>\"},{\"location\":\"ja/#any-8\",\"title\":\"<code>any</code> \\u306f\\u4f55\\u3082\\u8a00\\u308f\\u306a\\u3044 (#8)\",\"text\":\"\\u8981\\u7d04 <p><code>json.Marshal</code> \\u306a\\u3069\\u8003\\u3048\\u3046\\u308b\\u3059\\u3079\\u3066\\u306e\\u578b\\u3092\\u53d7\\u3051\\u5165\\u308c\\u308b\\u304b\\u8fd4\\u3059\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u5834\\u5408\\u306b\\u306e\\u307f <code>any</code> \\u3092\\u4f7f\\u7528\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u305d\\u308c\\u4ee5\\u5916\\u306e\\u5834\\u5408\\u3001<code>any</code> \\u306f\\u610f\\u5473\\u306e\\u3042\\u308b\\u60c5\\u5831\\u3092\\u63d0\\u4f9b\\u305b\\u305a\\u3001\\u547c\\u3073\\u51fa\\u3057\\u5143\\u304c\\u4efb\\u610f\\u306e\\u30c7\\u30fc\\u30bf\\u578b\\u306e\\u30e1\\u30bd\\u30c3\\u30c9\\u3092\\u547c\\u3073\\u51fa\\u3059\\u3053\\u3068\\u3092\\u8a31\\u53ef\\u3059\\u308b\\u305f\\u3081\\u3001\\u30b3\\u30f3\\u30d1\\u30a4\\u30eb\\u6642\\u306b\\u554f\\u984c\\u304c\\u767a\\u751f\\u3059\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p><code>any</code> \\u578b\\u306f\\u3001\\u8003\\u3048\\u3046\\u308b\\u3059\\u3079\\u3066\\u306e\\u578b\\u3092\\u53d7\\u3051\\u5165\\u308c\\u308b\\u304b\\u8fd4\\u3059\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u5834\\u5408\\uff08\\u305f\\u3068\\u3048\\u3070\\u3001\\u30de\\u30fc\\u30b7\\u30e3\\u30ea\\u30f3\\u30b0\\u3084\\u30d5\\u30a9\\u30fc\\u30de\\u30c3\\u30c8\\u306e\\u5834\\u5408\\uff09\\u306b\\u5f79\\u7acb\\u3061\\u307e\\u3059\\u3002\\u539f\\u5247\\u3068\\u3057\\u3066\\u30b3\\u30fc\\u30c9\\u3092\\u904e\\u5ea6\\u306b\\u4e00\\u822c\\u5316\\u3059\\u308b\\u3053\\u3068\\u306f\\u4f55\\u3068\\u3057\\u3066\\u3082\\u907f\\u3051\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002\\u30b3\\u30fc\\u30c9\\u306e\\u8868\\u73fe\\u529b\\u306a\\u3069\\u306e\\u4ed6\\u306e\\u5074\\u9762\\u304c\\u5411\\u4e0a\\u3059\\u308b\\u5834\\u5408\\u306f\\u3001\\u30b3\\u30fc\\u30c9\\u3092\\u5c11\\u3057\\u91cd\\u8907\\u3055\\u305b\\u305f\\u307b\\u3046\\u304c\\u826f\\u3044\\u3053\\u3068\\u3082\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#9\",\"title\":\"\\u30b8\\u30a7\\u30cd\\u30ea\\u30c3\\u30af\\u30b9\\u3092\\u3044\\u3064\\u4f7f\\u7528\\u3059\\u308b\\u3079\\u304d\\u304b\\u7406\\u89e3\\u3057\\u3066\\u3044\\u306a\\u3044 (#9)\",\"text\":\"\\u8981\\u7d04 <p>\\u30b8\\u30a7\\u30cd\\u30ea\\u30c3\\u30af\\u30b9\\u3068\\u578b\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u30fc\\u3092\\u5229\\u7528\\u3059\\u308b\\u3053\\u3068\\u3067\\u3001\\u8981\\u7d20\\u3084\\u52d5\\u4f5c\\u3092\\u9664\\u5916\\u3059\\u308b\\u305f\\u3081\\u306e\\u30dc\\u30a4\\u30e9\\u30fc\\u30d7\\u30ec\\u30fc\\u30c8\\u30b3\\u30fc\\u30c9\\u3092\\u907f\\u3051\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u578b\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u306f\\u6642\\u671f\\u5c1a\\u65e9\\u306b\\u4f7f\\u7528\\u305b\\u305a\\u3001\\u5177\\u4f53\\u7684\\u306a\\u5fc5\\u8981\\u6027\\u304c\\u308f\\u304b\\u3063\\u305f\\u5834\\u5408\\u306b\\u306e\\u307f\\u4f7f\\u7528\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u305d\\u3046\\u3067\\u306a\\u3051\\u308c\\u3070\\u3001\\u4e0d\\u5fc5\\u8981\\u306a\\u62bd\\u8c61\\u5316\\u3068\\u8907\\u96d1\\u3055\\u304c\\u751f\\u3058\\u307e\\u3059\\u3002</p> <p>\\u30bb\\u30af\\u30b7\\u30e7\\u30f3\\u5168\\u6587\\u306f\\u3053\\u3061\\u3089\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#10\",\"title\":\"\\u578b\\u306e\\u57cb\\u3081\\u8fbc\\u307f\\u3067\\u8d77\\u3053\\u308a\\u3046\\u308b\\u554f\\u984c\\u3092\\u628a\\u63e1\\u3057\\u3066\\u3044\\u306a\\u3044 (#10)\",\"text\":\"\\u8981\\u7d04 <p>\\u578b\\u57cb\\u3081\\u8fbc\\u307f\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u3001\\u30dc\\u30a4\\u30e9\\u30fc\\u30d7\\u30ec\\u30fc\\u30c8\\u30b3\\u30fc\\u30c9\\u3092\\u56de\\u907f\\u3059\\u308b\\u3053\\u3068\\u3082\\u3067\\u304d\\u307e\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u305d\\u3046\\u3059\\u308b\\u3053\\u3068\\u3067\\u3001\\u4e00\\u90e8\\u306e\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u3092\\u975e\\u8868\\u793a\\u306b\\u3057\\u3066\\u304a\\u304f\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u5834\\u5408\\u306b\\u554f\\u984c\\u304c\\u767a\\u751f\\u3057\\u306a\\u3044\\u3088\\u3046\\u306b\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u69cb\\u9020\\u4f53\\u3092\\u4f5c\\u6210\\u3059\\u308b\\u3068\\u304d\\u3001Go\\u8a00\\u8a9e\\u306f\\u578b\\u3092\\u57cb\\u3081\\u8fbc\\u3080\\u30aa\\u30d7\\u30b7\\u30e7\\u30f3\\u3092\\u63d0\\u4f9b\\u3057\\u307e\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u578b\\u57cb\\u3081\\u8fbc\\u307f\\u306e\\u610f\\u5473\\u3092\\u3059\\u3079\\u3066\\u7406\\u89e3\\u3057\\u3066\\u3044\\u306a\\u3044\\u3068\\u3001\\u4e88\\u60f3\\u5916\\u306e\\u52d5\\u4f5c\\u304c\\u767a\\u751f\\u3059\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3053\\u306e\\u30bb\\u30af\\u30b7\\u30e7\\u30f3\\u3067\\u306f\\u3001\\u578b\\u3092\\u57cb\\u3081\\u8fbc\\u3080\\u65b9\\u6cd5\\u3001\\u305d\\u308c\\u304c\\u3082\\u305f\\u3089\\u3059\\u3082\\u306e\\u3001\\u304a\\u3088\\u3073\\u8003\\u3048\\u3089\\u308c\\u308b\\u554f\\u984c\\u306b\\u3064\\u3044\\u3066\\u898b\\u3066\\u3044\\u304d\\u307e\\u3059\\u3002</p> <p>Go\\u8a00\\u8a9e\\u3067\\u306f\\u3001\\u540d\\u524d\\u306a\\u3057\\u3067\\u5ba3\\u8a00\\u3055\\u308c\\u305f\\u69cb\\u9020\\u4f53\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u306f\\u3001\\u57cb\\u3081\\u8fbc\\u307f\\u3068\\u547c\\u3070\\u308c\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001\\u6b21\\u306e\\u3088\\u3046\\u306a\\u3082\\u306e\\u3067\\u3059\\u3002</p> <pre><code>type Foo struct {\\n    Bar // \\u57cb\\u3081\\u8fbc\\u307f\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\n}\\n\\ntype Bar struct {\\n    Baz int\\n}\\n</code></pre> <p><code>Foo</code> \\u69cb\\u9020\\u4f53\\u3067\\u306f\\u3001<code>Bar</code> \\u578b\\u304c\\u95a2\\u9023\\u4ed8\\u3051\\u3089\\u308c\\u305f\\u540d\\u524d\\u306a\\u3057\\u3067\\u5ba3\\u8a00\\u3055\\u308c\\u3066\\u3044\\u307e\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u3053\\u308c\\u306f\\u57cb\\u3081\\u8fbc\\u307f\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u3067\\u3059\\u3002</p> <p>\\u57cb\\u3081\\u8fbc\\u307f\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u3067\\u3001\\u57cb\\u3081\\u8fbc\\u307f\\u578b\\u306e\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u3068\\u30e1\\u30bd\\u30c3\\u30c9\\u306f\\u6607\\u683c\\u3057\\u307e\\u3059\\u3002Bar \\u306b\\u306f Baz \\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u304c\\u542b\\u307e\\u308c\\u3066\\u3044\\u308b\\u305f\\u3081\\u3001\\u3053\\u306e\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u306f <code>Foo</code> \\u306b\\u6607\\u683c\\u3057\\u307e\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001Foo \\u304b\\u3089 Baz \\u3092\\u5229\\u7528\\u3067\\u304d\\u308b\\u3088\\u3046\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002</p> <p>\\u578b\\u306e\\u57cb\\u3081\\u8fbc\\u307f\\u306b\\u3064\\u3044\\u3066\\u4f55\\u304c\\u8a00\\u3048\\u308b\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002\\u307e\\u305a\\u3001\\u3053\\u308c\\u304c\\u5fc5\\u8981\\u306b\\u306a\\u308b\\u3053\\u3068\\u306f\\u307b\\u3068\\u3093\\u3069\\u306a\\u304f\\u3001\\u30e6\\u30fc\\u30b9\\u30b1\\u30fc\\u30b9\\u304c\\u4f55\\u3067\\u3042\\u308c\\u3001\\u304a\\u305d\\u3089\\u304f\\u578b\\u57cb\\u3081\\u8fbc\\u307f\\u306a\\u3057\\u3067\\u3082\\u540c\\u69d8\\u306b\\u89e3\\u6c7a\\u3067\\u304d\\u308b\\u3053\\u3068\\u3092\\u610f\\u5473\\u3057\\u307e\\u3059\\u3002\\u578b\\u306e\\u57cb\\u3081\\u8fbc\\u307f\\u306f\\u4e3b\\u306b\\u5229\\u4fbf\\u6027\\u3092\\u76ee\\u7684\\u3068\\u3057\\u3066\\u4f7f\\u7528\\u3055\\u308c\\u307e\\u3059\\u3002\\u307b\\u3068\\u3093\\u3069\\u306e\\u5834\\u5408\\u3001\\u305d\\u308c\\u306f\\u52d5\\u4f5c\\u3092\\u6607\\u683c\\u3059\\u308b\\u305f\\u3081\\u306b\\u4f7f\\u7528\\u3055\\u308c\\u307e\\u3059\\u3002</p> <p>\\u578b\\u57cb\\u3081\\u8fbc\\u307f\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u5834\\u5408\\u306f\\u3001\\u6b21\\u306e 2 \\u3064\\u306e\\u4e3b\\u306a\\u5236\\u7d04\\u3092\\u5ff5\\u982d\\u306b\\u7f6e\\u304f\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <ul> <li>\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u3078\\u306e\\u30a2\\u30af\\u30bb\\u30b9\\u3092\\u7c21\\u7d20\\u5316\\u3059\\u308b\\u305f\\u3081\\u306e\\u7cd6\\u8863\\u69cb\\u6587\\u3068\\u3057\\u3066\\u306e\\u307f\\u4f7f\\u7528\\u3057\\u306a\\u3044\\u3067\\u304f\\u3060\\u3055\\u3044\\uff08 <code>Foo.Bar.Baz()</code> \\u306e\\u4ee3\\u308f\\u308a\\u306b <code>Foo.Baz()</code> \\u306a\\u3069\\uff09\\u3002 \\u3053\\u308c\\u304c\\u552f\\u4e00\\u306e\\u6839\\u62e0\\u3067\\u3042\\u308b\\u5834\\u5408\\u306f\\u3001\\u5185\\u90e8\\u578b\\u3092\\u57cb\\u3081\\u8fbc\\u307e\\u305a\\u3001\\u4ee3\\u308f\\u308a\\u306b\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u3092\\u4f7f\\u3044\\u307e\\u3057\\u3087\\u3046\\u3002</li> <li>\\u5916\\u90e8\\u304b\\u3089\\u96a0\\u3057\\u305f\\u3044\\u30c7\\u30fc\\u30bf\\uff08\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\uff09\\u3084\\u52d5\\u4f5c\\uff08\\u30e1\\u30bd\\u30c3\\u30c9\\uff09\\u3092\\u6607\\u683c\\u3057\\u3066\\u306f\\u306a\\u308a\\u307e\\u305b\\u3093\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001\\u69cb\\u9020\\u4f53\\u306b\\u5bfe\\u3057\\u3066\\u30d7\\u30e9\\u30a4\\u30d9\\u30fc\\u30c8\\u306a\\u307e\\u307e\\u306b\\u3057\\u3066\\u304a\\u304f\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u30ed\\u30c3\\u30af\\u52d5\\u4f5c\\u306b\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u304c\\u30a2\\u30af\\u30bb\\u30b9\\u3067\\u304d\\u308b\\u3088\\u3046\\u306b\\u3059\\u308b\\u5834\\u5408\\u306a\\u3069\\u3067\\u3059\\u3002</li> </ul> <p>\\u3053\\u308c\\u3089\\u306e\\u5236\\u7d04\\u3092\\u5ff5\\u982d\\u306b\\u7f6e\\u3044\\u3066\\u578b\\u57cb\\u3081\\u8fbc\\u307f\\u3092\\u610f\\u8b58\\u7684\\u306b\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u3001\\u8ffd\\u52a0\\u306e\\u8ee2\\u9001\\u30e1\\u30bd\\u30c3\\u30c9\\u306b\\u3088\\u308b\\u30dc\\u30a4\\u30e9\\u30fc\\u30d7\\u30ec\\u30fc\\u30c8\\u30b3\\u30fc\\u30c9\\u3092\\u56de\\u907f\\u3059\\u308b\\u306e\\u306b\\u5f79\\u7acb\\u3061\\u307e\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u898b\\u305f\\u76ee\\u3060\\u3051\\u3092\\u76ee\\u7684\\u3068\\u3057\\u305f\\u308a\\u3001\\u96a0\\u3059\\u3079\\u304d\\u8981\\u7d20\\u3092\\u6607\\u683c\\u3057\\u305f\\u308a\\u3057\\u306a\\u3044\\u3088\\u3046\\u306b\\u6ce8\\u610f\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#functional-options-11\",\"title\":\"Functional Options \\u30d1\\u30bf\\u30fc\\u30f3\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3044\\u306a\\u3044 (#11)\",\"text\":\"\\u8981\\u7d04 <p>API \\u306b\\u9069\\u3057\\u305f\\u65b9\\u6cd5\\u3067\\u30aa\\u30d7\\u30b7\\u30e7\\u30f3\\u3092\\u4fbf\\u5229\\u306b\\u51e6\\u7406\\u3059\\u308b\\u306b\\u306f\\u3001Functional Options \\u30d1\\u30bf\\u30fc\\u30f3\\u3092\\u4f7f\\u7528\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>\\u3055\\u307e\\u3056\\u307e\\u306a\\u5b9f\\u88c5\\u65b9\\u6cd5\\u304c\\u5b58\\u5728\\u3057\\u3001\\u591a\\u5c11\\u306e\\u9055\\u3044\\u306f\\u3042\\u308a\\u307e\\u3059\\u304c\\u3001\\u4e3b\\u306a\\u8003\\u3048\\u65b9\\u306f\\u6b21\\u306e\\u3068\\u304a\\u308a\\u3067\\u3059\\u3002</p> <ul> <li>\\u672a\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u306e\\u69cb\\u9020\\u4f53\\u306f\\u30aa\\u30d7\\u30b7\\u30e7\\u30f3\\u8a2d\\u5b9a\\u3092\\u4fdd\\u6301\\u3057\\u307e\\u3059\\u3002</li> <li>\\u5404\\u30aa\\u30d7\\u30b7\\u30e7\\u30f3\\u306f\\u540c\\u3058\\u578b\\u3001<code>type Option func(options *options)</code> \\u30a8\\u30e9\\u30fc\\u3092\\u8fd4\\u3059\\u95a2\\u6570\\u3067\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001<code>WithPort</code> \\u306f\\u30dd\\u30fc\\u30c8\\u3092\\u8868\\u3059 <code>int</code> \\u5f15\\u6570\\u3092\\u53d7\\u3051\\u53d6\\u308a\\u3001<code>options</code> \\u69cb\\u9020\\u4f53\\u306e\\u66f4\\u65b0\\u65b9\\u6cd5\\u3092\\u8868\\u3059 <code>Option</code> \\u578b\\u3092\\u8fd4\\u3057\\u307e\\u3059\\u3002</li> </ul> <p></p> <pre><code>type options struct {\\n  port *int\\n}\\n\\ntype Option func(options *options) error\\n\\nfunc WithPort(port int) Option {\\n  return func(options *options) error {\\n    if port &lt; 0 {\\n    return errors.New(\\\"port should be positive\\\")\\n  }\\n  options.port = &amp;port\\n  return nil\\n  }\\n}\\n\\nfunc NewServer(addr string, opts ...Option) ( *http.Server, error) {\\n  var options options\\n  for _, opt := range opts { \\n    err := opt(&amp;options) \\n    if err != nil {\\n      return nil, err\\n    }\\n  }\\n\\n// \\u3053\\u306e\\u6bb5\\u968e\\u3067\\u3001options \\u69cb\\u9020\\u4f53\\u304c\\u69cb\\u7bc9\\u3055\\u308c\\u3001\\u69cb\\u6210\\u304c\\u542b\\u307e\\u308c\\u307e\\u3059\\u3002\\n// \\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u30dd\\u30fc\\u30c8\\u8a2d\\u5b9a\\u306b\\u95a2\\u9023\\u3059\\u308b\\u30ed\\u30b8\\u30c3\\u30af\\u3092\\u5b9f\\u88c5\\u3067\\u304d\\u307e\\u3059\\u3002\\n  var port int\\n  if options.port == nil {\\n    port = defaultHTTPPort\\n  } else {\\n      if *options.port == 0 {\\n      port = randomPort()\\n    } else {\\n      port = *options.port\\n    }\\n  }\\n\\n  // ...\\n}\\n</code></pre> <p>Functional Options \\u30d1\\u30bf\\u30fc\\u30f3\\u306f\\u3001\\u30aa\\u30d7\\u30b7\\u30e7\\u30f3\\u3092\\u51e6\\u7406\\u3059\\u308b\\u305f\\u3081\\u306e\\u624b\\u8efd\\u3067 API \\u30d5\\u30ec\\u30f3\\u30c9\\u30ea\\u30fc\\u306a\\u65b9\\u6cd5\\u3092\\u63d0\\u4f9b\\u3057\\u307e\\u3059\\u3002 Builder \\u30d1\\u30bf\\u30fc\\u30f3\\u306f\\u6709\\u52b9\\u306a\\u30aa\\u30d7\\u30b7\\u30e7\\u30f3\\u3067\\u3059\\u304c\\u3001\\u3044\\u304f\\u3064\\u304b\\u306e\\u5c0f\\u3055\\u306a\\u6b20\\u70b9\\uff08\\u7a7a\\u306e\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u69cb\\u6210\\u69cb\\u9020\\u4f53\\u3092\\u6e21\\u3055\\u306a\\u3051\\u308c\\u3070\\u306a\\u3089\\u306a\\u3044\\u3001\\u307e\\u305f\\u306f\\u30a8\\u30e9\\u30fc\\u3092\\u51e6\\u7406\\u3059\\u308b\\u65b9\\u6cd5\\u304c\\u3042\\u307e\\u308a\\u4fbf\\u5229\\u3067\\u306f\\u306a\\u3044\\uff09\\u304c\\u3042\\u308a\\u3001\\u3053\\u306e\\u7a2e\\u306e\\u554f\\u984c\\u306b\\u304a\\u3044\\u3066 Functional Options \\u30d1\\u30bf\\u30fc\\u30f3\\u304cGo\\u8a00\\u8a9e\\u306b\\u304a\\u3051\\u308b\\u6163\\u7528\\u7684\\u306a\\u5bfe\\u51e6\\u65b9\\u6cd5\\u306b\\u306a\\u308b\\u50be\\u5411\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#12\",\"title\":\"\\u8aa4\\u3063\\u305f\\u30d7\\u30ed\\u30b8\\u30a7\\u30af\\u30c8\\u69cb\\u6210 (\\u30d7\\u30ed\\u30b8\\u30a7\\u30af\\u30c8\\u69cb\\u9020\\u3068\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u69cb\\u6210) (#12)\",\"text\":\"<p>\\u5168\\u4f53\\u7684\\u306a\\u69cb\\u6210\\u306b\\u95a2\\u3057\\u3066\\u306f\\u3001\\u3055\\u307e\\u3056\\u307e\\u306a\\u8003\\u3048\\u65b9\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u30b3\\u30f3\\u30c6\\u30ad\\u30b9\\u30c8\\u3054\\u3068\\u306b\\u6574\\u7406\\u3059\\u3079\\u304d\\u304b\\u3001\\u305d\\u308c\\u3068\\u3082\\u30ec\\u30a4\\u30e4\\u30fc\\u3054\\u3068\\u306b\\u6574\\u7406\\u3059\\u3079\\u304d\\u304b\\u3001\\u305d\\u308c\\u306f\\u597d\\u307f\\u306b\\u3088\\u3063\\u3066\\u7570\\u306a\\u308a\\u307e\\u3059\\u3002\\u30b3\\u30f3\\u30c6\\u30ad\\u30b9\\u30c8\\uff08\\u9867\\u5ba2\\u30b3\\u30f3\\u30c6\\u30ad\\u30b9\\u30c8\\u3001\\u5951\\u7d04\\u30b3\\u30f3\\u30c6\\u30ad\\u30b9\\u30c8\\u306a\\u3069\\uff09\\u3054\\u3068\\u306b\\u30b3\\u30fc\\u30c9\\u3092\\u30b0\\u30eb\\u30fc\\u30d7\\u5316\\u3059\\u308b\\u3053\\u3068\\u3092\\u9078\\u3076\\u5834\\u5408\\u3082\\u3042\\u308c\\u3070\\u3001\\u516d\\u89d2\\u5f62\\u306e\\u30a2\\u30fc\\u30ad\\u30c6\\u30af\\u30c1\\u30e3\\u539f\\u5247\\u306b\\u5f93\\u3046\\u3053\\u3068\\u3068\\u3001\\u6280\\u8853\\u5c64\\u3054\\u3068\\u306b\\u30b0\\u30eb\\u30fc\\u30d7\\u5316\\u3059\\u308b\\u3053\\u3068\\u3092\\u9078\\u3076\\u5834\\u5408\\u3082\\u3042\\u308a\\u307e\\u3059\\u3002\\u79c1\\u305f\\u3061\\u304c\\u884c\\u3046\\u6c7a\\u5b9a\\u304c\\u4e00\\u8cab\\u3057\\u3066\\u3044\\u308b\\u9650\\u308a\\u3001\\u305d\\u308c\\u304c\\u30e6\\u30fc\\u30b9\\u30b1\\u30fc\\u30b9\\u306b\\u9069\\u5408\\u3059\\u308b\\u306a\\u3089\\u3001\\u305d\\u308c\\u304c\\u9593\\u9055\\u3063\\u3066\\u3044\\u308b\\u3053\\u3068\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002</p> <p>\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306b\\u95a2\\u3057\\u3066\\u306f\\u3001\\u5f93\\u3046\\u3079\\u304d\\u30d9\\u30b9\\u30c8\\u30d7\\u30e9\\u30af\\u30c6\\u30a3\\u30b9\\u304c\\u8907\\u6570\\u3042\\u308a\\u307e\\u3059\\u3002\\u307e\\u305a\\u3001\\u30d7\\u30ed\\u30b8\\u30a7\\u30af\\u30c8\\u304c\\u904e\\u5ea6\\u306b\\u8907\\u96d1\\u306b\\u306a\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u305f\\u3081\\u3001\\u6642\\u671f\\u5c1a\\u65e9\\u306a\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u5316\\u306f\\u907f\\u3051\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002\\u5834\\u5408\\u306b\\u3088\\u3063\\u3066\\u306f\\u3001\\u5b8c\\u74a7\\u306a\\u69cb\\u9020\\u3092\\u6700\\u521d\\u304b\\u3089\\u7121\\u7406\\u306b\\u4f5c\\u308d\\u3046\\u3068\\u3059\\u308b\\u3088\\u308a\\u3082\\u3001\\u5358\\u7d14\\u306a\\u69cb\\u6210\\u3092\\u4f7f\\u7528\\u3057\\u3001\\u305d\\u306e\\u5185\\u5bb9\\u3092\\u7406\\u89e3\\u3057\\u305f\\u4e0a\\u3067\\u30d7\\u30ed\\u30b8\\u30a7\\u30af\\u30c8\\u3092\\u767a\\u5c55\\u3055\\u305b\\u308b\\u307b\\u3046\\u304c\\u826f\\u3044\\u5834\\u5408\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002 \\u7c92\\u5ea6\\u3082\\u8003\\u616e\\u3059\\u3079\\u304d\\u91cd\\u8981\\u306a\\u70b9\\u3067\\u3059\\u3002 1 \\u3064\\u307e\\u305f\\u306f 2 \\u3064\\u306e\\u30d5\\u30a1\\u30a4\\u30eb\\u3060\\u3051\\u3092\\u542b\\u3080\\u6570\\u5341\\u306e\\u30ca\\u30ce\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u3092\\u4f5c\\u6210\\u3059\\u308b\\u3053\\u3068\\u306f\\u907f\\u3051\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002\\u305d\\u306e\\u5834\\u5408\\u3001\\u304a\\u305d\\u3089\\u304f\\u3053\\u308c\\u3089\\u306e\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u9593\\u306e\\u8ad6\\u7406\\u7684\\u306a\\u63a5\\u7d9a\\u306e\\u4e00\\u90e8\\u304c\\u629c\\u3051\\u843d\\u3061\\u3001\\u8aad\\u307f\\u624b\\u306b\\u3068\\u3063\\u3066\\u30d7\\u30ed\\u30b8\\u30a7\\u30af\\u30c8\\u304c\\u7406\\u89e3\\u3057\\u306b\\u304f\\u304f\\u306a\\u308b\\u304b\\u3089\\u3067\\u3059\\u3002\\u9006\\u306b\\u3001\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u540d\\u306e\\u610f\\u5473\\u3092\\u8584\\u3081\\u308b\\u3088\\u3046\\u306a\\u5de8\\u5927\\u306a\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u3082\\u907f\\u3051\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002</p> <p>\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306e\\u540d\\u524d\\u4ed8\\u3051\\u3082\\u6ce8\\u610f\\u3057\\u3066\\u884c\\u3046\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\uff08\\u958b\\u767a\\u8005\\u306a\\u3089\\uff09\\u8ab0\\u3082\\u304c\\u77e5\\u3063\\u3066\\u3044\\u308b\\u3088\\u3046\\u306b\\u3001\\u540d\\u524d\\u3092\\u4ed8\\u3051\\u308b\\u306e\\u306f\\u96e3\\u3057\\u3044\\u3067\\u3059\\u3002\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u304c Go \\u30d7\\u30ed\\u30b8\\u30a7\\u30af\\u30c8\\u3092\\u7406\\u89e3\\u3057\\u3084\\u3059\\u3044\\u3088\\u3046\\u306b\\u3001\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306b\\u542b\\u307e\\u308c\\u308b\\u3082\\u306e\\u3067\\u306f\\u306a\\u304f\\u3001\\u63d0\\u4f9b\\u3059\\u308b\\u3082\\u306e\\u306b\\u57fa\\u3065\\u3044\\u3066\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306b\\u540d\\u524d\\u3092\\u4ed8\\u3051\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u307e\\u305f\\u3001\\u30cd\\u30fc\\u30df\\u30f3\\u30b0\\u306b\\u306f\\u610f\\u5473\\u306e\\u3042\\u308b\\u3082\\u306e\\u3092\\u4ed8\\u3051\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u540d\\u306f\\u77ed\\u304f\\u3001\\u7c21\\u6f54\\u3067\\u3001\\u8868\\u73fe\\u529b\\u8c4a\\u304b\\u3067\\u3001\\u6163\\u4f8b\\u306b\\u3088\\u308a\\u5358\\u4e00\\u306e\\u5c0f\\u6587\\u5b57\\u306b\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p>\\u4f55\\u3092\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3059\\u308b\\u304b\\u306b\\u3064\\u3044\\u3066\\u306e\\u30eb\\u30fc\\u30eb\\u306f\\u975e\\u5e38\\u306b\\u7c21\\u5358\\u3067\\u3059\\u3002\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u9593\\u306e\\u7d50\\u5408\\u3092\\u6e1b\\u3089\\u3057\\u3001\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3055\\u308c\\u308b\\u4e0d\\u8981\\u306a\\u8981\\u7d20\\u3092\\u975e\\u8868\\u793a\\u306b\\u3059\\u308b\\u305f\\u3081\\u306b\\u3001\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u3082\\u306e\\u3092\\u3067\\u304d\\u308b\\u9650\\u308a\\u6700\\u5c0f\\u9650\\u306b\\u6291\\u3048\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u8981\\u7d20\\u3092\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3059\\u308b\\u304b\\u3069\\u3046\\u304b\\u4e0d\\u660e\\u306a\\u5834\\u5408\\u306f\\u3001\\u30c7\\u30d5\\u30a9\\u30eb\\u30c8\\u3067\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3057\\u306a\\u3044\\u3088\\u3046\\u306b\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u5f8c\\u3067\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u3053\\u3068\\u304c\\u5224\\u660e\\u3057\\u305f\\u5834\\u5408\\u306f\\u3001\\u30b3\\u30fc\\u30c9\\u3092\\u8abf\\u6574\\u3067\\u304d\\u307e\\u3059\\u3002\\u307e\\u305f\\u3001\\u69cb\\u9020\\u4f53\\u3092 encoding/json \\u3067\\u30a2\\u30f3\\u30de\\u30fc\\u30b7\\u30e3\\u30ea\\u30f3\\u30b0\\u3067\\u304d\\u308b\\u3088\\u3046\\u306b\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u3092\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3059\\u308b\\u306a\\u3069\\u3001\\u3044\\u304f\\u3064\\u304b\\u306e\\u4f8b\\u5916\\u306b\\u3082\\u7559\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u30d7\\u30ed\\u30b8\\u30a7\\u30af\\u30c8\\u3092\\u69cb\\u6210\\u3059\\u308b\\u306e\\u306f\\u7c21\\u5358\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u304c\\u3001\\u3053\\u308c\\u3089\\u306e\\u30eb\\u30fc\\u30eb\\u306b\\u5f93\\u3046\\u3053\\u3068\\u3067\\u7dad\\u6301\\u304c\\u5bb9\\u6613\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u4fdd\\u5b88\\u6027\\u3092\\u5bb9\\u6613\\u306b\\u3059\\u308b\\u305f\\u3081\\u306b\\u306f\\u4e00\\u8cab\\u6027\\u3082\\u91cd\\u8981\\u3067\\u3042\\u308b\\u3053\\u3068\\u306b\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u30b3\\u30fc\\u30c9\\u30d9\\u30fc\\u30b9\\u5185\\u3067\\u53ef\\u80fd\\u306a\\u9650\\u308a\\u4e00\\u8cab\\u6027\\u3092\\u4fdd\\u3064\\u3088\\u3046\\u306b\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> \\u88dc\\u8db3 <p>Go \\u30c1\\u30fc\\u30e0\\u306f Go \\u30d7\\u30ed\\u30b8\\u30a7\\u30af\\u30c8\\u306e\\u7d44\\u7e54\\u5316/\\u69cb\\u9020\\u5316\\u306b\\u95a2\\u3059\\u308b\\u516c\\u5f0f\\u30ac\\u30a4\\u30c9\\u30e9\\u30a4\\u30f3\\u3092 2023 \\u5e74\\u306b\\u767a\\u884c\\u3057\\u307e\\u3057\\u305f\\uff1a go.dev/doc/modules/layout</p>\"},{\"location\":\"ja/#13\",\"title\":\"\\u30e6\\u30fc\\u30c6\\u30a3\\u30ea\\u30c6\\u30a3\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306e\\u4f5c\\u6210 (#13)\",\"text\":\"\\u8981\\u7d04 <p>\\u540d\\u524d\\u4ed8\\u3051\\u306f\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u8a2d\\u8a08\\u306e\\u91cd\\u8981\\u306a\\u90e8\\u5206\\u3067\\u3059\\u3002<code>common</code> \\u3001<code>util</code> \\u3001<code>shared</code> \\u306e\\u3088\\u3046\\u306a\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u3092\\u4f5c\\u6210\\u3057\\u3066\\u3082\\u3001\\u8aad\\u307f\\u624b\\u306b\\u305d\\u308c\\u307b\\u3069\\u306e\\u4fa1\\u5024\\u3092\\u3082\\u305f\\u3089\\u3057\\u307e\\u305b\\u3093\\u3002\\u3053\\u306e\\u3088\\u3046\\u306a\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u3092\\u610f\\u5473\\u306e\\u3042\\u308b\\u5177\\u4f53\\u7684\\u306a\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u540d\\u306b\\u30ea\\u30d5\\u30a1\\u30af\\u30bf\\u30ea\\u30f3\\u30b0\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>\\u307e\\u305f\\u3001\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306b\\u542b\\u307e\\u308c\\u308b\\u3082\\u306e\\u3067\\u306f\\u306a\\u304f\\u3001\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u304c\\u63d0\\u4f9b\\u3059\\u308b\\u3082\\u306e\\u306b\\u57fa\\u3065\\u3044\\u3066\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306b\\u540d\\u524d\\u3092\\u4ed8\\u3051\\u308b\\u3068\\u3001\\u305d\\u306e\\u8868\\u73fe\\u529b\\u3092\\u9ad8\\u3081\\u308b\\u52b9\\u7387\\u7684\\u306a\\u65b9\\u6cd5\\u306b\\u306a\\u308b\\u3053\\u3068\\u306b\\u3082\\u7559\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#14\",\"title\":\"\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u540d\\u306e\\u885d\\u7a81\\u3092\\u7121\\u8996\\u3059\\u308b (#14)\",\"text\":\"\\u8981\\u7d04 <p>\\u6df7\\u4e71\\u3001\\u3055\\u3089\\u306b\\u306f\\u30d0\\u30b0\\u306b\\u3064\\u306a\\u304c\\u308a\\u304b\\u306d\\u306a\\u3044\\u3001\\u5909\\u6570\\u3068\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u9593\\u306e\\u540d\\u524d\\u306e\\u885d\\u7a81\\u3092\\u56de\\u907f\\u3059\\u308b\\u305f\\u3081\\u306b\\u3001\\u305d\\u308c\\u305e\\u308c\\u306b\\u4e00\\u610f\\u306e\\u540d\\u524d\\u3092\\u4f7f\\u7528\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002\\u3053\\u308c\\u304c\\u4e0d\\u53ef\\u80fd\\u306a\\u5834\\u5408\\u306f\\u3001\\u30a4\\u30f3\\u30dd\\u30fc\\u30c8\\u30a8\\u30a4\\u30ea\\u30a2\\u30b9\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u4fee\\u98fe\\u5b50\\u3092\\u5909\\u66f4\\u3057\\u3066\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u540d\\u3068\\u5909\\u6570\\u540d\\u3092\\u533a\\u5225\\u3059\\u308b\\u304b\\u3001\\u3088\\u308a\\u826f\\u3044\\u540d\\u524d\\u3092\\u8003\\u3048\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306e\\u885d\\u7a81\\u306f\\u3001\\u5909\\u6570\\u540d\\u304c\\u65e2\\u5b58\\u306e\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u540d\\u3068\\u885d\\u7a81\\u3059\\u308b\\u5834\\u5408\\u306b\\u767a\\u751f\\u3057\\u3001\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306e\\u518d\\u5229\\u7528\\u304c\\u59a8\\u3052\\u3089\\u308c\\u307e\\u3059\\u3002\\u66d6\\u6627\\u3055\\u3092\\u907f\\u3051\\u308b\\u305f\\u3081\\u306b\\u3001\\u5909\\u6570\\u540d\\u306e\\u885d\\u7a81\\u3092\\u9632\\u3050\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u885d\\u7a81\\u304c\\u767a\\u751f\\u3057\\u305f\\u5834\\u5408\\u306f\\u3001\\u5225\\u306e\\u610f\\u5473\\u306e\\u3042\\u308b\\u540d\\u524d\\u3092\\u898b\\u3064\\u3051\\u308b\\u304b\\u3001\\u30a4\\u30f3\\u30dd\\u30fc\\u30c8\\u30a8\\u30a4\\u30ea\\u30a2\\u30b9\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p>\"},{\"location\":\"ja/#15\",\"title\":\"\\u30b3\\u30fc\\u30c9\\u306e\\u6587\\u7ae0\\u5316\\u304c\\u884c\\u308f\\u308c\\u3066\\u3044\\u306a\\u3044 (#15)\",\"text\":\"\\u8981\\u7d04 <p>\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u3068\\u30e1\\u30f3\\u30c6\\u30ca\\u304c\\u30b3\\u30fc\\u30c9\\u306e\\u610f\\u56f3\\u3092\\u7406\\u89e3\\u3067\\u304d\\u308b\\u3088\\u3046\\u306b\\u3001\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3055\\u308c\\u305f\\u8981\\u7d20\\u3092\\u6587\\u7ae0\\u5316\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>\\u6587\\u7ae0\\u5316\\u306f\\u30b3\\u30fc\\u30c7\\u30a3\\u30f3\\u30b0\\u306e\\u91cd\\u8981\\u306a\\u5074\\u9762\\u3067\\u3059\\u3002\\u3053\\u308c\\u306b\\u3088\\u308a\\u3001\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u304c API \\u3092\\u3088\\u308a\\u7c21\\u5358\\u306b\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u304c\\u3001\\u30d7\\u30ed\\u30b8\\u30a7\\u30af\\u30c8\\u306e\\u7dad\\u6301\\u306b\\u3082\\u5f79\\u7acb\\u3061\\u307e\\u3059\\u3002Go\\u8a00\\u8a9e\\u3067\\u306f\\u3001\\u30b3\\u30fc\\u30c9\\u3092\\u6163\\u7528\\u7684\\u306a\\u3082\\u306e\\u306b\\u3059\\u308b\\u305f\\u3081\\u306b\\u3001\\u3044\\u304f\\u3064\\u304b\\u306e\\u30eb\\u30fc\\u30eb\\u306b\\u5f93\\u3046\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p>\\u307e\\u305a\\u3001\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3055\\u308c\\u305f\\u3059\\u3079\\u3066\\u306e\\u8981\\u7d20\\u3092\\u6587\\u7ae0\\u5316\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u69cb\\u9020\\u3001\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3001\\u95a2\\u6570\\u306a\\u3069\\u3001\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3059\\u308b\\u5834\\u5408\\u306f\\u6587\\u7ae0\\u5316\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u6163\\u4f8b\\u3068\\u3057\\u3066\\u3001\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3055\\u308c\\u305f\\u8981\\u7d20\\u306e\\u540d\\u524d\\u304b\\u3089\\u59cb\\u307e\\u308b\\u30b3\\u30e1\\u30f3\\u30c8\\u3092\\u8ffd\\u52a0\\u3057\\u307e\\u3059\\u3002</p> <p>\\u6163\\u4f8b\\u3068\\u3057\\u3066\\u3001\\u5404\\u30b3\\u30e1\\u30f3\\u30c8\\u306f\\u53e5\\u8aad\\u70b9\\u3067\\u7d42\\u308f\\u308b\\u5b8c\\u5168\\u306a\\u6587\\u3067\\u3042\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u307e\\u305f\\u3001\\u95a2\\u6570\\uff08\\u307e\\u305f\\u306f\\u30e1\\u30bd\\u30c3\\u30c9\\uff09\\u3092\\u6587\\u7ae0\\u5316\\u3059\\u308b\\u3068\\u304d\\u306f\\u3001\\u95a2\\u6570\\u304c\\u3069\\u306e\\u3088\\u3046\\u306b\\u5b9f\\u884c\\u3059\\u308b\\u304b\\u3067\\u306f\\u306a\\u304f\\u3001\\u305d\\u306e\\u95a2\\u6570\\u304c\\u4f55\\u3092\\u5b9f\\u884c\\u3059\\u308b\\u3064\\u3082\\u308a\\u3067\\u3042\\u308b\\u304b\\u3092\\u5f37\\u8abf\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u3053\\u3068\\u306b\\u3082\\u7559\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u3053\\u308c\\u306f\\u30c9\\u30ad\\u30e5\\u30e1\\u30f3\\u30c8\\u3067\\u306f\\u306a\\u304f\\u3001\\u95a2\\u6570\\u3068\\u30b3\\u30e1\\u30f3\\u30c8\\u306b\\u3064\\u3044\\u3066\\u3067\\u3059\\u3002\\u30c9\\u30ad\\u30e5\\u30e1\\u30f3\\u30c8\\u306f\\u7406\\u60f3\\u7684\\u306b\\u306f\\u3001\\u5229\\u7528\\u8005\\u304c\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3055\\u308c\\u305f\\u8981\\u7d20\\u306e\\u4f7f\\u7528\\u65b9\\u6cd5\\u3092\\u7406\\u89e3\\u3059\\u308b\\u305f\\u3081\\u306b\\u30b3\\u30fc\\u30c9\\u3092\\u898b\\u308b\\u5fc5\\u8981\\u304c\\u306a\\u3044\\u307b\\u3069\\u5341\\u5206\\u306a\\u60c5\\u5831\\u3092\\u63d0\\u4f9b\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p>\\u5909\\u6570\\u307e\\u305f\\u306f\\u5b9a\\u6570\\u3092\\u6587\\u7ae0\\u5316\\u3059\\u308b\\u5834\\u5408\\u3001\\u305d\\u306e\\u76ee\\u7684\\u3068\\u5185\\u5bb9\\u3068\\u3044\\u3046 2 \\u3064\\u306e\\u5074\\u9762\\u3092\\u4f1d\\u3048\\u308b\\u3053\\u3068\\u304c\\u91cd\\u8981\\u304b\\u3082\\u3057\\u308c\\u307e\\u305b\\u3093\\u3002\\u524d\\u8005\\u306f\\u3001\\u5916\\u90e8\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u306b\\u3068\\u3063\\u3066\\u5f79\\u7acb\\u3064\\u3088\\u3046\\u306b\\u3001\\u30b3\\u30fc\\u30c9\\u30c9\\u30ad\\u30e5\\u30e1\\u30f3\\u30c8\\u3068\\u3057\\u3066\\u5b58\\u5728\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u5f8c\\u8005\\u306f\\u5fc5\\u305a\\u3057\\u3082\\u516c\\u958b\\u3055\\u308c\\u308b\\u3079\\u304d\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002</p> <p>\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u3068\\u30e1\\u30f3\\u30c6\\u30ca\\u304c\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306e\\u76ee\\u7684\\u3092\\u7406\\u89e3\\u3067\\u304d\\u308b\\u3088\\u3046\\u306b\\u3001\\u5404\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u3092\\u30c9\\u30ad\\u30e5\\u30e1\\u30f3\\u30c8\\u3059\\u308b\\u5fc5\\u8981\\u3082\\u3042\\u308a\\u307e\\u3059\\u3002\\u6163\\u4f8b\\u3068\\u3057\\u3066\\u3001\\u30b3\\u30e1\\u30f3\\u30c8\\u306f <code>//Package</code> \\u3067\\u59cb\\u307e\\u308a\\u3001\\u305d\\u306e\\u5f8c\\u306b\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u540d\\u304c\\u7d9a\\u304d\\u307e\\u3059\\u3002\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u30b3\\u30e1\\u30f3\\u30c8\\u306e\\u6700\\u521d\\u306e\\u884c\\u306f\\u3001\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306b\\u8868\\u793a\\u3055\\u308c\\u308b\\u305f\\u3081\\u7c21\\u6f54\\u306b\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305d\\u3057\\u3066\\u3001\\u6b21\\u306e\\u884c\\u306b\\u5fc5\\u8981\\u306a\\u60c5\\u5831\\u3092\\u3059\\u3079\\u3066\\u5165\\u529b\\u3057\\u307e\\u3059\\u3002</p> <p>\\u30b3\\u30fc\\u30c9\\u3092\\u6587\\u7ae0\\u5316\\u3059\\u308b\\u3053\\u3068\\u304c\\u5236\\u7d04\\u306b\\u306a\\u308b\\u3079\\u304d\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u3084\\u30e1\\u30f3\\u30c6\\u30ca\\u304c\\u30b3\\u30fc\\u30c9\\u306e\\u610f\\u56f3\\u3092\\u7406\\u89e3\\u3059\\u308b\\u306e\\u306b\\u5f79\\u7acb\\u3064\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p>\"},{\"location\":\"ja/#16\",\"title\":\"\\u30ea\\u30f3\\u30bf\\u30fc\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u306a\\u3044 (#16)\",\"text\":\"\\u8981\\u7d04 <p>\\u30b3\\u30fc\\u30c9\\u306e\\u54c1\\u8cea\\u3068\\u4e00\\u8cab\\u6027\\u3092\\u5411\\u4e0a\\u3055\\u305b\\u308b\\u306b\\u306f\\u3001\\u30ea\\u30f3\\u30bf\\u30fc\\u3068\\u30d5\\u30a9\\u30fc\\u30de\\u30c3\\u30bf\\u30fc\\u3092\\u4f7f\\u7528\\u3057\\u307e\\u3057\\u3087\\u3046</p> <p>\\u30ea\\u30f3\\u30bf\\u30fc\\u306f\\u3001\\u30b3\\u30fc\\u30c9\\u3092\\u5206\\u6790\\u3057\\u3066\\u30a8\\u30e9\\u30fc\\u3092\\u691c\\u51fa\\u3059\\u308b\\u81ea\\u52d5\\u30c4\\u30fc\\u30eb\\u3067\\u3059\\u3002\\u3053\\u306e\\u30bb\\u30af\\u30b7\\u30e7\\u30f3\\u306e\\u76ee\\u7684\\u306f\\u3001\\u65e2\\u5b58\\u306e\\u30ea\\u30f3\\u30bf\\u30fc\\u306e\\u5b8c\\u5168\\u306a\\u30ea\\u30b9\\u30c8\\u3092\\u63d0\\u4f9b\\u3059\\u308b\\u3053\\u3068\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u305d\\u3046\\u3057\\u305f\\u5834\\u5408\\u3001\\u3059\\u3050\\u306b\\u4f7f\\u3044\\u7269\\u306b\\u306a\\u3089\\u306a\\u304f\\u306a\\u3063\\u3066\\u3057\\u307e\\u3046\\u304b\\u3089\\u3067\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u307b\\u3068\\u3093\\u3069\\u306e Go \\u30d7\\u30ed\\u30b8\\u30a7\\u30af\\u30c8\\u306b\\u30ea\\u30f3\\u30bf\\u30fc\\u304c\\u4e0d\\u53ef\\u6b20\\u3067\\u3042\\u308b\\u3068\\u3044\\u3046\\u3053\\u3068\\u306f\\u7406\\u89e3\\u3057\\u3001\\u899a\\u3048\\u3066\\u304a\\u304d\\u307e\\u3057\\u3087\\u3046\\u3002</p> <ul> <li>https://golang.org/cmd/vet\\u2015\\u2015Go\\u8a00\\u8a9e\\u306e\\u6a19\\u6e96\\u30b3\\u30fc\\u30c9\\u30a2\\u30ca\\u30e9\\u30a4\\u30b6\\u30fc</li> <li>https://github.com/kisielk/errcheck\\u2015\\u2015\\u30a8\\u30e9\\u30fc\\u30c1\\u30a7\\u30c3\\u30ab\\u30fc</li> <li>https://github.com/fzipp/gocyclo\\u2015\\u2015\\u5faa\\u74b0\\u7684\\u8907\\u96d1\\u5ea6\\u30a2\\u30ca\\u30e9\\u30a4\\u30b6\\u30fc</li> <li>https://github.com/jgautheron/goconst\\u2015\\u2015\\u8907\\u6570\\u56de\\u4f7f\\u7528\\u6587\\u5b57\\u5217\\u30a2\\u30ca\\u30e9\\u30a4\\u30b6\\u30fc</li> </ul> <p>\\u30ea\\u30f3\\u30bf\\u30fc\\u306e\\u307b\\u304b\\u306b\\u3001\\u30b3\\u30fc\\u30c9\\u30b9\\u30bf\\u30a4\\u30eb\\u3092\\u4fee\\u6b63\\u3059\\u308b\\u305f\\u3081\\u306b\\u30b3\\u30fc\\u30c9\\u30d5\\u30a9\\u30fc\\u30de\\u30c3\\u30bf\\u30fc\\u3082\\u4f7f\\u7528\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002\\u4ee5\\u4e0b\\u306b\\u3001\\u3044\\u304f\\u3064\\u304b\\u306e\\u30b3\\u30fc\\u30c9\\u30d5\\u30a9\\u30fc\\u30de\\u30c3\\u30bf\\u30fc\\u3092\\u793a\\u3057\\u307e\\u3059\\u3002</p> <ul> <li>https://golang.org/cmd/gofmt\\u2015\\u2015Go\\u8a00\\u8a9e\\u306e\\u6a19\\u6e96\\u30b3\\u30fc\\u30c9\\u30d5\\u30a9\\u30fc\\u30de\\u30c3\\u30bf\\u30fc</li> <li>https://godoc.org/golang.org/x/tools/cmd/goimports\\u2015\\u2015Go\\u8a00\\u8a9e\\u306e\\u6a19\\u6e96\\u30a4\\u30f3\\u30dd\\u30fc\\u30c8\\u30d5\\u30a9\\u30fc\\u30de\\u30c3\\u30bf\\u30fc</li> </ul> <p>\\u307b\\u304b\\u306b golangci-lint (https://github.com/golangci/golangci-lint) \\u3068\\u3044\\u3046\\u3082\\u306e\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3053\\u308c\\u306f\\u3001\\u591a\\u304f\\u306e\\u4fbf\\u5229\\u306a\\u30ea\\u30f3\\u30bf\\u30fc\\u3084\\u30d5\\u30a9\\u30fc\\u30de\\u30c3\\u30bf\\u30fc\\u306e\\u4e0a\\u306b\\u30d5\\u30a1\\u30b5\\u30fc\\u30c9\\u3092\\u63d0\\u4f9b\\u3059\\u308b\\u30ea\\u30f3\\u30c6\\u30a3\\u30f3\\u30b0\\u30c4\\u30fc\\u30eb\\u3067\\u3059\\u3002\\u307e\\u305f\\u3001\\u30ea\\u30f3\\u30bf\\u30fc\\u3092\\u4e26\\u5217\\u5b9f\\u884c\\u3057\\u3066\\u5206\\u6790\\u901f\\u5ea6\\u3092\\u5411\\u4e0a\\u3055\\u305b\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u3001\\u975e\\u5e38\\u306b\\u4fbf\\u5229\\u3067\\u3059\\u3002</p> <p>\\u30ea\\u30f3\\u30bf\\u30fc\\u3068\\u30d5\\u30a9\\u30fc\\u30de\\u30c3\\u30bf\\u30fc\\u306f\\u3001\\u30b3\\u30fc\\u30c9\\u30d9\\u30fc\\u30b9\\u306e\\u54c1\\u8cea\\u3068\\u4e00\\u8cab\\u6027\\u3092\\u5411\\u4e0a\\u3055\\u305b\\u308b\\u5f37\\u529b\\u306a\\u65b9\\u6cd5\\u3067\\u3059\\u3002\\u6642\\u9593\\u3092\\u304b\\u3051\\u3066\\u3069\\u308c\\u3092\\u4f7f\\u7528\\u3059\\u3079\\u304d\\u304b\\u3092\\u7406\\u89e3\\u3057\\u3001\\u305d\\u308c\\u3089\\u306e\\u5b9f\\u884c\\uff08 CI \\u3084 Git \\u30d7\\u30ea\\u30b3\\u30df\\u30c3\\u30c8\\u30d5\\u30c3\\u30af\\u306a\\u3069\\uff09\\u3092\\u81ea\\u52d5\\u5316\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p>\"},{\"location\":\"ja/#_2\",\"title\":\"\\u30c7\\u30fc\\u30bf\\u578b\",\"text\":\"\"},{\"location\":\"ja/#8-17\",\"title\":\"8 \\u9032\\u6570\\u30ea\\u30c6\\u30e9\\u30eb\\u3067\\u6df7\\u4e71\\u3092\\u62db\\u3044\\u3066\\u3057\\u307e\\u3046 (#17)\",\"text\":\"\\u8981\\u7d04 <p>\\u65e2\\u5b58\\u306e\\u30b3\\u30fc\\u30c9\\u3092\\u8aad\\u3080\\u3068\\u304d\\u306f\\u3001 <code>0</code> \\u3067\\u59cb\\u307e\\u308b\\u6574\\u6570\\u30ea\\u30c6\\u30e9\\u30eb\\u304c 8 \\u9032\\u6570\\u3067\\u3042\\u308b\\u3053\\u3068\\u306b\\u7559\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u307e\\u305f\\u3001\\u63a5\\u982d\\u8f9e <code>0o</code> \\u3092\\u4ed8\\u3051\\u308b\\u3053\\u3068\\u30678\\u9032\\u6570\\u3067\\u3042\\u308b\\u3053\\u3068\\u3092\\u660e\\u78ba\\u306b\\u3057\\u3001\\u8aad\\u307f\\u3084\\u3059\\u3055\\u3092\\u5411\\u4e0a\\u3055\\u305b\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>8 \\u9032\\u6570\\u306f 0 \\u3067\\u59cb\\u307e\\u308a\\u307e\\u3059\\uff08\\u305f\\u3068\\u3048\\u3070\\u3001<code>010</code> \\u306f 10 \\u9032\\u6570\\u306e 8 \\u306b\\u76f8\\u5f53\\u3057\\u307e\\u3059\\uff09\\u3002\\u53ef\\u8aad\\u6027\\u3092\\u5411\\u4e0a\\u3055\\u305b\\u3001\\u5c06\\u6765\\u306e\\u30b3\\u30fc\\u30c9\\u30ea\\u30fc\\u30c0\\u30fc\\u306e\\u6f5c\\u5728\\u7684\\u306a\\u9593\\u9055\\u3044\\u3092\\u56de\\u907f\\u3059\\u308b\\u306b\\u306f\\u3001 <code>0o</code> \\u63a5\\u982d\\u8f9e\\u3092\\u4f7f\\u7528\\u3057\\u3066 8 \\u9032\\u6570\\u3067\\u3042\\u308b\\u3053\\u3068\\u3092\\u660e\\u3089\\u304b\\u306b\\u3057\\u307e\\u3057\\u3087\\u3046\\uff08\\u4f8b: <code>0o10</code> \\uff09\\u3002</p> <p>\\u4ed6\\u306e\\u6574\\u6570\\u30ea\\u30c6\\u30e9\\u30eb\\u8868\\u73fe\\u306b\\u3082\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002 </p> <ul> <li>\\u30d0\\u30a4\\u30ca\\u30ea - \\u63a5\\u982d\\u8f9e <code>0b</code> \\u3042\\u308b\\u3044\\u306f <code>0B</code> \\u3092\\u4f7f\\u7528\\u3057\\u307e\\u3059\\uff08\\u305f\\u3068\\u3048\\u3070\\u3001 <code>0b</code> \\u306f 10 \\u9032\\u6570\\u306e 4 \\u306b\\u76f8\\u5f53\\u3057\\u307e\\u3059\\uff09</li> <li>16\\u9032\\u6570 - \\u63a5\\u982d\\u8f9e <code>0x</code> \\u3042\\u308b\\u3044\\u306f <code>0X</code> \\u3092\\u4f7f\\u7528\\u3057\\u307e\\u3059\\uff08\\u305f\\u3068\\u3048\\u3070\\u3001 <code>0xF</code> \\u306f 10 \\u9032\\u6570\\u306e 15 \\u306b\\u76f8\\u5f53\\u3057\\u307e\\u3059\\uff09\\u3002 </li> <li>\\u865a\\u6570 - \\u63a5\\u5c3e\\u8f9e <code>i</code> \\u3092\\u4f7f\\u7528\\u3057\\u307e\\u3059\\uff08\\u305f\\u3068\\u3048\\u3070\\u3001 <code>3i</code> \\uff09</li> </ul> <p>\\u8aad\\u307f\\u3084\\u3059\\u304f\\u3059\\u308b\\u305f\\u3081\\u306b\\u3001\\u533a\\u5207\\u308a\\u6587\\u5b57\\u3068\\u3057\\u3066\\u30a2\\u30f3\\u30c0\\u30fc\\u30b9\\u30b3\\u30a2\\uff08 _ \\uff09\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u3082\\u3067\\u304d\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001 10 \\u5104\\u306f <code>1_000_000_000</code> \\u306e\\u3088\\u3046\\u306b\\u66f8\\u304f\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002\\u30a2\\u30f3\\u30c0\\u30fc\\u30b9\\u30b3\\u30a2\\u306f <code>0b)00_00_01</code> \\u306e\\u3088\\u3046\\u306b\\u4ed6\\u306e\\u8868\\u73fe\\u3068\\u4f75\\u7528\\u3059\\u308b\\u3053\\u3068\\u3082\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#18\",\"title\":\"\\u6574\\u6570\\u30aa\\u30fc\\u30d0\\u30fc\\u30d5\\u30ed\\u30fc\\u3092\\u7121\\u8996\\u3057\\u3066\\u3044\\u308b (#18)\",\"text\":\"\\u8981\\u7d04 <p>Go\\u8a00\\u8a9e\\u3067\\u306f\\u6574\\u6570\\u306e\\u30aa\\u30fc\\u30d0\\u30fc\\u30d5\\u30ed\\u30fc\\u3068\\u30a2\\u30f3\\u30c0\\u30fc\\u30d5\\u30ed\\u30fc\\u304c\\u88cf\\u5074\\u3067\\u51e6\\u7406\\u3055\\u308c\\u308b\\u305f\\u3081\\u3001\\u305d\\u308c\\u3089\\u3092\\u30ad\\u30e3\\u30c3\\u30c1\\u3059\\u308b\\u72ec\\u81ea\\u306e\\u95a2\\u6570\\u3092\\u5b9f\\u88c5\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>Go\\u8a00\\u8a9e\\u3067\\u306f\\u3001\\u30b3\\u30f3\\u30d1\\u30a4\\u30eb\\u6642\\u306b\\u691c\\u51fa\\u3067\\u304d\\u308b\\u6574\\u6570\\u30aa\\u30fc\\u30d0\\u30fc\\u30d5\\u30ed\\u30fc\\u306b\\u3088\\u3063\\u3066\\u30b3\\u30f3\\u30d1\\u30a4\\u30eb\\u30a8\\u30e9\\u30fc\\u304c\\u751f\\u6210\\u3055\\u308c\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001\\u6b21\\u306e\\u3088\\u3046\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002</p> <pre><code>var counter int32 = math.MaxInt32 + 1\\n</code></pre> <pre><code>constant 2147483648 overflows int32\\n</code></pre> <p>\\u305f\\u3060\\u3057\\u3001\\u5b9f\\u884c\\u6642\\u306b\\u306f\\u3001\\u6574\\u6570\\u306e\\u30aa\\u30fc\\u30d0\\u30fc\\u30d5\\u30ed\\u30fc\\u307e\\u305f\\u306f\\u30a2\\u30f3\\u30c0\\u30fc\\u30d5\\u30ed\\u30fc\\u306f\\u767a\\u751f\\u3057\\u307e\\u305b\\u3093\\u3002\\u3053\\u308c\\u306b\\u3088\\u3063\\u3066\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u306e\\u30d1\\u30cb\\u30c3\\u30af\\u304c\\u767a\\u751f\\u3059\\u308b\\u3053\\u3068\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u3053\\u306e\\u52d5\\u4f5c\\u306f\\u3084\\u3063\\u304b\\u3044\\u306a\\u30d0\\u30b0\\uff08\\u305f\\u3068\\u3048\\u3070\\u3001\\u8ca0\\u306e\\u7d50\\u679c\\u306b\\u3064\\u306a\\u304c\\u308b\\u6574\\u6570\\u306e\\u5897\\u5206\\u3084\\u6b63\\u306e\\u6574\\u6570\\u306e\\u52a0\\u7b97\\u306a\\u3069\\uff09\\u306b\\u3064\\u306a\\u304c\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u305f\\u3081\\u3001\\u982d\\u306b\\u5165\\u308c\\u3066\\u304a\\u304f\\u3053\\u3068\\u304c\\u91cd\\u8981\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#19\",\"title\":\"\\u6d6e\\u52d5\\u5c0f\\u6570\\u70b9\\u3092\\u7406\\u89e3\\u3057\\u3066\\u3044\\u306a\\u3044 (#19)\",\"text\":\"\\u8981\\u7d04 <p>\\u7279\\u5b9a\\u306e\\u30c7\\u30eb\\u30bf\\u5185\\u3067\\u6d6e\\u52d5\\u5c0f\\u6570\\u70b9\\u6bd4\\u8f03\\u3092\\u884c\\u3046\\u3068\\u3001\\u30b3\\u30fc\\u30c9\\u306e\\u79fb\\u690d\\u6027\\u3092\\u78ba\\u4fdd\\u3067\\u304d\\u307e\\u3059\\u3002\\u52a0\\u7b97\\u307e\\u305f\\u306f\\u6e1b\\u7b97\\u3092\\u5b9f\\u884c\\u3059\\u308b\\u3068\\u304d\\u306f\\u3001\\u7cbe\\u5ea6\\u3092\\u5411\\u4e0a\\u3055\\u305b\\u308b\\u305f\\u3081\\u306b\\u3001\\u540c\\u7a0b\\u5ea6\\u306e\\u5927\\u304d\\u3055\\u306e\\u6f14\\u7b97\\u3092\\u30b0\\u30eb\\u30fc\\u30d7\\u5316\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u307e\\u305f\\u3001\\u4e57\\u7b97\\u3068\\u9664\\u7b97\\u306f\\u52a0\\u7b97\\u3068\\u6e1b\\u7b97\\u306e\\u524d\\u306b\\u5b9f\\u884c\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>Go\\u8a00\\u8a9e\\u306b\\u306f\\u3001\\uff08\\u865a\\u6570\\u3092\\u9664\\u3044\\u305f\\u5834\\u5408\\uff09 <code>float32</code> \\u3068 <code>float64</code> \\u3068\\u3044\\u3046 2 \\u3064\\u306e\\u6d6e\\u52d5\\u5c0f\\u6570\\u70b9\\u578b\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u6d6e\\u52d5\\u5c0f\\u6570\\u70b9\\u306e\\u6982\\u5ff5\\u306f\\u3001\\u5c0f\\u6570\\u5024\\u3092\\u8868\\u73fe\\u3067\\u304d\\u306a\\u3044\\u3068\\u3044\\u3046\\u6574\\u6570\\u306e\\u5927\\u304d\\u306a\\u554f\\u984c\\u3092\\u89e3\\u6c7a\\u3059\\u308b\\u305f\\u3081\\u306b\\u767a\\u660e\\u3055\\u308c\\u307e\\u3057\\u305f\\u3002\\u4e88\\u60f3\\u5916\\u306e\\u4e8b\\u614b\\u3092\\u907f\\u3051\\u308b\\u305f\\u3081\\u306b\\u3001\\u6d6e\\u52d5\\u5c0f\\u6570\\u70b9\\u6f14\\u7b97\\u306f\\u5b9f\\u969b\\u306e\\u6f14\\u7b97\\u306e\\u8fd1\\u4f3c\\u3067\\u3042\\u308b\\u3053\\u3068\\u3092\\u77e5\\u3063\\u3066\\u304a\\u304f\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002 </p> <p>\\u305d\\u306e\\u305f\\u3081\\u306b\\u3001\\u4e57\\u7b97\\u306e\\u4f8b\\u3092\\u898b\\u3066\\u307f\\u307e\\u3057\\u3087\\u3046\\u3002</p> <pre><code>var n float32 = 1.0001\\nfmt.Println(n * n)\\n</code></pre> <p>\\u3053\\u306e\\u30b3\\u30fc\\u30c9\\u306b\\u304a\\u3044\\u3066\\u306f 1.0001 * 1.0001 = 1.00020001 \\u3068\\u3044\\u3046\\u7d50\\u679c\\u304c\\u51fa\\u529b\\u3055\\u308c\\u308b\\u3053\\u3068\\u3092\\u671f\\u5f85\\u3059\\u308b\\u3068\\u601d\\u3044\\u307e\\u3059\\u3002\\u3057\\u304b\\u3057\\u306a\\u304c\\u3089\\u3001\\u307b\\u3068\\u3093\\u3069\\u306e x86 \\u30d7\\u30ed\\u30bb\\u30c3\\u30b5\\u3067\\u306f\\u3001\\u4ee3\\u308f\\u308a\\u306b 1.0002 \\u304c\\u51fa\\u529b\\u3055\\u308c\\u307e\\u3059\\u3002 </p> <p>Go\\u8a00\\u8a9e\\u306e <code>float32</code> \\u304a\\u3088\\u3073 <code>float64</code> \\u578b\\u306f\\u8fd1\\u4f3c\\u5024\\u3067\\u3042\\u308b\\u305f\\u3081\\u3001\\u3044\\u304f\\u3064\\u304b\\u306e\\u30eb\\u30fc\\u30eb\\u3092\\u5ff5\\u982d\\u306b\\u7f6e\\u304f\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <ul> <li>2 \\u3064\\u306e\\u6d6e\\u52d5\\u5c0f\\u6570\\u70b9\\u6570\\u3092\\u6bd4\\u8f03\\u3059\\u308b\\u5834\\u5408\\u306f\\u3001\\u305d\\u306e\\u5dee\\u304c\\u8a31\\u5bb9\\u7bc4\\u56f2\\u5185\\u3067\\u3042\\u308b\\u3053\\u3068\\u3092\\u78ba\\u8a8d\\u3059\\u308b\\u3002</li> <li>\\u52a0\\u7b97\\u307e\\u305f\\u306f\\u6e1b\\u7b97\\u3092\\u5b9f\\u884c\\u3059\\u308b\\u5834\\u5408\\u3001\\u7cbe\\u5ea6\\u3092\\u9ad8\\u3081\\u308b\\u305f\\u3081\\u306b\\u3001\\u540c\\u3058\\u6841\\u6570\\u306e\\u6f14\\u7b97\\u3092\\u30b0\\u30eb\\u30fc\\u30d7\\u5316\\u3059\\u308b\\u3002</li> <li>\\u7cbe\\u5ea6\\u3092\\u9ad8\\u3081\\u308b\\u305f\\u3081\\u3001\\u4e00\\u9023\\u306e\\u6f14\\u7b97\\u3067\\u52a0\\u7b97\\u3001\\u6e1b\\u7b97\\u3001\\u4e57\\u7b97\\u3001\\u9664\\u7b97\\u304c\\u5fc5\\u8981\\u306a\\u5834\\u5408\\u306f\\u3001\\u4e57\\u7b97\\u3068\\u9664\\u7b97\\u3092\\u6700\\u521d\\u306b\\u5b9f\\u884c\\u3059\\u308b\\u3002</li> </ul> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#20\",\"title\":\"\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u9577\\u3055\\u3068\\u5bb9\\u91cf\\u3092\\u7406\\u89e3\\u3057\\u3066\\u3044\\u306a\\u3044 (#20)\",\"text\":\"\\u8981\\u7d04 <p>Go \\u958b\\u767a\\u8005\\u306a\\u3089\\u3070\\u3001\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u9577\\u3055\\u3068\\u5bb9\\u91cf\\u306e\\u9055\\u3044\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u9577\\u3055\\u306f\\u30b9\\u30e9\\u30a4\\u30b9\\u5185\\u306e\\u4f7f\\u7528\\u53ef\\u80fd\\u306a\\u8981\\u7d20\\u306e\\u6570\\u3067\\u3042\\u308a\\u3001\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u5bb9\\u91cf\\u306f\\u30d0\\u30c3\\u30ad\\u30f3\\u30b0\\u914d\\u5217\\u5185\\u306e\\u8981\\u7d20\\u306e\\u6570\\u3067\\u3059\\u3002</p> <p>\\u30bb\\u30af\\u30b7\\u30e7\\u30f3\\u5168\\u6587\\u306f\\u3053\\u3061\\u3089\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#21\",\"title\":\"\\u975e\\u52b9\\u7387\\u306a\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u521d\\u671f\\u5316 (#21)\",\"text\":\"\\u8981\\u7d04 <p>\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u4f5c\\u6210\\u3059\\u308b\\u3068\\u304d\\u3001\\u9577\\u3055\\u304c\\u3059\\u3067\\u306b\\u308f\\u304b\\u3063\\u3066\\u3044\\u308b\\u5834\\u5408\\u306f\\u3001\\u6307\\u5b9a\\u3055\\u308c\\u305f\\u9577\\u3055\\u307e\\u305f\\u306f\\u5bb9\\u91cf\\u3067\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u521d\\u671f\\u5316\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002\\u3053\\u308c\\u306b\\u3088\\u308a\\u3001\\u5272\\u308a\\u5f53\\u3066\\u306e\\u6570\\u304c\\u6e1b\\u308a\\u3001\\u30d1\\u30d5\\u30a9\\u30fc\\u30de\\u30f3\\u30b9\\u304c\\u5411\\u4e0a\\u3057\\u307e\\u3059\\u3002</p> <p><code>make</code> \\u3092\\u4f7f\\u7528\\u3057\\u3066\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u521d\\u671f\\u5316\\u3059\\u308b\\u3068\\u304d\\u306b\\u3001\\u9577\\u3055\\u3068\\u30aa\\u30d7\\u30b7\\u30e7\\u30f3\\u306e\\u5bb9\\u91cf\\u3092\\u6307\\u5b9a\\u3067\\u304d\\u307e\\u3059\\u3002\\u3053\\u308c\\u3089\\u306e\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u306e\\u4e21\\u65b9\\u306b\\u9069\\u5207\\u306a\\u5024\\u3092\\u6e21\\u3059\\u3053\\u3068\\u304c\\u9069\\u5f53\\u3067\\u3042\\u308b\\u306b\\u3082\\u304b\\u304b\\u308f\\u3089\\u305a\\u3001\\u305d\\u308c\\u3092\\u5fd8\\u308c\\u308b\\u306e\\u306f\\u3088\\u304f\\u3042\\u308b\\u9593\\u9055\\u3044\\u3067\\u3059\\u3002\\u5b9f\\u969b\\u3001\\u8907\\u6570\\u306e\\u30b3\\u30d4\\u30fc\\u304c\\u5fc5\\u8981\\u306b\\u306a\\u308a\\u3001\\u4e00\\u6642\\u7684\\u306a\\u30d0\\u30c3\\u30ad\\u30f3\\u30b0\\u914d\\u5217\\u3092\\u30af\\u30ea\\u30fc\\u30f3\\u30a2\\u30c3\\u30d7\\u3059\\u308b\\u305f\\u3081\\u306b GC \\u306b\\u8ffd\\u52a0\\u306e\\u52b4\\u529b\\u304c\\u304b\\u304b\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u30d1\\u30d5\\u30a9\\u30fc\\u30de\\u30f3\\u30b9\\u306e\\u89b3\\u70b9\\u304b\\u3089\\u8a00\\u3048\\u3070\\u3001Go \\u30e9\\u30f3\\u30bf\\u30a4\\u30e0\\u306b\\u624b\\u3092\\u5dee\\u3057\\u4f38\\u3079\\u306a\\u3044\\u7406\\u7531\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002 </p> <p>\\u30aa\\u30d7\\u30b7\\u30e7\\u30f3\\u306f\\u3001\\u6307\\u5b9a\\u3055\\u308c\\u305f\\u5bb9\\u91cf\\u307e\\u305f\\u306f\\u6307\\u5b9a\\u3055\\u308c\\u305f\\u9577\\u3055\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u5272\\u308a\\u5f53\\u3066\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002 \\u3053\\u308c\\u3089 2 \\u3064\\u306e\\u89e3\\u6c7a\\u7b56\\u306e\\u3046\\u3061\\u30012 \\u756a\\u76ee\\u306e\\u89e3\\u6c7a\\u7b56\\u306e\\u65b9\\u304c\\u308f\\u305a\\u304b\\u306b\\u9ad8\\u901f\\u3067\\u3042\\u308b\\u50be\\u5411\\u304c\\u3042\\u308b\\u3053\\u3068\\u304c\\u308f\\u304b\\u308a\\u307e\\u3057\\u305f\\u3002\\u305f\\u3060\\u3057\\u3001\\u7279\\u5b9a\\u306e\\u5bb9\\u91cf\\u3068\\u8ffd\\u52a0\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u3001\\u5834\\u5408\\u306b\\u3088\\u3063\\u3066\\u306f\\u5b9f\\u88c5\\u3068\\u8aad\\u307f\\u53d6\\u308a\\u304c\\u5bb9\\u6613\\u306b\\u306a\\u308b\\u3053\\u3068\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#nil-22\",\"title\":\"nil \\u3068\\u7a7a\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u6df7\\u540c\\u3057\\u3066\\u3044\\u308b (#22)\",\"text\":\"\\u8981\\u7d04 <p><code>encoding/json</code> \\u3084 <code>reflect</code> \\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306a\\u3069\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u304d\\u306b\\u3088\\u304f\\u3042\\u308b\\u6df7\\u4e71\\u3092\\u907f\\u3051\\u308b\\u305f\\u3081\\u306b\\u306f\\u3001nil \\u30b9\\u30e9\\u30a4\\u30b9\\u3068\\u7a7a\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u9055\\u3044\\u3092\\u7406\\u89e3\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3069\\u3061\\u3089\\u3082\\u9577\\u3055\\u30bc\\u30ed\\u3001\\u5bb9\\u91cf\\u30bc\\u30ed\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u3067\\u3059\\u304c\\u3001\\u5272\\u308a\\u5f53\\u3066\\u3092\\u5fc5\\u8981\\u3068\\u3057\\u306a\\u3044\\u306e\\u306f nil \\u30b9\\u30e9\\u30a4\\u30b9\\u3060\\u3051\\u3067\\u3059\\u3002</p> <p>Go\\u8a00\\u8a9e\\u3067\\u306f\\u3001nil \\u3068\\u7a7a\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u306f\\u533a\\u5225\\u3055\\u308c\\u307e\\u3059\\u3002nil \\u30b9\\u30e9\\u30a4\\u30b9\\u306f <code>nil</code> \\u306b\\u7b49\\u3057\\u3044\\u306e\\u306b\\u5bfe\\u3057\\u3001\\u7a7a\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u9577\\u3055\\u306f\\u30bc\\u30ed\\u3067\\u3059\\u3002nil \\u30b9\\u30e9\\u30a4\\u30b9\\u306f\\u7a7a\\u3067\\u3059\\u304c\\u3001\\u7a7a\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u306f\\u5fc5\\u305a\\u3057\\u3082<code>nil</code> \\u3067\\u3042\\u308b\\u3068\\u306f\\u9650\\u308a\\u307e\\u305b\\u3093\\u3002\\u4e00\\u65b9\\u3001nil \\u30b9\\u30e9\\u30a4\\u30b9\\u306b\\u306f\\u5272\\u308a\\u5f53\\u3066\\u306f\\u5fc5\\u8981\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u3053\\u306e\\u30bb\\u30af\\u30b7\\u30e7\\u30f3\\u5168\\u4f53\\u3092\\u901a\\u3057\\u3066\\u3001\\u4ee5\\u4e0b\\u306e\\u65b9\\u6cd5\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u306b\\u3088\\u3063\\u3066\\u3001\\u72b6\\u6cc1\\u306b\\u5fdc\\u3058\\u3066\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u521d\\u671f\\u5316\\u3059\\u308b\\u3053\\u3068\\u3092\\u898b\\u3066\\u304d\\u307e\\u3057\\u305f\\u3002</p> <ul> <li>\\u6700\\u7d42\\u7684\\u306a\\u9577\\u3055\\u304c\\u4e0d\\u660e\\u3067\\u30b9\\u30e9\\u30a4\\u30b9\\u304c\\u7a7a\\u306e\\u5834\\u5408\\u306f <code>var s []string</code> </li> <li>nil \\u3068\\u7a7a\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u4f5c\\u6210\\u3059\\u308b\\u7cd6\\u8863\\u69cb\\u6587\\u3068\\u3057\\u3066\\u306e <code>[]string(nil)</code> </li> <li>\\u5c06\\u6765\\u306e\\u9577\\u3055\\u304c\\u308f\\u304b\\u3063\\u3066\\u3044\\u308b\\u5834\\u5408\\u306f <code>make([]string, length)</code> </li> </ul> <p>\\u8981\\u7d20\\u306a\\u3057\\u3067\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u521d\\u671f\\u5316\\u3059\\u308b\\u5834\\u5408\\u3001\\u6700\\u5f8c\\u306e\\u30aa\\u30d7\\u30b7\\u30e7\\u30f3 <code>[]string{}</code> \\u306f\\u907f\\u3051\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002\\u6700\\u5f8c\\u306b\\u3001\\u4e88\\u60f3\\u5916\\u306e\\u52d5\\u4f5c\\u3092\\u9632\\u3050\\u305f\\u3081\\u306b\\u3001\\u4f7f\\u7528\\u3059\\u308b\\u30e9\\u30a4\\u30d6\\u30e9\\u30ea\\u304c nil \\u3068\\u7a7a\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u533a\\u5225\\u3057\\u3066\\u3044\\u308b\\u304b\\u3069\\u3046\\u304b\\u3092\\u78ba\\u8a8d\\u3057\\u3066\\u307f\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#23\",\"title\":\"\\u30b9\\u30e9\\u30a4\\u30b9\\u304c\\u7a7a\\u304b\\u3069\\u3046\\u304b\\u3092\\u9069\\u5207\\u306b\\u78ba\\u8a8d\\u3057\\u306a\\u3044 (#23)\",\"text\":\"\\u8981\\u7d04 <p>\\u30b9\\u30e9\\u30a4\\u30b9\\u306b\\u8981\\u7d20\\u304c\\u542b\\u307e\\u308c\\u3066\\u3044\\u306a\\u3044\\u3053\\u3068\\u3092\\u78ba\\u8a8d\\u3059\\u308b\\u306b\\u306f\\u3001\\u305d\\u306e\\u9577\\u3055\\u3092\\u78ba\\u8a8d\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002\\u3053\\u308c\\u306f\\u3001\\u30b9\\u30e9\\u30a4\\u30b9\\u304c <code>nil</code> \\u3067\\u3042\\u308b\\u304b\\u7a7a\\u3067\\u3042\\u308b\\u304b\\u306b\\u95a2\\u4fc2\\u306a\\u304f\\u6a5f\\u80fd\\u3057\\u307e\\u3059\\u3002\\u30de\\u30c3\\u30d7\\u306b\\u3064\\u3044\\u3066\\u3082\\u540c\\u69d8\\u3067\\u3059\\u3002\\u660e\\u78ba\\u306a API \\u3092\\u8a2d\\u8a08\\u3059\\u308b\\u306b\\u306f\\u3001nil \\u30b9\\u30e9\\u30a4\\u30b9\\u3068\\u7a7a\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u533a\\u5225\\u3057\\u306a\\u3044\\u3067\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u30b9\\u30e9\\u30a4\\u30b9\\u306b\\u8981\\u7d20\\u304c\\u3042\\u308b\\u304b\\u3069\\u3046\\u304b\\u3092\\u5224\\u65ad\\u3059\\u308b\\u306b\\u306f\\u3001\\u30b9\\u30e9\\u30a4\\u30b9\\u304c nil \\u304b\\u3069\\u3046\\u304b\\u3001\\u307e\\u305f\\u306f\\u305d\\u306e\\u9577\\u3055\\u304c 0 \\u306b\\u7b49\\u3057\\u3044\\u304b\\u3069\\u3046\\u304b\\u3092\\u78ba\\u8a8d\\u3059\\u308b\\u3053\\u3068\\u3067\\u5224\\u65ad\\u3067\\u304d\\u307e\\u3059\\u3002\\u30b9\\u30e9\\u30a4\\u30b9\\u304c\\u7a7a\\u3067\\u3042\\u308b\\u5834\\u5408\\u3068\\u30b9\\u30e9\\u30a4\\u30b9\\u304c nil \\u3067\\u3042\\u308b\\u5834\\u5408\\u306e\\u4e21\\u65b9\\u3092\\u30ab\\u30d0\\u30fc\\u3067\\u304d\\u308b\\u305f\\u3081\\u3001\\u9577\\u3055\\u3092\\u78ba\\u304b\\u3081\\u308b\\u3053\\u3068\\u304c\\u6700\\u826f\\u306e\\u65b9\\u6cd5\\u3067\\u3059\\u3002</p> <p>\\u4e00\\u65b9\\u3001\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3092\\u8a2d\\u8a08\\u3059\\u308b\\u3068\\u304d\\u306f\\u3001\\u8efd\\u5fae\\u306a\\u30d7\\u30ed\\u30b0\\u30e9\\u30df\\u30f3\\u30b0\\u30a8\\u30e9\\u30fc\\u3092\\u8d77\\u3053\\u3055\\u306a\\u3044\\u3088\\u3046 nil \\u30b9\\u30e9\\u30a4\\u30b9\\u3068\\u7a7a\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u533a\\u5225\\u3057\\u306a\\u3044\\u3088\\u3046\\u306b\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u8fd4\\u3059\\u3068\\u304d\\u306b\\u3001nil \\u307e\\u305f\\u306f\\u7a7a\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u8fd4\\u3059\\u304b\\u3069\\u3046\\u304b\\u306f\\u3001\\u610f\\u5473\\u7684\\u306b\\u3082\\u6280\\u8853\\u7684\\u306b\\u3082\\u9055\\u3044\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u30b3\\u30fc\\u30e9\\u30fc\\u306b\\u3068\\u3063\\u3066\\u306f\\u3069\\u3061\\u3089\\u3082\\u540c\\u3058\\u3053\\u3068\\u3092\\u610f\\u5473\\u3059\\u308b\\u306f\\u305a\\u3067\\u3059\\u3002\\u3053\\u306e\\u539f\\u7406\\u306f\\u30de\\u30c3\\u30d7\\u3067\\u3082\\u540c\\u3058\\u3067\\u3059\\u3002\\u30de\\u30c3\\u30d7\\u304c\\u7a7a\\u304b\\u3069\\u3046\\u304b\\u3092\\u78ba\\u8a8d\\u3059\\u308b\\u306b\\u306f\\u3001\\u305d\\u308c\\u304c nil \\u304b\\u3069\\u3046\\u304b\\u3067\\u306f\\u306a\\u304f\\u3001\\u305d\\u306e\\u9577\\u3055\\u3092\\u78ba\\u8a8d\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#24\",\"title\":\"\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u30b3\\u30d4\\u30fc\\u3092\\u6b63\\u3057\\u304f\\u4f5c\\u6210\\u3057\\u3066\\u3044\\u306a\\u3044 (#24)\",\"text\":\"\\u8981\\u7d04 <p>\\u7d44\\u307f\\u8fbc\\u307f\\u95a2\\u6570 <code>copy</code> \\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3042\\u308b\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u5225\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u306b\\u30b3\\u30d4\\u30fc\\u3059\\u308b\\u306b\\u306f\\u3001\\u30b3\\u30d4\\u30fc\\u3055\\u308c\\u308b\\u8981\\u7d20\\u306e\\u6570\\u304c 2 \\u3064\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u9577\\u3055\\u306e\\u9593\\u306e\\u6700\\u5c0f\\u5024\\u306b\\u76f8\\u5f53\\u3059\\u308b\\u3053\\u3068\\u306b\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u8981\\u7d20\\u3092\\u3042\\u308b\\u30b9\\u30e9\\u30a4\\u30b9\\u304b\\u3089\\u5225\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u306b\\u30b3\\u30d4\\u30fc\\u3059\\u308b\\u64cd\\u4f5c\\u306f\\u3001\\u304b\\u306a\\u308a\\u983b\\u7e41\\u306b\\u884c\\u308f\\u308c\\u307e\\u3059\\u3002\\u30b3\\u30d4\\u30fc\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u5834\\u5408\\u3001\\u30b3\\u30d4\\u30fc\\u5148\\u306b\\u30b3\\u30d4\\u30fc\\u3055\\u308c\\u308b\\u8981\\u7d20\\u306e\\u6570\\u306f 2 \\u3064\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u9577\\u3055\\u306e\\u9593\\u306e\\u6700\\u5c0f\\u5024\\u306b\\u76f8\\u5f53\\u3059\\u308b\\u3053\\u3068\\u306b\\u6ce8\\u610f\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u307e\\u305f\\u3001\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u30b3\\u30d4\\u30fc\\u3059\\u308b\\u305f\\u3081\\u306e\\u4ed6\\u306e\\u4ee3\\u66ff\\u624b\\u6bb5\\u304c\\u5b58\\u5728\\u3059\\u308b\\u3053\\u3068\\u306b\\u3082\\u7559\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u305d\\u306e\\u305f\\u3081\\u3001\\u30b3\\u30fc\\u30c9\\u30d9\\u30fc\\u30b9\\u3067\\u305d\\u308c\\u3089\\u3092\\u898b\\u3064\\u3051\\u3066\\u3082\\u9a5a\\u304f\\u3053\\u3068\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#append-25\",\"title\":\"<code>append</code> \\u306e\\u4f7f\\u7528\\u306b\\u3088\\u308b\\u4e88\\u60f3\\u5916\\u306e\\u526f\\u4f5c\\u7528 (#25)\",\"text\":\"\\u8981\\u7d04 <p>2\\u3064\\u306e\\u7570\\u306a\\u308b\\u95a2\\u6570\\u304c\\u540c\\u3058\\u914d\\u5217\\u306b\\u57fa\\u3065\\u304f\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u5834\\u5408\\u306b\\u3001copy \\u307e\\u305f\\u306f\\u5b8c\\u5168\\u30b9\\u30e9\\u30a4\\u30b9\\u5f0f\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u3067 <code>append</code> \\u306b\\u3088\\u308b\\u885d\\u7a81\\u3092\\u9632\\u3050\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u5927\\u304d\\u306a\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u7e2e\\u5c0f\\u3059\\u308b\\u5834\\u5408\\u3001\\u30e1\\u30e2\\u30ea\\u30ea\\u30fc\\u30af\\u3092\\u9632\\u3050\\u3053\\u3068\\u304c\\u3067\\u304d\\u308b\\u306e\\u306f\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u30b3\\u30d4\\u30fc\\u3060\\u3051\\u3067\\u3059\\u3002</p> <p>\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u304d\\u306f\\u3001\\u4e88\\u60f3\\u5916\\u306e\\u526f\\u4f5c\\u7528\\u306b\\u3064\\u306a\\u304c\\u308b\\u72b6\\u6cc1\\u306b\\u76f4\\u9762\\u3059\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u3053\\u3068\\u3092\\u899a\\u3048\\u3066\\u304a\\u304f\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u7d50\\u679c\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u9577\\u3055\\u304c\\u305d\\u306e\\u5bb9\\u91cf\\u3088\\u308a\\u5c0f\\u3055\\u3044\\u5834\\u5408\\u3001\\u8ffd\\u52a0\\u306b\\u3088\\u3063\\u3066\\u5143\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u304c\\u5909\\u66f4\\u3055\\u308c\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u8d77\\u3053\\u308a\\u5f97\\u308b\\u526f\\u4f5c\\u7528\\u306e\\u7bc4\\u56f2\\u3092\\u5236\\u9650\\u3057\\u305f\\u3044\\u5834\\u5408\\u306f\\u3001\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u30b3\\u30d4\\u30fc\\u307e\\u305f\\u306f\\u5b8c\\u5168\\u30b9\\u30e9\\u30a4\\u30b9\\u5f0f\\u3092\\u4f7f\\u7528\\u3067\\u304d\\u307e\\u3059\\u3002\\u3053\\u308c\\u306b\\u3088\\u308a\\u3001\\u30b3\\u30d4\\u30fc\\u3092\\u5b9f\\u884c\\u3067\\u304d\\u306a\\u304f\\u306a\\u308a\\u307e\\u3059\\u3002</p> \\u88dc\\u8db3 <p><code>s[low:high:max]</code>\\uff08\\u5b8c\\u5168\\u30b9\\u30e9\\u30a4\\u30b9\\u5f0f\\uff09\\u2015\\u2015\\u3053\\u306e\\u547d\\u4ee4\\u6587\\u306f\\u3001\\u5bb9\\u91cf\\u304c <code>max - low</code> \\u306b\\u7b49\\u3057\\u3044\\u3053\\u3068\\u3092\\u9664\\u3051\\u3070\\u3001<code>s[low:high]</code> \\u3067\\u4f5c\\u6210\\u3055\\u308c\\u305f\\u30b9\\u30e9\\u30a4\\u30b9\\u3068\\u540c\\u69d8\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u4f5c\\u6210\\u3057\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#26\",\"title\":\"\\u30b9\\u30e9\\u30a4\\u30b9\\u3068\\u30e1\\u30e2\\u30ea\\u30ea\\u30fc\\u30af (#26)\",\"text\":\"\\u8981\\u7d04 <p>\\u30dd\\u30a4\\u30f3\\u30bf\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u307e\\u305f\\u306f\\u30dd\\u30a4\\u30f3\\u30bf\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u3092\\u6301\\u3064\\u69cb\\u9020\\u4f53\\u3092\\u64cd\\u4f5c\\u3059\\u308b\\u5834\\u5408\\u3001\\u30b9\\u30e9\\u30a4\\u30b9\\u64cd\\u4f5c\\u306b\\u3088\\u3063\\u3066\\u9664\\u5916\\u3055\\u308c\\u305f\\u8981\\u7d20\\u3092 nil \\u3068\\u3059\\u308b\\u3053\\u3068\\u3067\\u30e1\\u30e2\\u30ea\\u30ea\\u30fc\\u30af\\u3092\\u56de\\u907f\\u3067\\u304d\\u307e\\u3059\\u3002</p>\"},{\"location\":\"ja/#_3\",\"title\":\"\\u5bb9\\u91cf\\u6f0f\\u308c\",\"text\":\"<p>\\u5927\\u304d\\u306a\\u30b9\\u30e9\\u30a4\\u30b9\\u307e\\u305f\\u306f\\u914d\\u5217\\u3092\\u30b9\\u30e9\\u30a4\\u30b9\\u3059\\u308b\\u3068\\u3001\\u30e1\\u30e2\\u30ea\\u6d88\\u8cbb\\u304c\\u9ad8\\u304f\\u306a\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u3053\\u3068\\u306b\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u6b8b\\u308a\\u306e\\u30b9\\u30da\\u30fc\\u30b9\\u306f GC \\u306b\\u3088\\u3063\\u3066\\u518d\\u5229\\u7528\\u3055\\u308c\\u305a\\u3001\\u5c11\\u6570\\u306e\\u8981\\u7d20\\u3057\\u304b\\u4f7f\\u7528\\u3057\\u306a\\u3044\\u306b\\u3082\\u304b\\u304b\\u308f\\u3089\\u305a\\u3001\\u5927\\u304d\\u306a\\u30d0\\u30c3\\u30ad\\u30f3\\u30b0\\u914d\\u5217\\u304c\\u4fdd\\u6301\\u3055\\u308c\\u307e\\u3059\\u3002\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u30b3\\u30d4\\u30fc\\u3092\\u3059\\u308b\\u3053\\u3068\\u3067\\u3001\\u3053\\u306e\\u3088\\u3046\\u306a\\u4e8b\\u614b\\u3092\\u9632\\u3050\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#_4\",\"title\":\"\\u30b9\\u30e9\\u30a4\\u30b9\\u3068\\u30dd\\u30a4\\u30f3\\u30bf\",\"text\":\"<p>\\u30dd\\u30a4\\u30f3\\u30bf\\u307e\\u305f\\u306f\\u30dd\\u30a4\\u30f3\\u30bf\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u3092\\u542b\\u3080\\u69cb\\u9020\\u4f53\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u30b9\\u30e9\\u30a4\\u30b9\\u64cd\\u4f5c\\u3092\\u3059\\u308b\\u5834\\u5408\\u3001GC \\u304c\\u3053\\u308c\\u3089\\u306e\\u8981\\u7d20\\u3092\\u518d\\u5229\\u7528\\u3057\\u306a\\u3044\\u3053\\u3068\\u3092\\u77e5\\u3063\\u3066\\u304a\\u304f\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305d\\u306e\\u5834\\u5408\\u306e\\u9078\\u629e\\u80a2\\u306f\\u3001\\u30b3\\u30d4\\u30fc\\u3092\\u5b9f\\u884c\\u3059\\u308b\\u304b\\u3001\\u6b8b\\u308a\\u306e\\u8981\\u7d20\\u307e\\u305f\\u306f\\u305d\\u306e\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u3092\\u660e\\u793a\\u7684\\u306b <code>nil</code> \\u3068\\u3059\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#27\",\"title\":\"\\u975e\\u52b9\\u7387\\u306a\\u30de\\u30c3\\u30d7\\u306e\\u521d\\u671f\\u5316 (#27)\",\"text\":\"\\u8981\\u7d04 <p>\\u30de\\u30c3\\u30d7\\u3092\\u4f5c\\u6210\\u3059\\u308b\\u3068\\u304d\\u3001\\u305d\\u306e\\u9577\\u3055\\u304c\\u3059\\u3067\\u306b\\u308f\\u304b\\u3063\\u3066\\u3044\\u308b\\u5834\\u5408\\u306f\\u3001\\u6307\\u5b9a\\u3055\\u308c\\u305f\\u9577\\u3055\\u3067\\u521d\\u671f\\u5316\\u3057\\u307e\\u3059\\u3002\\u3053\\u308c\\u306b\\u3088\\u308a\\u3001\\u5272\\u308a\\u5f53\\u3066\\u306e\\u6570\\u304c\\u6e1b\\u308a\\u3001\\u30d1\\u30d5\\u30a9\\u30fc\\u30de\\u30f3\\u30b9\\u304c\\u5411\\u4e0a\\u3057\\u307e\\u3059\\u3002</p> <p>\\u30de\\u30c3\\u30d7\\u306f\\u3001\\u30ad\\u30fc\\u30fb\\u5024\\u30da\\u30a2\\u306e\\u9806\\u5e8f\\u306a\\u3057\\u30b3\\u30ec\\u30af\\u30b7\\u30e7\\u30f3\\u3092\\u63d0\\u4f9b\\u3057\\u307e\\u3059\\u3002\\u306a\\u304a\\u3001\\u305d\\u308c\\u305e\\u308c\\u306e\\u30da\\u30a2\\u306f\\u56fa\\u6709\\u306e\\u30ad\\u30fc\\u3092\\u6301\\u3061\\u307e\\u3059\\u3002Go\\u8a00\\u8a9e\\u3067\\u306f\\u3001\\u30de\\u30c3\\u30d7\\u306f\\u30cf\\u30c3\\u30b7\\u30e5\\u30c6\\u30fc\\u30d6\\u30eb\\u30c7\\u30fc\\u30bf\\u69cb\\u9020\\u306b\\u57fa\\u3065\\u3044\\u3066\\u3044\\u307e\\u3059\\u3002\\u5185\\u90e8\\u7684\\u306b\\u306f\\u3001\\u30cf\\u30c3\\u30b7\\u30e5\\u30c6\\u30fc\\u30d6\\u30eb\\u306f\\u30d0\\u30b1\\u30c3\\u30c8\\u306e\\u914d\\u5217\\u3067\\u3042\\u308a\\u3001\\u5404\\u30d0\\u30b1\\u30c3\\u30c8\\u306f\\u30ad\\u30fc\\u30fb\\u5024\\u30da\\u30a2\\u306e\\u914d\\u5217\\u3078\\u306e\\u30dd\\u30a4\\u30f3\\u30bf\\u3067\\u3059\\u3002 </p> <p>\\u30de\\u30c3\\u30d7\\u306b\\u542b\\u307e\\u308c\\u308b\\u8981\\u7d20\\u306e\\u6570\\u304c\\u4e8b\\u524d\\u306b\\u308f\\u304b\\u3063\\u3066\\u3044\\u308b\\u5834\\u5408\\u306f\\u3001\\u305d\\u306e\\u521d\\u671f\\u30b5\\u30a4\\u30ba\\u3092\\u6307\\u5b9a\\u3057\\u3066\\u4f5c\\u6210\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u30de\\u30c3\\u30d7\\u306e\\u5897\\u5927\\u306f\\u3001\\u5341\\u5206\\u306a\\u30b9\\u30da\\u30fc\\u30b9\\u3092\\u518d\\u5272\\u308a\\u5f53\\u3066\\u3057\\u3001\\u3059\\u3079\\u3066\\u306e\\u8981\\u7d20\\u306e\\u30d0\\u30e9\\u30f3\\u30b9\\u3092\\u518d\\u8abf\\u6574\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u305f\\u3081\\u3001\\u8a08\\u7b97\\u91cf\\u304c\\u975e\\u5e38\\u306b\\u591a\\u304f\\u306a\\u308a\\u307e\\u3059\\u304c\\u3001\\u3053\\u308c\\u306b\\u3088\\u308a\\u305d\\u308c\\u3092\\u56de\\u907f\\u3059\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#28\",\"title\":\"\\u30de\\u30c3\\u30d7\\u3068\\u30e1\\u30e2\\u30ea\\u30ea\\u30fc\\u30af (#28)\",\"text\":\"\\u8981\\u7d04 <p>\\u30de\\u30c3\\u30d7\\u306f\\u30e1\\u30e2\\u30ea\\u5185\\u3067\\u5e38\\u306b\\u5897\\u5927\\u3059\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u304c\\u3001\\u7e2e\\u5c0f\\u3059\\u308b\\u3053\\u3068\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u30e1\\u30e2\\u30ea\\u306e\\u554f\\u984c\\u304c\\u767a\\u751f\\u3059\\u308b\\u5834\\u5408\\u306f\\u3001\\u30de\\u30c3\\u30d7\\u3092\\u5f37\\u5236\\u7684\\u306b\\u518d\\u751f\\u6210\\u3057\\u305f\\u308a\\u3001\\u30dd\\u30a4\\u30f3\\u30bf\\u3092\\u4f7f\\u7528\\u3057\\u305f\\u308a\\u3059\\u308b\\u306a\\u3069\\u3001\\u3055\\u307e\\u3056\\u307e\\u306a\\u624b\\u6bb5\\u3092\\u8a66\\u3059\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30bb\\u30af\\u30b7\\u30e7\\u30f3\\u5168\\u6587\\u306f\\u3053\\u3061\\u3089\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#29\",\"title\":\"\\u8aa4\\u3063\\u305f\\u65b9\\u6cd5\\u306b\\u3088\\u308b\\u5024\\u306e\\u6bd4\\u8f03 (#29)\",\"text\":\"\\u8981\\u7d04 <p>Go\\u8a00\\u8a9e\\u3067\\u578b\\u3092\\u6bd4\\u8f03\\u3059\\u200b\\u200b\\u308b\\u306b\\u306f\\u30012 \\u3064\\u306e\\u578b\\u304c\\u6bd4\\u8f03\\u53ef\\u80fd\\u306a\\u3089\\u3070\\u3001== \\u6f14\\u7b97\\u5b50\\u3068 != \\u6f14\\u7b97\\u5b50\\u3092\\u4f7f\\u7528\\u3067\\u304d\\u307e\\u3059\\u3002\\u771f\\u507d\\u5024\\u3001\\u6570\\u5024\\u3001\\u6587\\u5b57\\u5217\\u3001\\u30dd\\u30a4\\u30f3\\u30bf\\u3001\\u30c1\\u30e3\\u30cd\\u30eb\\u3001\\u304a\\u3088\\u3073\\u69cb\\u9020\\u4f53\\u304c\\u5b8c\\u5168\\u306b\\u6bd4\\u8f03\\u53ef\\u80fd\\u306a\\u578b\\u3067\\u69cb\\u6210\\u3055\\u308c\\u3066\\u3044\\u307e\\u3059\\u3002\\u305d\\u308c\\u4ee5\\u5916\\u306f\\u3001 <code>reflect.DeepEqual</code> \\u3092\\u4f7f\\u7528\\u3057\\u3066\\u30ea\\u30d5\\u30ec\\u30af\\u30b7\\u30e7\\u30f3\\u306e\\u4ee3\\u511f\\u3092\\u652f\\u6255\\u3046\\u304b\\u3001\\u72ec\\u81ea\\u306e\\u5b9f\\u88c5\\u3068\\u30e9\\u30a4\\u30d6\\u30e9\\u30ea\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u52b9\\u679c\\u7684\\u306b\\u6bd4\\u8f03\\u3059\\u308b\\u306b\\u306f\\u3001 <code>==</code> \\u3068 <code>!=</code> \\u306e\\u4f7f\\u7528\\u65b9\\u6cd5\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3053\\u3068\\u304c\\u4e0d\\u53ef\\u6b20\\u3067\\u3059\\u3002\\u3053\\u308c\\u3089\\u306e\\u6f14\\u7b97\\u5b50\\u306f\\u3001\\u6bd4\\u8f03\\u53ef\\u80fd\\u306a\\u88ab\\u6f14\\u7b97\\u5b50\\u3067\\u4f7f\\u7528\\u3067\\u304d\\u307e\\u3059\\u3002 </p> <ul> <li>\\u771f\\u507d\\u5024 - 2 \\u3064\\u306e\\u771f\\u507d\\u5024\\u304c\\u7b49\\u3057\\u3044\\u304b\\u3069\\u3046\\u304b\\u3092\\u6bd4\\u8f03\\u3057\\u307e\\u3059\\u3002 </li> <li>\\u6570\\u5024 (int\\u3001float\\u3001\\u304a\\u3088\\u3073 complex \\u578b) - 2 \\u3064\\u306e\\u6570\\u5024\\u304c\\u7b49\\u3057\\u3044\\u304b\\u3069\\u3046\\u304b\\u3092\\u6bd4\\u8f03\\u3057\\u307e\\u3059\\u3002 </li> <li>\\u6587\\u5b57\\u5217 - 2 \\u3064\\u306e\\u6587\\u5b57\\u5217\\u304c\\u7b49\\u3057\\u3044\\u304b\\u3069\\u3046\\u304b\\u3092\\u6bd4\\u8f03\\u3057\\u307e\\u3059\\u3002 </li> <li>\\u30c1\\u30e3\\u30cd\\u30eb - 2 \\u3064\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u304c\\u540c\\u3058 make \\u547c\\u3073\\u51fa\\u3057\\u306b\\u3088\\u3063\\u3066\\u4f5c\\u6210\\u3055\\u308c\\u305f\\u304b\\u3001\\u307e\\u305f\\u306f\\u4e21\\u65b9\\u304c nil \\u3067\\u3042\\u308b\\u304b\\u3092\\u6bd4\\u8f03\\u3057\\u307e\\u3059\\u3002 </li> <li>\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9 - 2 \\u3064\\u306e\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u304c\\u540c\\u3058\\u52d5\\u7684\\u30bf\\u30a4\\u30d7\\u3068\\u7b49\\u3057\\u3044\\u52d5\\u7684\\u5024\\u3092\\u6301\\u3064\\u304b\\u3069\\u3046\\u304b\\u3001\\u307e\\u305f\\u306f\\u4e21\\u65b9\\u304c nil \\u3067\\u3042\\u308b\\u304b\\u3069\\u3046\\u304b\\u3092\\u6bd4\\u8f03\\u3057\\u307e\\u3059\\u3002 </li> <li>\\u30dd\\u30a4\\u30f3\\u30bf - 2 \\u3064\\u306e\\u30dd\\u30a4\\u30f3\\u30bf\\u304c\\u30e1\\u30e2\\u30ea\\u5185\\u306e\\u540c\\u3058\\u5024\\u3092\\u6307\\u3057\\u3066\\u3044\\u308b\\u304b\\u3001\\u307e\\u305f\\u306f\\u4e21\\u65b9\\u3068\\u3082 nil \\u3067\\u3042\\u308b\\u304b\\u3092\\u6bd4\\u8f03\\u3057\\u307e\\u3059\\u3002 </li> <li>\\u69cb\\u9020\\u4f53\\u3068\\u914d\\u5217 - \\u985e\\u4f3c\\u3057\\u305f\\u578b\\u3067\\u69cb\\u6210\\u3055\\u308c\\u3066\\u3044\\u308b\\u304b\\u3069\\u3046\\u304b\\u3092\\u6bd4\\u8f03\\u3057\\u307e\\u3059\\u3002</li> </ul> \\u88dc\\u8db3 <p><code>?</code> \\u3001 <code>&gt;=</code> \\u3001 <code>&lt;</code> \\u3001\\u304a\\u3088\\u3073 <code>&gt;</code> \\u6f14\\u7b97\\u5b50\\u3092\\u6570\\u5024\\u578b\\u3067\\u4f7f\\u7528\\u3057\\u3066\\u5024\\u3092\\u6bd4\\u8f03\\u3057\\u305f\\u308a\\u3001\\u6587\\u5b57\\u5217\\u3067\\u5b57\\u53e5\\u9806\\u5e8f\\u3092\\u6bd4\\u8f03\\u3057\\u305f\\u308a\\u3059\\u308b\\u3053\\u3068\\u3082\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u88ab\\u6f14\\u7b97\\u5b50\\u304c\\u6bd4\\u8f03\\u3067\\u304d\\u306a\\u3044\\u5834\\u5408\\uff08\\u30b9\\u30e9\\u30a4\\u30b9\\u3068\\u30de\\u30c3\\u30d7\\u306a\\u3069\\uff09\\u3001\\u30ea\\u30d5\\u30ec\\u30af\\u30b7\\u30e7\\u30f3\\u306a\\u3069\\u306e\\u4ed6\\u306e\\u65b9\\u6cd5\\u3092\\u5229\\u7528\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u30ea\\u30d5\\u30ec\\u30af\\u30b7\\u30e7\\u30f3\\u306f\\u30e1\\u30bf\\u30d7\\u30ed\\u30b0\\u30e9\\u30df\\u30f3\\u30b0\\u306e\\u4e00\\u7a2e\\u3067\\u3042\\u308a\\u3001\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u304c\\u305d\\u306e\\u69cb\\u9020\\u3068\\u52d5\\u4f5c\\u3092\\u5185\\u7701\\u3057\\u3066\\u5909\\u66f4\\u3059\\u308b\\u6a5f\\u80fd\\u3092\\u6307\\u3057\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001Go\\u8a00\\u8a9e\\u3067\\u306f <code>reflect.DeepEqual</code> \\u3092\\u4f7f\\u7528\\u3067\\u304d\\u307e\\u3059\\u3002\\u3053\\u306e\\u95a2\\u6570\\u306f\\u30012\\u3064\\u306e\\u5024\\u3092\\u518d\\u5e30\\u7684\\u306b\\u8abf\\u3079\\u308b\\u3053\\u3068\\u306b\\u3088\\u3063\\u3066\\u30012\\u3064\\u306e\\u8981\\u7d20\\u304c\\u5b8c\\u5168\\u306b\\u7b49\\u3057\\u3044\\u304b\\u3069\\u3046\\u304b\\u3092\\u5831\\u544a\\u3057\\u307e\\u3059\\u3002\\u53d7\\u3051\\u5165\\u308c\\u3089\\u308c\\u308b\\u8981\\u7d20\\u306f\\u3001\\u57fa\\u672c\\u578b\\u306b\\u52a0\\u3048\\u3066\\u3001\\u914d\\u5217\\u3001\\u69cb\\u9020\\u4f53\\u3001\\u30b9\\u30e9\\u30a4\\u30b9\\u3001\\u30de\\u30c3\\u30d7\\u3001\\u30dd\\u30a4\\u30f3\\u30bf\\u3001\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3001\\u95a2\\u6570\\u3067\\u3059\\u3002\\u3057\\u304b\\u3057\\u3001\\u6700\\u5927\\u306e\\u843d\\u3068\\u3057\\u7a74\\u306f\\u30d1\\u30d5\\u30a9\\u30fc\\u30de\\u30f3\\u30b9\\u4e0a\\u306e\\u30da\\u30ca\\u30eb\\u30c6\\u30a3\\u3067\\u3059\\u3002 </p> <p>\\u5b9f\\u884c\\u6642\\u306e\\u30d1\\u30d5\\u30a9\\u30fc\\u30de\\u30f3\\u30b9\\u304c\\u91cd\\u8981\\u306a\\u5834\\u5408\\u306f\\u3001\\u72ec\\u81ea\\u306e\\u30e1\\u30bd\\u30c3\\u30c9\\u3092\\u5b9f\\u88c5\\u3059\\u308b\\u3053\\u3068\\u304c\\u6700\\u5584\\u3068\\u306a\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p>\\u8ffd\\u8a18\\uff1a\\u6a19\\u6e96\\u30e9\\u30a4\\u30d6\\u30e9\\u30ea\\u306b\\u306f\\u65e2\\u306b\\u6bd4\\u8f03\\u30e1\\u30bd\\u30c3\\u30c9\\u304c\\u3044\\u304f\\u3064\\u304b\\u3042\\u308b\\u3053\\u3068\\u3092\\u899a\\u3048\\u3066\\u304a\\u304f\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001\\u6700\\u9069\\u5316\\u3055\\u308c\\u305f <code>bytes.Compare</code> \\u95a2\\u6570\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u30012\\u3064\\u306e\\u30d0\\u30a4\\u30c8\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u6bd4\\u8f03\\u3067\\u304d\\u307e\\u3059\\u3002\\u72ec\\u81ea\\u306e\\u30e1\\u30bd\\u30c3\\u30c9\\u3092\\u5b9f\\u88c5\\u3059\\u308b\\u524d\\u306b\\u3001\\u8eca\\u8f2a\\u306e\\u518d\\u767a\\u660e\\u3092\\u3057\\u306a\\u3044\\u3088\\u3046\\u306b\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#_5\",\"title\":\"\\u5236\\u5fa1\\u69cb\\u9020\",\"text\":\"\"},{\"location\":\"ja/#range-30\",\"title\":\"\\u8981\\u7d20\\u304c <code>range</code> \\u30eb\\u30fc\\u30d7\\u5185\\u3067\\u30b3\\u30d4\\u30fc\\u3055\\u308c\\u308b\\u3053\\u3068\\u3092\\u77e5\\u3089\\u306a\\u3044  (#30)\",\"text\":\"\\u8981\\u7d04 <p><code>range</code> \\u30eb\\u30fc\\u30d7\\u5185\\u306e value \\u8981\\u7d20\\u306f\\u30b3\\u30d4\\u30fc\\u3067\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u305f\\u3068\\u3048\\u3070\\u69cb\\u9020\\u4f53\\u3092\\u5909\\u66f4\\u3059\\u308b\\u306b\\u306f\\u3001\\u305d\\u306e\\u30a4\\u30f3\\u30c7\\u30c3\\u30af\\u30b9\\u3092\\u4ecb\\u3057\\u3066\\u30a2\\u30af\\u30bb\\u30b9\\u3059\\u308b\\u304b\\u3001\\u5f93\\u6765\\u306e <code>for</code> \\u30eb\\u30fc\\u30d7\\u3092\\u4ecb\\u3057\\u3066\\u30a2\\u30af\\u30bb\\u30b9\\u3057\\u307e\\u3057\\u3087\\u3046\\uff08\\u5909\\u66f4\\u3059\\u308b\\u8981\\u7d20\\u307e\\u305f\\u306f\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u304c\\u30dd\\u30a4\\u30f3\\u30bf\\u3067\\u3042\\u308b\\u5834\\u5408\\u3092\\u9664\\u304f\\uff09\\u3002</p> <p>range \\u30eb\\u30fc\\u30d7\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u3001\\u3055\\u307e\\u3056\\u307e\\u306a\\u30c7\\u30fc\\u30bf\\u69cb\\u9020\\u306b\\u53cd\\u5fa9\\u51e6\\u7406\\u3092\\u884c\\u3046\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002 </p> <ul> <li>\\u6587\\u5b57\\u5217</li> <li>\\u914d\\u5217</li> <li>\\u914d\\u5217\\u3078\\u306e\\u30dd\\u30a4\\u30f3\\u30bf</li> <li>\\u30b9\\u30e9\\u30a4\\u30b9</li> <li>\\u30de\\u30c3\\u30d7</li> <li>\\u53d7\\u4fe1\\u30c1\\u30e3\\u30cd\\u30eb </li> </ul> <p>\\u53e4\\u5178\\u7684\\u306a <code>for</code> \\u30eb\\u30fc\\u30d7\\u3068\\u6bd4\\u8f03\\u3059\\u308b\\u3068\\u3001<code>range</code> \\u30eb\\u30fc\\u30d7\\u306f\\u305d\\u306e\\u7c21\\u6f54\\u306a\\u69cb\\u6587\\u306e\\u304a\\u304b\\u3052\\u3067\\u3001\\u3053\\u308c\\u3089\\u306e\\u30c7\\u30fc\\u30bf\\u69cb\\u9020\\u306e\\u3059\\u3079\\u3066\\u306e\\u8981\\u7d20\\u306b\\u53cd\\u5fa9\\u51e6\\u7406\\u3092\\u3059\\u308b\\u306e\\u306b\\u4fbf\\u5229\\u3067\\u3059\\u3002</p> <p>\\u305f\\u3060\\u3057\\u3001range \\u30eb\\u30fc\\u30d7\\u5185\\u306e\\u5024\\u8981\\u7d20\\u306f\\u30b3\\u30d4\\u30fc\\u3067\\u3042\\u308b\\u3053\\u3068\\u3092\\u899a\\u3048\\u3066\\u304a\\u304f\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u5024\\u3092\\u5909\\u66f4\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u69cb\\u9020\\u4f53\\u306e\\u5834\\u5408\\u3001\\u5909\\u66f4\\u3059\\u308b\\u5024\\u307e\\u305f\\u306f\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u304c\\u30dd\\u30a4\\u30f3\\u30bf\\u3067\\u306a\\u3044\\u9650\\u308a\\u3001\\u8981\\u7d20\\u81ea\\u4f53\\u3067\\u306f\\u306a\\u304f\\u30b3\\u30d4\\u30fc\\u306e\\u307f\\u3092\\u66f4\\u65b0\\u3057\\u307e\\u3059\\u3002range \\u30eb\\u30fc\\u30d7\\u307e\\u305f\\u306f\\u5f93\\u6765\\u306e for \\u30eb\\u30fc\\u30d7\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u30a4\\u30f3\\u30c7\\u30c3\\u30af\\u30b9\\u7d4c\\u7531\\u3067\\u8981\\u7d20\\u306b\\u30a2\\u30af\\u30bb\\u30b9\\u3059\\u308b\\u3053\\u3068\\u304c\\u63a8\\u5968\\u3055\\u308c\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#range-31\",\"title\":\"<code>range</code> \\u30eb\\u30fc\\u30d7\\uff08\\u30c1\\u30e3\\u30cd\\u30eb\\u3068\\u914d\\u5217\\uff09\\u3067\\u306e\\u5f15\\u6570\\u306e\\u8a55\\u4fa1\\u65b9\\u6cd5\\u3092\\u77e5\\u3089\\u306a\\u3044 (#31)\",\"text\":\"\\u8981\\u7d04 <p><code>range</code> \\u6f14\\u7b97\\u5b50\\u306b\\u6e21\\u3055\\u308c\\u308b\\u5f0f\\u306f\\u30eb\\u30fc\\u30d7\\u306e\\u958b\\u59cb\\u524d\\u306b 1 \\u56de\\u3060\\u3051\\u8a55\\u4fa1\\u3055\\u308c\\u308b\\u3053\\u3068\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3068\\u3001\\u30c1\\u30e3\\u30cd\\u30eb\\u307e\\u305f\\u306f\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u53cd\\u5fa9\\u51e6\\u7406\\u306b\\u304a\\u3051\\u308b\\u975e\\u52b9\\u7387\\u306a\\u5272\\u308a\\u5f53\\u3066\\u306a\\u3069\\u306e\\u3042\\u308a\\u304c\\u3061\\u306a\\u9593\\u9055\\u3044\\u3092\\u56de\\u907f\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>range \\u30eb\\u30fc\\u30d7\\u306f\\u3001\\uff08\\u30bf\\u30a4\\u30d7\\u306b\\u95a2\\u4fc2\\u306a\\u304f\\uff09\\u30b3\\u30d4\\u30fc\\u3092\\u5b9f\\u884c\\u3059\\u308b\\u3053\\u3068\\u306b\\u3088\\u308a\\u3001\\u30eb\\u30fc\\u30d7\\u306e\\u958b\\u59cb\\u524d\\u306b\\u3001\\u6307\\u5b9a\\u3055\\u308c\\u305f\\u5f0f\\u3092 1 \\u56de\\u3060\\u3051\\u8a55\\u4fa1\\u3057\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001\\u8aa4\\u3063\\u305f\\u8981\\u7d20\\u306b\\u30a2\\u30af\\u30bb\\u30b9\\u3057\\u3066\\u3057\\u307e\\u3046\\u3001\\u3068\\u3044\\u3046\\u3088\\u3046\\u306a\\u3042\\u308a\\u304c\\u3061\\u306a\\u9593\\u9055\\u3044\\u3092\\u907f\\u3051\\u308b\\u305f\\u3081\\u306b\\u3001\\u3053\\u306e\\u52d5\\u4f5c\\u3092\\u899a\\u3048\\u3066\\u304a\\u304f\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070</p> <pre><code>a := [3]int{0, 1, 2}\\nfor i, v := range a {\\n    a[2] = 10\\n    if i == 2 {\\n        fmt.Println(v)\\n    }\\n}\\n</code></pre> <p>\\u3053\\u306e\\u30b3\\u30fc\\u30c9\\u306f\\u3001\\u6700\\u5f8c\\u306e\\u30a4\\u30f3\\u30c7\\u30c3\\u30af\\u30b9\\u3092 10 \\u306b\\u66f4\\u65b0\\u3057\\u307e\\u3059\\u3002\\u3057\\u304b\\u3057\\u3001\\u3053\\u306e\\u30b3\\u30fc\\u30c9\\u3092\\u5b9f\\u884c\\u3059\\u308b\\u3068\\u300110 \\u306f\\u51fa\\u529b\\u3055\\u308c\\u307e\\u305b\\u3093\\u3002 2 \\u304c\\u51fa\\u529b\\u3055\\u308c\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#range-32\",\"title\":\"<code>range</code> \\u30eb\\u30fc\\u30d7\\u5185\\u306b\\u304a\\u3051\\u308b\\u30dd\\u30a4\\u30f3\\u30bf\\u8981\\u7d20\\u306e\\u4f7f\\u7528\\u304c\\u53ca\\u307c\\u3059\\u5f71\\u97ff\\u3092\\u5206\\u304b\\u3063\\u3066\\u3044\\u306a\\u3044 (#32)\",\"text\":\"\\u8981\\u7d04 <p>\\u30ed\\u30fc\\u30ab\\u30eb\\u5909\\u6570\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u304b\\u3001\\u30a4\\u30f3\\u30c7\\u30c3\\u30af\\u30b9\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u8981\\u7d20\\u306b\\u30a2\\u30af\\u30bb\\u30b9\\u3059\\u308b\\u3068\\u3001\\u30eb\\u30fc\\u30d7\\u5185\\u3067\\u30dd\\u30a4\\u30f3\\u30bf\\u3092\\u30b3\\u30d4\\u30fc\\u3059\\u308b\\u969b\\u306e\\u9593\\u9055\\u3044\\u3092\\u9632\\u3050\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p><code>range</code> \\u30eb\\u30fc\\u30d7\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u30c7\\u30fc\\u30bf\\u69cb\\u9020\\u306b\\u53cd\\u5fa9\\u51e6\\u7406\\u3092\\u65bd\\u3059\\u5834\\u5408\\u3001\\u3059\\u3079\\u3066\\u306e\\u5024\\u304c\\u5358\\u4e00\\u306e\\u4e00\\u610f\\u306e\\u30a2\\u30c9\\u30ec\\u30b9\\u3092\\u6301\\u3064\\u4e00\\u610f\\u306e\\u5909\\u6570\\u306b\\u5272\\u308a\\u5f53\\u3066\\u3089\\u308c\\u308b\\u3053\\u3068\\u3092\\u601d\\u3044\\u51fa\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u3086\\u3048\\u306b\\u3001\\u5404\\u53cd\\u5fa9\\u51e6\\u7406\\u4e2d\\u306b\\u3053\\u306e\\u5909\\u6570\\u3092\\u53c2\\u7167\\u3059\\u308b\\u30dd\\u30a4\\u30f3\\u30bf\\u3092\\u4fdd\\u5b58\\u3059\\u308b\\u3068\\u3001\\u540c\\u3058\\u8981\\u7d20\\u3001\\u3064\\u307e\\u308a\\u6700\\u65b0\\u306e\\u8981\\u7d20\\u3092\\u53c2\\u7167\\u3059\\u308b\\u540c\\u3058\\u30dd\\u30a4\\u30f3\\u30bf\\u3092\\u4fdd\\u5b58\\u3059\\u308b\\u3053\\u3068\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002\\u3053\\u306e\\u554f\\u984c\\u306f\\u3001\\u30eb\\u30fc\\u30d7\\u306e\\u30b9\\u30b3\\u30fc\\u30d7\\u5185\\u306b\\u30ed\\u30fc\\u30ab\\u30eb\\u5909\\u6570\\u3092\\u5f37\\u5236\\u7684\\u306b\\u4f5c\\u6210\\u3059\\u308b\\u304b\\u3001\\u30a4\\u30f3\\u30c7\\u30c3\\u30af\\u30b9\\u3092\\u4ecb\\u3057\\u3066\\u30b9\\u30e9\\u30a4\\u30b9\\u8981\\u7d20\\u3092\\u53c2\\u7167\\u3059\\u308b\\u30dd\\u30a4\\u30f3\\u30bf\\u3092\\u4f5c\\u6210\\u3059\\u308b\\u3053\\u3068\\u3067\\u89e3\\u6c7a\\u3067\\u304d\\u307e\\u3059\\u3002\\u3069\\u3061\\u3089\\u306e\\u89e3\\u6c7a\\u7b56\\u3067\\u3082\\u554f\\u984c\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#33\",\"title\":\"\\u30de\\u30c3\\u30d7\\u306e\\u53cd\\u5fa9\\u51e6\\u7406\\u4e2d\\u306b\\u8aa4\\u3063\\u305f\\u4eee\\u5b9a\\u3092\\u3059\\u308b\\uff08\\u53cd\\u5fa9\\u51e6\\u7406\\u4e2d\\u306e\\u9806\\u5e8f\\u4ed8\\u3051\\u3068\\u30de\\u30c3\\u30d7\\u306e\\u633f\\u5165\\uff09 (#33)\",\"text\":\"\\u8981\\u7d04 <p>\\u30de\\u30c3\\u30d7\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u304d\\u306b\\u4e88\\u6e2c\\u53ef\\u80fd\\u306a\\u51fa\\u529b\\u3092\\u4fdd\\u8a3c\\u3059\\u308b\\u306b\\u306f\\u3001\\u30de\\u30c3\\u30d7\\u306e\\u30c7\\u30fc\\u30bf\\u69cb\\u9020\\u304c\\u6b21\\u306e\\u3068\\u304a\\u308a\\u3067\\u3042\\u308b\\u3053\\u3068\\u306b\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002 </p> <ul> <li>\\u30c7\\u30fc\\u30bf\\u3092\\u30ad\\u30fc\\u3067\\u4e26\\u3079\\u66ff\\u3048\\u307e\\u305b\\u3093 </li> <li>\\u633f\\u5165\\u9806\\u5e8f\\u306f\\u4fdd\\u6301\\u3055\\u308c\\u307e\\u305b\\u3093 </li> <li>\\u53cd\\u5fa9\\u51e6\\u7406\\u9806\\u5e8f\\u306f\\u6c7a\\u307e\\u3063\\u3066\\u3044\\u307e\\u305b\\u3093</li> <li>\\u3042\\u308b\\u53cd\\u5fa9\\u51e6\\u7406\\u4e2d\\u306b\\u8ffd\\u52a0\\u3055\\u308c\\u305f\\u8981\\u7d20\\u304c\\u305d\\u306e\\u51e6\\u7406\\u4e2d\\u306b\\u751f\\u6210\\u3055\\u308c\\u308b\\u3053\\u3068\\u3092\\u4fdd\\u8a3c\\u3057\\u307e\\u305b\\u3093</li> </ul> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#break-34\",\"title\":\"<code>break</code> \\u6587\\u304c\\u3069\\u306e\\u3088\\u3046\\u306b\\u6a5f\\u80fd\\u3059\\u308b\\u304b\\u3092\\u5206\\u304b\\u3063\\u3066\\u3044\\u306a\\u3044 (#34)\",\"text\":\"\\u8981\\u7d04 <p>\\u30e9\\u30d9\\u30eb\\u3068 <code>break</code> \\u307e\\u305f\\u306f <code>continue</code> \\u306e\\u4f75\\u7528\\u306f\\u3001\\u7279\\u5b9a\\u306e\\u547d\\u4ee4\\u6587\\u3092\\u5f37\\u5236\\u7684\\u306b\\u4e2d\\u65ad\\u3057\\u307e\\u3059\\u3002\\u3053\\u308c\\u306f\\u3001\\u30eb\\u30fc\\u30d7\\u5185\\u306e <code>switch</code> \\u307e\\u305f\\u306f <code>select</code> \\u6587\\u3067\\u5f79\\u7acb\\u3061\\u307e\\u3059\\u3002 </p> <p>\\u901a\\u5e38\\u3001break \\u6587\\u306f\\u30eb\\u30fc\\u30d7\\u306e\\u5b9f\\u884c\\u3092\\u7d42\\u4e86\\u3059\\u308b\\u305f\\u3081\\u306b\\u4f7f\\u7528\\u3055\\u308c\\u307e\\u3059\\u3002\\u30eb\\u30fc\\u30d7\\u304c switch \\u307e\\u305f\\u306f select \\u3068\\u7d44\\u307f\\u5408\\u308f\\u305b\\u3066\\u4f7f\\u7528\\u200b\\u200b\\u3055\\u308c\\u308b\\u5834\\u5408\\u3001\\u76ee\\u7684\\u306e\\u547d\\u4ee4\\u6587\\u3067\\u306f\\u306a\\u3044\\u306e\\u306b\\u4e2d\\u65ad\\u3055\\u305b\\u3066\\u3057\\u307e\\u3046\\u3001\\u3068\\u3044\\u3046\\u30df\\u30b9\\u3092\\u3059\\u308b\\u3053\\u3068\\u304c\\u958b\\u767a\\u8005\\u306b\\u306f\\u3088\\u304f\\u3042\\u308a\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070</p> <pre><code>for i := 0; i &lt; 5; i++ {\\n    fmt.Printf(\\\"%d \\\", i)\\n\\n    switch i {\\n    default:\\n    case 2:\\n        break\\n    }\\n}\\n</code></pre> <p>break \\u6587\\u306f <code>for</code> \\u30eb\\u30fc\\u30d7\\u3092\\u7d42\\u4e86\\u3055\\u305b\\u308b\\u306e\\u3067\\u306f\\u306a\\u304f\\u3001\\u4ee3\\u308f\\u308a\\u306b <code>switch</code> \\u6587\\u3092\\u7d42\\u4e86\\u3055\\u305b\\u307e\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u3053\\u306e\\u30b3\\u30fc\\u30c9\\u306f 0 \\u304b\\u3089 2 \\u307e\\u3067\\u3092\\u53cd\\u5fa9\\u3059\\u308b\\u4ee3\\u308f\\u308a\\u306b\\u30010 \\u304b\\u3089 4 \\u307e\\u3067\\u3092\\u53cd\\u5fa9\\u3057\\u307e\\u3059\\uff08<code>0 1 2 3 4</code>\\uff09\\u3002</p> <p>\\u899a\\u3048\\u3066\\u304a\\u304f\\u3079\\u304d\\u91cd\\u8981\\u306a\\u30eb\\u30fc\\u30eb\\u306e1\\u3064\\u306f\\u3001 <code>break</code> \\u6587\\u306f\\u6700\\u3082\\u5185\\u5074\\u306e <code>for</code> \\u3001<code>switch</code> \\u3001\\u307e\\u305f\\u306f <code>select</code> \\u6587\\u306e\\u5b9f\\u884c\\u3092\\u7d42\\u4e86\\u3059\\u308b\\u3068\\u3044\\u3046\\u3053\\u3068\\u3067\\u3059\\u3002\\u524d\\u306e\\u4f8b\\u3067\\u306f\\u3001<code>switch</code> \\u6587\\u3092\\u7d42\\u4e86\\u3057\\u307e\\u3059\\u3002 </p> <p><code>switch</code> \\u6587\\u306e\\u4ee3\\u308f\\u308a\\u306b\\u30eb\\u30fc\\u30d7\\u3092\\u4e2d\\u65ad\\u3059\\u308b\\u6700\\u3082\\u6163\\u7528\\u7684\\u306a\\u65b9\\u6cd5\\u306f\\u30e9\\u30d9\\u30eb\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002</p> <pre><code>loop:\\n    for i := 0; i &lt; 5; i++ {\\n        fmt.Printf(\\\"%d \\\", i)\\n\\n        switch i {\\n        default:\\n        case 2:\\n            break loop\\n        }\\n    }\\n</code></pre> <p>\\u3053\\u3053\\u3067\\u306f\\u3001<code>loop</code> \\u30e9\\u30d9\\u30eb\\u3092 <code>for</code> \\u30eb\\u30fc\\u30d7\\u306b\\u95a2\\u9023\\u4ed8\\u3051\\u307e\\u3059\\u3002 \\u6b21\\u306b\\u3001<code>break</code> \\u6587\\u306b <code>loop</code> \\u30e9\\u30d9\\u30eb\\u3092\\u6307\\u5b9a\\u3059\\u308b\\u306e\\u3067\\u3001switch \\u3067\\u306f\\u306a\\u304f loop \\u304c\\u4e2d\\u65ad\\u3055\\u308c\\u307e\\u3059\\u3002\\u3088\\u3063\\u3066\\u3001\\u3053\\u306e\\u65b0\\u3057\\u3044\\u30d0\\u30fc\\u30b8\\u30e7\\u30f3\\u306f\\u4e88\\u60f3\\u3069\\u304a\\u308a <code>0 1 2</code> \\u3092\\u51fa\\u529b\\u3057\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#defer-35\",\"title\":\"\\u30eb\\u30fc\\u30d7\\u5185\\u3067 <code>defer</code> \\u3092\\u4f7f\\u7528\\u3059\\u308b (#35)\",\"text\":\"\\u8981\\u7d04 <p>\\u95a2\\u6570\\u5185\\u306e\\u30eb\\u30fc\\u30d7\\u30ed\\u30b8\\u30c3\\u30af\\u306e\\u62bd\\u51fa\\u306f\\u3001\\u5404\\u53cd\\u5fa9\\u306e\\u6700\\u5f8c\\u3067\\u306e <code>defer</code> \\u6587\\u306e\\u5b9f\\u884c\\u306b\\u3064\\u306a\\u304c\\u308a\\u307e\\u3059\\u3002</p> <p><code>defer</code> \\u6587\\u306f\\u3001\\u4e0a\\u4f4d\\u30d6\\u30ed\\u30c3\\u30af\\u306e\\u95a2\\u6570\\u304c\\u623b\\u308b\\u307e\\u3067\\u547c\\u3073\\u51fa\\u3057\\u306e\\u5b9f\\u884c\\u3092\\u9045\\u3089\\u305b\\u307e\\u3059\\u3002\\u3053\\u308c\\u306f\\u4e3b\\u306b\\u5b9a\\u578b\\u30b3\\u30fc\\u30c9\\u3092\\u524a\\u6e1b\\u3059\\u308b\\u305f\\u3081\\u306b\\u4f7f\\u7528\\u3055\\u308c\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001\\u30ea\\u30bd\\u30fc\\u30b9\\u3092\\u6700\\u7d42\\u7684\\u306b\\u9589\\u3058\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u5834\\u5408\\u306f\\u3001<code>defer</code> \\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3001<code>return</code> \\u3092\\u5b9f\\u884c\\u3059\\u308b\\u524d\\u306b\\u30af\\u30ed\\u30fc\\u30b8\\u30e3\\u547c\\u3073\\u51fa\\u3057\\u3092\\u7e70\\u308a\\u8fd4\\u3059\\u3053\\u3068\\u3092\\u907f\\u3051\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002 </p> <p><code>defer</code> \\u3067\\u3088\\u304f\\u3042\\u308b\\u30df\\u30b9\\u306e1\\u3064\\u306f\\u3001\\u4e0a\\u4f4d\\u30d6\\u30ed\\u30c3\\u30af \\u306e\\u95a2\\u6570\\u304c\\u623b\\u3063\\u305f\\u3068\\u304d\\u306b\\u95a2\\u6570\\u547c\\u3073\\u51fa\\u3057\\u304c\\u30b9\\u30b1\\u30b8\\u30e5\\u30fc\\u30eb\\u3055\\u308c\\u308b\\u3053\\u3068\\u3092\\u5fd8\\u308c\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070</p> <pre><code>func readFiles(ch &lt;-chan string) error {\\n    for path := range ch {\\n        file, err := os.Open(path)\\n        if err != nil {\\n            return err\\n        }\\n\\n        defer file.Close()\\n\\n        // \\u30d5\\u30a1\\u30a4\\u30eb\\u306e\\u51e6\\u7406\\u3092\\u3059\\u308b\\n    }\\n    return nil\\n}\\n</code></pre> <p><code>defer</code> \\u547c\\u3073\\u51fa\\u3057\\u306f\\u3001\\u5404\\u30eb\\u30fc\\u30d7\\u53cd\\u5fa9\\u4e2d\\u3067\\u306f\\u306a\\u304f\\u3001<code>readFiles</code> \\u95a2\\u6570\\u304c\\u8fd4\\u3055\\u308c\\u305f\\u3068\\u304d\\u306b\\u5b9f\\u884c\\u3055\\u308c\\u307e\\u3059\\u3002 <code>readFiles</code> \\u304c\\u8fd4\\u3089\\u306a\\u3044\\u5834\\u5408\\u3001\\u30d5\\u30a1\\u30a4\\u30eb\\u8a18\\u8ff0\\u5b50\\u306f\\u6c38\\u4e45\\u306b\\u958b\\u3044\\u305f\\u307e\\u307e\\u306b\\u306a\\u308a\\u3001\\u30ea\\u30fc\\u30af\\u304c\\u767a\\u751f\\u3057\\u307e\\u3059\\u3002 </p> <p>\\u3053\\u306e\\u554f\\u984c\\u3092\\u89e3\\u6c7a\\u3059\\u308b\\u305f\\u3081\\u306e\\u4e00\\u822c\\u7684\\u306a\\u624b\\u6bb5\\u306e1\\u3064\\u306f\\u3001 <code>defer</code> \\u306e\\u5f8c\\u306b\\u3001\\u5404\\u53cd\\u5fa9\\u4e2d\\u306b\\u547c\\u3073\\u51fa\\u3055\\u308c\\u308b\\u4e0a\\u4f4d\\u30d6\\u30ed\\u30c3\\u30af\\u306e\\u95a2\\u6570\\u3092\\u4f5c\\u6210\\u3059\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002</p> <pre><code>func readFiles(ch &lt;-chan string) error {\\n    for path := range ch {\\n        if err := readFile(path); err != nil {\\n            return err\\n        }\\n    }\\n    return nil\\n}\\n\\nfunc readFile(path string) error {\\n    file, err := os.Open(path)\\n    if err != nil {\\n        return err\\n    }\\n\\n    defer file.Close()\\n\\n    // \\u30d5\\u30a1\\u30a4\\u30eb\\u306e\\u51e6\\u7406\\u3092\\u3059\\u308b\\n    return nil\\n}\\n</code></pre> <p>\\u5225\\u306e\\u89e3\\u6c7a\\u7b56\\u306f\\u3001<code>readFile</code> \\u95a2\\u6570\\u3092\\u30af\\u30ed\\u30fc\\u30b8\\u30e3\\u306b\\u3059\\u308b\\u3053\\u3068\\u3067\\u3059\\u304c\\u3001\\u672c\\u8cea\\u7684\\u306b\\u306f\\u540c\\u3058\\u3067\\u3059\\u3002\\u5225\\u306e\\u4e0a\\u4f4d\\u30d6\\u30ed\\u30c3\\u30af\\u306e\\u95a2\\u6570\\u3092\\u8ffd\\u52a0\\u3057\\u3066\\u3001\\u5404\\u53cd\\u5fa9\\u4e2d\\u306b <code>defer</code> \\u547c\\u3073\\u51fa\\u3057\\u3092\\u5b9f\\u884c\\u3057\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#_6\",\"title\":\"\\u6587\\u5b57\\u5217\",\"text\":\"\"},{\"location\":\"ja/#36\",\"title\":\"\\u30eb\\u30fc\\u30f3\\u3092\\u7406\\u89e3\\u3057\\u3066\\u3044\\u306a\\u3044 (#36)\",\"text\":\"\\u8981\\u7d04 <p>\\u30eb\\u30fc\\u30f3\\u304c Unicode \\u30b3\\u30fc\\u30c9\\u30dd\\u30a4\\u30f3\\u30c8\\u306e\\u6982\\u5ff5\\u306b\\u5bfe\\u5fdc\\u3057\\u3001\\u8907\\u6570\\u306e\\u30d0\\u30a4\\u30c8\\u3067\\u69cb\\u6210\\u3055\\u308c\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u3053\\u3068\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3053\\u3068\\u306f\\u3001 Go \\u958b\\u767a\\u8005\\u304c\\u6587\\u5b57\\u5217\\u3092\\u6b63\\u78ba\\u306b\\u64cd\\u4f5c\\u3059\\u308b\\u305f\\u3081\\u306b\\u4e0d\\u53ef\\u6b20\\u3067\\u3059\\u3002</p> <p>Go\\u8a00\\u8a9e\\u3067\\u306f\\u30eb\\u30fc\\u30f3\\u304c\\u3042\\u3089\\u3086\\u308b\\u5834\\u6240\\u306b\\u4f7f\\u7528\\u3055\\u308c\\u308b\\u305f\\u3081\\u3001\\u6b21\\u306e\\u70b9\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3053\\u3068\\u304c\\u91cd\\u8981\\u3067\\u3059\\u3002 </p> <ul> <li>\\u6587\\u5b57\\u30bb\\u30c3\\u30c8\\u306f\\u6587\\u5b57\\u306e\\u96c6\\u5408\\u3067\\u3059\\u304c\\u3001\\u30a8\\u30f3\\u30b3\\u30fc\\u30c7\\u30a3\\u30f3\\u30b0\\u306f\\u6587\\u5b57\\u30bb\\u30c3\\u30c8\\u3092\\u30d0\\u30a4\\u30ca\\u30ea\\u306b\\u5909\\u63db\\u3059\\u308b\\u65b9\\u6cd5\\u3092\\u8a18\\u8ff0\\u3057\\u307e\\u3059\\u3002</li> <li>Go\\u8a00\\u8a9e\\u3067\\u306f\\u3001\\u6587\\u5b57\\u5217\\u306f\\u4efb\\u610f\\u306e\\u30d0\\u30a4\\u30c8\\u306e\\u4e0d\\u5909\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u53c2\\u7167\\u3057\\u307e\\u3059\\u3002</li> <li>Go\\u8a00\\u8a9e\\u306e\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9\\u306f UTF-8 \\u3067\\u30a8\\u30f3\\u30b3\\u30fc\\u30c9\\u3055\\u308c\\u3066\\u3044\\u307e\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u3059\\u3079\\u306e\\u6587\\u5b57\\u5217\\u30ea\\u30c6\\u30e9\\u30eb\\u306f UTF-8 \\u6587\\u5b57\\u5217\\u3067\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u6587\\u5b57\\u5217\\u306b\\u306f\\u4efb\\u610f\\u306e\\u30d0\\u30a4\\u30c8\\u304c\\u542b\\u307e\\u308c\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u305f\\u3081\\u3001\\u6587\\u5b57\\u5217\\u304c\\uff08\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9\\u3067\\u306f\\u306a\\u3044\\uff09\\u4ed6\\u306e\\u5834\\u6240\\u304b\\u3089\\u53d6\\u5f97\\u3055\\u308c\\u305f\\u5834\\u5408\\u3001\\u305d\\u306e\\u6587\\u5b57\\u5217\\u304c UTF-8 \\u30a8\\u30f3\\u30b3\\u30fc\\u30c7\\u30a3\\u30f3\\u30b0\\u306b\\u57fa\\u3065\\u3044\\u3066\\u3044\\u308b\\u4fdd\\u8a3c\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002</li> <li><code>rune</code> \\u306f Unicode \\u30b3\\u30fc\\u30c9\\u30dd\\u30a4\\u30f3\\u30c8\\u306e\\u6982\\u5ff5\\u306b\\u5bfe\\u5fdc\\u3057\\u3001\\u5358\\u4e00\\u306e\\u5024\\u3067\\u8868\\u3055\\u308c\\u308b\\u30a2\\u30a4\\u30c6\\u30e0\\u3092\\u610f\\u5473\\u3057\\u307e\\u3059\\u3002</li> <li>UTF-8 \\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u3001Unicode \\u30b3\\u30fc\\u30c9\\u30dd\\u30a4\\u30f3\\u30c8\\u3092 1 \\uff5e 4 \\u30d0\\u30a4\\u30c8\\u306b\\u30a8\\u30f3\\u30b3\\u30fc\\u30c9\\u3067\\u304d\\u307e\\u3059\\u3002</li> <li>Go\\u8a00\\u8a9e\\u3067\\u6587\\u5b57\\u5217\\u306b\\u5bfe\\u3057\\u3066 <code>len()</code> \\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u3001\\u30eb\\u30fc\\u30f3\\u6570\\u3067\\u306f\\u306a\\u304f\\u30d0\\u30a4\\u30c8\\u6570\\u304c\\u8fd4\\u3055\\u308c\\u307e\\u3059\\u3002</li> </ul> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#37\",\"title\":\"\\u6587\\u5b57\\u5217\\u306b\\u5bfe\\u3059\\u308b\\u4e0d\\u6b63\\u306a\\u53cd\\u5fa9\\u51e6\\u7406 (#37)\",\"text\":\"\\u8981\\u7d04 <p><code>range</code> \\u6f14\\u7b97\\u5b50\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u6587\\u5b57\\u5217\\u3092\\u53cd\\u5fa9\\u51e6\\u7406\\u3059\\u308b\\u3068\\u3001\\u30eb\\u30fc\\u30f3\\u306e\\u30d0\\u30a4\\u30c8\\u30b7\\u30fc\\u30b1\\u30f3\\u30b9\\u306e\\u958b\\u59cb\\u30a4\\u30f3\\u30c7\\u30c3\\u30af\\u30b9\\u306b\\u5bfe\\u5fdc\\u3059\\u308b\\u30a4\\u30f3\\u30c7\\u30c3\\u30af\\u30b9\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u30eb\\u30fc\\u30f3\\u304c\\u53cd\\u5fa9\\u51e6\\u7406\\u3055\\u308c\\u307e\\u3059\\u3002\\u7279\\u5b9a\\u306e\\u30eb\\u30fc\\u30f3\\u30a4\\u30f3\\u30c7\\u30c3\\u30af\\u30b9\\uff08 3 \\u756a\\u76ee\\u306e\\u30eb\\u30fc\\u30f3\\u306a\\u3069\\uff09\\u306b\\u30a2\\u30af\\u30bb\\u30b9\\u3059\\u308b\\u306b\\u306f\\u3001\\u6587\\u5b57\\u5217\\u3092 <code>[]rune</code> \\u306b\\u5909\\u63db\\u3057\\u307e\\u3059\\u3002 </p> <p>\\u6587\\u5b57\\u5217\\u306e\\u53cd\\u5fa9\\u51e6\\u7406\\u306f\\u3001\\u958b\\u767a\\u8005\\u306b\\u3068\\u3063\\u3066\\u4e00\\u822c\\u7684\\u306a\\u64cd\\u4f5c\\u3067\\u3059\\u3002\\u304a\\u305d\\u3089\\u304f\\u3001\\u6587\\u5b57\\u5217\\u5185\\u306e\\u5404\\u30eb\\u30fc\\u30f3\\u306b\\u5bfe\\u3057\\u3066\\u64cd\\u4f5c\\u3092\\u5b9f\\u884c\\u3059\\u308b\\u304b\\u3001\\u7279\\u5b9a\\u306e\\u90e8\\u5206\\u6587\\u5b57\\u5217\\u3092\\u691c\\u7d22\\u3059\\u308b\\u72ec\\u81ea\\u306e\\u95a2\\u6570\\u3092\\u5b9f\\u88c5\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u3067\\u3057\\u3087\\u3046\\u3002\\u3069\\u3061\\u3089\\u306e\\u5834\\u5408\\u3082\\u3001\\u6587\\u5b57\\u5217\\u306e\\u7570\\u306a\\u308b\\u30eb\\u30fc\\u30f3\\u3092\\u53cd\\u5fa9\\u51e6\\u7406\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3057\\u304b\\u3057\\u3001\\u53cd\\u5fa9\\u51e6\\u7406\\u304c\\u3069\\u306e\\u3088\\u3046\\u306b\\u6a5f\\u80fd\\u3059\\u308b\\u304b\\u306b\\u3064\\u3044\\u3066\\u306f\\u56f0\\u60d1\\u3057\\u3084\\u3059\\u3044\\u3067\\u3059\\u3002 </p> <p>\\u6b21\\u306e\\u4f8b\\u3092\\u8003\\u3048\\u3066\\u307f\\u307e\\u3057\\u3087\\u3046\\u3002</p> <pre><code>s := \\\"h\\u00eallo\\\"\\nfor i := range s {\\n    fmt.Printf(\\\"position %d: %c\\\\n\\\", i, s[i])\\n}\\nfmt.Printf(\\\"len=%d\\\\n\\\", len(s))\\n</code></pre> <pre><code>position 0: h\\nposition 1: \\u00c3\\nposition 3: l\\nposition 4: l\\nposition 5: o\\nlen=6\\n</code></pre> <p>\\u6df7\\u4e71\\u3092\\u62db\\u304f\\u53ef\\u80fd\\u6027\\u306e\\u3042\\u308b 3 \\u70b9\\u3092\\u53d6\\u308a\\u4e0a\\u3052\\u307e\\u3057\\u3087\\u3046\\u3002 </p> <ul> <li>2 \\u756a\\u76ee\\u306e\\u30eb\\u30fc\\u30f3\\u306f\\u3001\\u51fa\\u529b\\u3067\\u306f \\u00ea \\u3067\\u306f\\u306a\\u304f \\u00c3 \\u306b\\u306a\\u308a\\u307e\\u3059\\u3002 </li> <li>position 1 \\u304b\\u3089 position 3 \\u306b\\u30b8\\u30e3\\u30f3\\u30d7\\u3057\\u307e\\u3057\\u305f\\u3002 position 2 \\u306b\\u306f\\u4f55\\u304c\\u3042\\u308b\\u306e\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002</li> <li>len \\u306f 6 \\u3092\\u8fd4\\u3057\\u307e\\u3059\\u304c\\u3001s \\u306b\\u306f 5 \\u3064\\u306e\\u30eb\\u30fc\\u30f3\\u3057\\u304b\\u542b\\u307e\\u308c\\u3066\\u3044\\u307e\\u305b\\u3093\\u3002 </li> </ul> <p>\\u7d50\\u679c\\u306e\\u6700\\u5f8c\\u304b\\u3089\\u898b\\u3066\\u3044\\u304d\\u307e\\u3057\\u3087\\u3046\\u3002len \\u306f\\u30eb\\u30fc\\u30f3\\u6570\\u3067\\u306f\\u306a\\u304f\\u3001\\u6587\\u5b57\\u5217\\u5185\\u306e\\u30d0\\u30a4\\u30c8\\u6570\\u3092\\u8fd4\\u3059\\u3053\\u3068\\u306f\\u3059\\u3067\\u306b\\u8ff0\\u3079\\u307e\\u3057\\u305f\\u3002\\u6587\\u5b57\\u5217\\u30ea\\u30c6\\u30e9\\u30eb\\u3092 <code>s</code> \\u306b\\u5272\\u308a\\u5f53\\u3066\\u3066\\u3044\\u308b\\u305f\\u3081\\u3001<code>s</code> \\u306f UTF-8 \\u6587\\u5b57\\u5217\\u3067\\u3059\\u3002\\u4e00\\u65b9\\u3001\\u7279\\u6b8a\\u6587\\u5b57\\u300c\\u00ea\\u300d\\u306f 1 \\u30d0\\u30a4\\u30c8\\u3067\\u30a8\\u30f3\\u30b3\\u30fc\\u30c9\\u3055\\u308c\\u307e\\u305b\\u3093\\u3002 2 \\u30d0\\u30a4\\u30c8\\u5fc5\\u8981\\u3067\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001<code>len(s)</code> \\u3092\\u547c\\u3073\\u51fa\\u3059\\u3068 6 \\u304c\\u8fd4\\u3055\\u308c\\u307e\\u3059\\u3002 </p> <p>\\u524d\\u306e\\u4f8b\\u3067\\u306f\\u3001\\u5404\\u30eb\\u30fc\\u30f3\\u3092\\u53cd\\u5fa9\\u51e6\\u7406\\u3057\\u3066\\u3044\\u306a\\u3044\\u3053\\u3068\\u3092\\u7406\\u89e3\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u4ee3\\u308f\\u308a\\u306b\\u3001\\u30eb\\u30fc\\u30f3\\u306e\\u5404\\u958b\\u59cb\\u30a4\\u30f3\\u30c7\\u30c3\\u30af\\u30b9\\u3092\\u53cd\\u5fa9\\u51e6\\u7406\\u3057\\u307e\\u3059\\u3002 </p> <p> </p> <p><code>s[i]</code> \\u3092\\u51fa\\u529b\\u3057\\u3066\\u3082 i \\u756a\\u76ee\\u306e\\u30eb\\u30fc\\u30f3\\u306f\\u51fa\\u529b\\u3055\\u308c\\u307e\\u305b\\u3093\\u3002\\u30a4\\u30f3\\u30c7\\u30c3\\u30af\\u30b9 <code>i</code> \\u306e\\u30d0\\u30a4\\u30c8\\u306e UTF-8 \\u8868\\u73fe\\u3092\\u51fa\\u529b\\u3057\\u307e\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001 <code>h\\u00eallo</code> \\u306e\\u4ee3\\u308f\\u308a\\u306b <code>h\\u00c3llo</code> \\u3092\\u51fa\\u529b\\u304c\\u3055\\u308c\\u307e\\u3059\\u3002 </p> <p>\\u3055\\u307e\\u3056\\u307e\\u306a\\u30eb\\u30fc\\u30f3\\u6587\\u5b57\\u3092\\u3059\\u3079\\u3066\\u51fa\\u529b\\u3057\\u305f\\u3044\\u5834\\u5408\\u306f\\u3001 <code>range</code> \\u6f14\\u7b97\\u5b50\\u306e value \\u8981\\u7d20\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002</p> <pre><code>s := \\\"h\\u00eallo\\\"\\nfor i, r := range s {\\n    fmt.Printf(\\\"position %d: %c\\\\n\\\", i, r)\\n}\\n</code></pre> <p>\\u307e\\u305f\\u306f\\u3001\\u6587\\u5b57\\u5217\\u3092\\u30eb\\u30fc\\u30f3\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u306b\\u5909\\u63db\\u3057\\u3001\\u305d\\u308c\\u3092\\u53cd\\u5fa9\\u51e6\\u7406\\u3059\\u308b\\u3053\\u3068\\u3082\\u3067\\u304d\\u307e\\u3059\\u3002</p> <pre><code>s := \\\"h\\u00eallo\\\"\\nrunes := []rune(s)\\nfor i, r := range runes {\\n    fmt.Printf(\\\"position %d: %c\\\\n\\\", i, r)\\n}\\n</code></pre> <p>\\u3053\\u306e\\u89e3\\u6c7a\\u7b56\\u3067\\u306f\\u3001\\u4ee5\\u524d\\u306e\\u89e3\\u6c7a\\u7b56\\u3068\\u6bd4\\u8f03\\u3057\\u3066\\u5b9f\\u884c\\u6642\\u306e\\u30aa\\u30fc\\u30d0\\u30fc\\u30d8\\u30c3\\u30c9\\u304c\\u767a\\u751f\\u3059\\u308b\\u3053\\u3068\\u306b\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u5b9f\\u969b\\u3001\\u6587\\u5b57\\u5217\\u3092\\u30eb\\u30fc\\u30f3\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u306b\\u5909\\u63db\\u3059\\u308b\\u306b\\u306f\\u3001\\u8ffd\\u52a0\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u5272\\u308a\\u5f53\\u3066\\u3001\\u30d0\\u30a4\\u30c8\\u3092\\u30eb\\u30fc\\u30f3\\u306b\\u5909\\u63db\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u6587\\u5b57\\u5217\\u306e\\u30d0\\u30a4\\u30c8\\u6570\\u3092 n \\u3068\\u3059\\u308b\\u3068\\u3001\\u6642\\u9593\\u8a08\\u7b97\\u91cf\\u306f O(n) \\u306b\\u306a\\u308a\\u307e\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u3059\\u3079\\u3066\\u306e\\u30eb\\u30fc\\u30f3\\u3092\\u53cd\\u5fa9\\u51e6\\u7406\\u3059\\u308b\\u5834\\u5408\\u306f\\u3001\\u6700\\u521d\\u306e\\u89e3\\u6c7a\\u7b56\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002 </p> <p>\\u305f\\u3060\\u3057\\u3001\\u6700\\u521d\\u306e\\u65b9\\u6cd5\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u6587\\u5b57\\u5217\\u306e i \\u756a\\u76ee\\u306e\\u30eb\\u30fc\\u30f3\\u306b\\u30a2\\u30af\\u30bb\\u30b9\\u3057\\u305f\\u3044\\u5834\\u5408\\u306f\\u3001\\u30eb\\u30fc\\u30f3\\u30a4\\u30f3\\u30c7\\u30c3\\u30af\\u30b9\\u306b\\u30a2\\u30af\\u30bb\\u30b9\\u3067\\u304d\\u307e\\u305b\\u3093\\u3002\\u4ee3\\u308f\\u308a\\u306b\\u3001\\u30d0\\u30a4\\u30c8\\u30b7\\u30fc\\u30b1\\u30f3\\u30b9\\u5185\\u306e\\u30eb\\u30fc\\u30f3\\u306e\\u958b\\u59cb\\u30a4\\u30f3\\u30c7\\u30c3\\u30af\\u30b9\\u304c\\u308f\\u304b\\u308a\\u307e\\u3059\\u3002</p> <pre><code>s := \\\"h\\u00eallo\\\"\\nr := []rune(s)[4]\\nfmt.Printf(\\\"%c\\\\n\\\", r) // o\\n</code></pre> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#trim-38\",\"title\":\"trim \\u95a2\\u6570\\u306e\\u8aa4\\u7528 (#38)\",\"text\":\"\\u8981\\u7d04 <p><code>strings.TrimRight</code> \\u30fb <code>strings.TrimLeft</code> \\u306f\\u3001\\u6307\\u5b9a\\u3055\\u308c\\u305f\\u30bb\\u30c3\\u30c8\\u306b\\u542b\\u307e\\u308c\\u308b\\u3059\\u3079\\u3066\\u306e\\u672b\\u5c3e\\u30fb\\u5148\\u982d\\u306e\\u30eb\\u30fc\\u30f3\\u3092\\u524a\\u9664\\u3057\\u307e\\u3059\\u304c\\u3001 <code>strings.TrimSuffix</code> \\u30fb <code>strings.TrimPrefix</code> \\u306f\\u3001\\u6307\\u5b9a\\u3055\\u308c\\u305f\\u63a5\\u5c3e\\u8f9e\\u30fb\\u63a5\\u982d\\u8f9e\\u306e\\u306a\\u3044\\u6587\\u5b57\\u5217\\u3092\\u8fd4\\u3057\\u307e\\u3059\\u3002</p> <p>\\u305f\\u3068\\u3048\\u3070</p> <pre><code>fmt.Println(strings.TrimRight(\\\"123oxo\\\", \\\"xo\\\"))\\n</code></pre> <p>\\u306f 123 \\u3092\\u51fa\\u529b\\u3057\\u307e\\u3059</p> <p></p> <p>\\u9006\\u306b\\u3001 <code>strings.TrimLeft</code> \\u306f\\u3001\\u30bb\\u30c3\\u30c8\\u306b\\u542b\\u307e\\u308c\\u308b\\u5148\\u982d\\u306e\\u30eb\\u30fc\\u30f3\\u3092\\u3059\\u3079\\u3066\\u524a\\u9664\\u3057\\u307e\\u3059\\u3002 </p> <p>\\u4e00\\u65b9\\u3001<code>strings.TrimSuffix</code> \\u30fb <code>strings.TrimPrefix</code> \\u306f\\u3001\\u6307\\u5b9a\\u3055\\u308c\\u305f\\u672b\\u5c3e\\u306e\\u63a5\\u5c3e\\u8f9e\\u30fb\\u63a5\\u982d\\u8f9e\\u3092\\u9664\\u3044\\u305f\\u6587\\u5b57\\u5217\\u3092\\u8fd4\\u3057\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#39\",\"title\":\"\\u6700\\u9069\\u5316\\u304c\\u4e0d\\u5341\\u5206\\u306a\\u6587\\u5b57\\u5217\\u306e\\u9023\\u7d50 (#39)\",\"text\":\"\\u8981\\u7d04 <p>\\u6587\\u5b57\\u5217\\u306e\\u30ea\\u30b9\\u30c8\\u306e\\u9023\\u7d50\\u306f\\u3001\\u53cd\\u5fa9\\u3054\\u3068\\u306b\\u65b0\\u3057\\u3044\\u6587\\u5b57\\u5217\\u304c\\u5272\\u308a\\u5f53\\u3066\\u3089\\u308c\\u306a\\u3044\\u3088\\u3046\\u306b\\u3001<code>strings.Builder</code> \\u3092\\u4f7f\\u7528\\u3057\\u3066\\u884c\\u3046\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p><code>+=</code> \\u6f14\\u7b97\\u5b50\\u3092\\u7528\\u3044\\u3066\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u3059\\u3079\\u3066\\u306e\\u6587\\u5b57\\u5217\\u8981\\u7d20\\u3092\\u9023\\u7d50\\u3059\\u308b <code>concat</code> \\u95a2\\u6570\\u3092\\u8003\\u3048\\u3066\\u307f\\u307e\\u3057\\u3087\\u3046\\u3002</p> <pre><code>func concat(values []string) string {\\n    s := \\\"\\\"\\n    for _, value := range values {\\n        s += value\\n    }\\n    return s\\n}\\n</code></pre> <p>\\u5404\\u53cd\\u5fa9\\u4e2d\\u306b\\u3001 <code>+=</code> \\u6f14\\u7b97\\u5b50\\u306f <code>s</code> \\u3068 value \\u6587\\u5b57\\u5217\\u3092\\u9023\\u7d50\\u3057\\u307e\\u3059\\u3002\\u4e00\\u898b\\u3059\\u308b\\u3068\\u3001\\u3053\\u306e\\u95a2\\u6570\\u306f\\u9593\\u9055\\u3063\\u3066\\u3044\\u306a\\u3044\\u3088\\u3046\\u306b\\u898b\\u3048\\u308b\\u304b\\u3082\\u3057\\u308c\\u307e\\u305b\\u3093\\u3002\\u3057\\u304b\\u3057\\u3001\\u3053\\u306e\\u5b9f\\u88c5\\u306f\\u3001\\u6587\\u5b57\\u5217\\u306e\\u6838\\u3068\\u306a\\u308b\\u7279\\u6027\\u306e1\\u3064\\u3067\\u3042\\u308b\\u4e0d\\u5909\\u6027\\u3092\\u5fd8\\u308c\\u3066\\u3044\\u307e\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u5404\\u53cd\\u5fa9\\u3067\\u306f <code>s</code> \\u306f\\u66f4\\u65b0\\u3055\\u308c\\u307e\\u305b\\u3093\\u3002\\u30e1\\u30e2\\u30ea\\u5185\\u306b\\u65b0\\u3057\\u3044\\u6587\\u5b57\\u5217\\u3092\\u518d\\u5272\\u308a\\u5f53\\u3066\\u3059\\u308b\\u305f\\u3081\\u3001\\u3053\\u306e\\u95a2\\u6570\\u306e\\u30d1\\u30d5\\u30a9\\u30fc\\u30de\\u30f3\\u30b9\\u306b\\u5927\\u304d\\u306a\\u5f71\\u97ff\\u3092\\u4e0e\\u3048\\u307e\\u3059\\u3002 </p> <p>\\u5e78\\u3044\\u306a\\u3053\\u3068\\u306b\\u3001 <code>strings.Builder</code> \\u3092\\u7528\\u3044\\u308b\\u3053\\u3068\\u3067\\u3001\\u3053\\u306e\\u554f\\u984c\\u306b\\u5bfe\\u51e6\\u3059\\u308b\\u89e3\\u6c7a\\u7b56\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <pre><code>func concat(values []string) string {\\n    sb := strings.Builder{}\\n    for _, value := range values {\\n        _, _ = sb.WriteString(value)\\n    }\\n    return sb.String()\\n}\\n</code></pre> <p>\\u5404\\u53cd\\u5fa9\\u4e2d\\u306b\\u3001value \\u306e\\u5185\\u5bb9\\u3092\\u5185\\u90e8\\u30d0\\u30c3\\u30d5\\u30a1\\u306b\\u8ffd\\u52a0\\u3059\\u308b <code>WriteString</code> \\u30e1\\u30bd\\u30c3\\u30c9\\u3092\\u547c\\u3073\\u51fa\\u3057\\u3066\\u7d50\\u679c\\u306e\\u6587\\u5b57\\u5217\\u3092\\u69cb\\u7bc9\\u3057\\u3001\\u30e1\\u30e2\\u30ea\\u306e\\u30b3\\u30d4\\u30fc\\u3092\\u6700\\u5c0f\\u9650\\u306b\\u6291\\u3048\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3057\\u305f\\u3002</p> \\u88dc\\u8db3 <p><code>WriteString</code> \\u306f 2 \\u756a\\u76ee\\u306e\\u51fa\\u529b\\u3068\\u3057\\u3066\\u30a8\\u30e9\\u30fc\\u3092\\u8fd4\\u3057\\u307e\\u3059\\u304c\\u3001\\u610f\\u56f3\\u7684\\u306b\\u7121\\u8996\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002\\u5b9f\\u969b\\u3001\\u3053\\u306e\\u30e1\\u30bd\\u30c3\\u30c9\\u306f nil \\u30a8\\u30e9\\u30fc\\u4ee5\\u5916\\u3092\\u8fd4\\u3059\\u3053\\u3068\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u3067\\u306f\\u3001\\u3053\\u306e\\u30e1\\u30bd\\u30c3\\u30c9\\u304c\\u30b7\\u30b0\\u30cd\\u30c1\\u30e3\\u306e\\u4e00\\u90e8\\u3068\\u3057\\u3066\\u30a8\\u30e9\\u30fc\\u3092\\u8fd4\\u3059\\u76ee\\u7684\\u306f\\u4f55\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002<code>strings.Builder</code> \\u306f <code>io.StringWriter</code> \\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3092\\u5b9f\\u88c5\\u3057\\u3066\\u304a\\u308a\\u3001\\u3053\\u308c\\u306b\\u306f <code>WriteString(s string) (n int, err error)</code> \\u3068\\u3044\\u30461\\u3064\\u306e\\u30e1\\u30bd\\u30c3\\u30c9\\u304c\\u542b\\u307e\\u308c\\u3066\\u3044\\u307e\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u3053\\u306e\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u306b\\u6e96\\u62e0\\u3059\\u308b\\u306b\\u306f\\u3001<code>WriteString</code> \\u306f\\u30a8\\u30e9\\u30fc\\u3092\\u8fd4\\u3055\\u306a\\u3051\\u308c\\u3070\\u306a\\u3089\\u306a\\u3044\\u306e\\u3067\\u3059\\u3002</p> <p>\\u5185\\u90e8\\u7684\\u306b\\u306f\\u3001<code>strings.Builder</code> \\u306f\\u30d0\\u30a4\\u30c8\\u30b9\\u30e9\\u30a4\\u30b9\\u3092\\u4fdd\\u6301\\u3057\\u307e\\u3059\\u3002 <code>WriteString</code> \\u3092\\u547c\\u3073\\u51fa\\u3059\\u305f\\u3073\\u306b\\u3001\\u3053\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u306b\\u8ffd\\u52a0\\u3059\\u308b\\u547c\\u3073\\u51fa\\u3057\\u304c\\u884c\\u308f\\u308c\\u307e\\u3059\\u3002\\u3053\\u308c\\u306b\\u306f2\\u3064\\u306e\\u5f71\\u97ff\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u307e\\u305a\\u3001 <code>append</code> \\u306e\\u547c\\u3073\\u51fa\\u3057\\u304c\\u885d\\u7a81\\u72b6\\u614b\\u3092\\u5f15\\u304d\\u8d77\\u3053\\u3059\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u305f\\u3081\\u3001\\u3053\\u306e\\u69cb\\u9020\\u4f53\\u306f\\u540c\\u6642\\u306b\\u4f7f\\u7528\\u3055\\u308c\\u308b\\u3079\\u304d\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u30022\\u756a\\u76ee\\u306e\\u5f71\\u97ff\\u306f\\u3001 \\u975e\\u52b9\\u7387\\u306a\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u521d\\u671f\\u5316 (#21) \\u3067\\u898b\\u305f\\u3082\\u306e\\u3067\\u3059\\u3002\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u5c06\\u6765\\u306e\\u9577\\u3055\\u304c\\u3059\\u3067\\u306b\\u308f\\u304b\\u3063\\u3066\\u3044\\u308b\\u5834\\u5408\\u306f\\u3001\\u305d\\u308c\\u3092\\u4e8b\\u524d\\u306b\\u5272\\u308a\\u5f53\\u3066\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305d\\u306e\\u305f\\u3081\\u306b\\u3001<code>strings.Builder</code> \\u306f\\u5225\\u306e <code>n</code> \\u30d0\\u30a4\\u30c8\\u306e\\u305f\\u3081\\u306e\\u30b9\\u30da\\u30fc\\u30b9\\u3092\\u4fdd\\u8a3c\\u3059\\u308b\\u30e1\\u30bd\\u30c3\\u30c9 <code>Grow(n int)</code> \\u3092\\u6301\\u3063\\u3066\\u3044\\u307e\\u3059\\u3002</p> <pre><code>func concat(values []string) string {\\n    total := 0\\n    for i := 0; i &lt; len(values); i++ {\\n        total += len(values[i])\\n    }\\n\\n    sb := strings.Builder{}\\n    sb.Grow(total) (2)\\n    for _, value := range values {\\n        _, _ = sb.WriteString(value)\\n    }\\n    return sb.String()\\n}\\n</code></pre> <p>\\u30d9\\u30f3\\u30c1\\u30de\\u30fc\\u30af\\u3092\\u5b9f\\u884c\\u3057\\u3066 3 \\u3064\\u306e\\u30d0\\u30fc\\u30b8\\u30e7\\u30f3\\uff08 <code>+=</code> \\u3092\\u4f7f\\u7528\\u3057\\u305f V1 \\u3001\\u4e8b\\u524d\\u5272\\u308a\\u5f53\\u3066\\u306a\\u3057\\u3067 <code>strings.Builder{}</code> \\u3092\\u4f7f\\u7528\\u3057\\u305f V2 \\u3001\\u4e8b\\u524d\\u5272\\u308a\\u5f53\\u3066\\u3042\\u308a\\u306e <code>strings.Builder{}</code> \\u3092\\u4f7f\\u7528\\u3057\\u305f V3 \\uff09\\u3092\\u6bd4\\u8f03\\u3057\\u3066\\u307f\\u307e\\u3057\\u3087\\u3046\\u3002\\u5165\\u529b\\u30b9\\u30e9\\u30a4\\u30b9\\u306b\\u306f 1,000 \\u500b\\u306e\\u6587\\u5b57\\u5217\\u304c\\u542b\\u307e\\u308c\\u3066\\u304a\\u308a\\u3001\\u5404\\u6587\\u5b57\\u5217\\u306b\\u306f 1,000 \\u30d0\\u30a4\\u30c8\\u304c\\u542b\\u307e\\u308c\\u3066\\u3044\\u307e\\u3059\\u3002</p> <pre><code>BenchmarkConcatV1-4             16      72291485 ns/op\\nBenchmarkConcatV2-4           1188        878962 ns/op\\nBenchmarkConcatV3-4           5922        190340 ns/op\\n</code></pre> <p>\\u3054\\u89a7\\u306e\\u3068\\u304a\\u308a\\u3001\\u6700\\u65b0\\u30d0\\u30fc\\u30b8\\u30e7\\u30f3\\u304c\\u6700\\u3082\\u52b9\\u7387\\u7684\\u3067\\u3001V1 \\u3088\\u308a 99% \\u3001V2 \\u3088\\u308a 78% \\u9ad8\\u901f\\u3067\\u3059\\u3002 </p> <p><code>strings.Builder</code> \\u306f\\u3001\\u6587\\u5b57\\u5217\\u306e\\u30ea\\u30b9\\u30c8\\u3092\\u9023\\u7d50\\u3059\\u308b\\u305f\\u3081\\u306e\\u89e3\\u6c7a\\u7b56\\u3068\\u3057\\u3066\\u63a8\\u5968\\u3055\\u308c\\u307e\\u3059\\u3002\\u901a\\u5e38\\u3001\\u3053\\u308c\\u306f\\u30eb\\u30fc\\u30d7\\u5185\\u3067\\u4f7f\\u7528\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3044\\u304f\\u3064\\u304b\\u306e\\u6587\\u5b57\\u5217 \\uff08\\u540d\\u524d\\u3068\\u59d3\\u306a\\u3069\\uff09\\u3092\\u9023\\u7d50\\u3059\\u308b\\u3060\\u3051\\u306e\\u5834\\u5408\\u3001 <code>strings.Builder</code> \\u306e\\u4f7f\\u7528\\u306f\\u3001 <code>+=</code> \\u6f14\\u7b97\\u5b50\\u3084 <code>fmt.Sprintf</code> \\u3068\\u6bd4\\u3079\\u3066\\u53ef\\u8aad\\u6027\\u304c\\u4f4e\\u304f\\u306a\\u308b\\u304b\\u3089\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#40\",\"title\":\"\\u7121\\u99c4\\u306a\\u6587\\u5b57\\u5217\\u5909\\u63db (#40)\",\"text\":\"\\u8981\\u7d04 <p><code>bytes</code> \\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306f <code>strings</code> \\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u3068\\u540c\\u3058\\u64cd\\u4f5c\\u3092\\u63d0\\u4f9b\\u3057\\u3066\\u304f\\u308c\\u308b\\u3053\\u3068\\u3092\\u899a\\u3048\\u3066\\u304a\\u304f\\u3068\\u3001\\u4f59\\u5206\\u306a\\u30d0\\u30a4\\u30c8\\u30fb\\u6587\\u5b57\\u5217\\u5909\\u63db\\u3092\\u907f\\u3051\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u6587\\u5b57\\u5217\\u307e\\u305f\\u306f <code>[]byte</code> \\u3092\\u6271\\u3046\\u3053\\u3068\\u3092\\u9078\\u629e\\u3059\\u308b\\u5834\\u5408\\u3001\\u307b\\u3068\\u3093\\u3069\\u306e\\u30d7\\u30ed\\u30b0\\u30e9\\u30de\\u30fc\\u306f\\u5229\\u4fbf\\u6027\\u306e\\u305f\\u3081\\u306b\\u6587\\u5b57\\u5217\\u3092\\u597d\\u3080\\u50be\\u5411\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3057\\u304b\\u3057\\u3001\\u307b\\u3068\\u3093\\u3069\\u306e I/O \\u306f\\u5b9f\\u969b\\u306b\\u306f <code>[]byte</code> \\u3067\\u884c\\u308f\\u308c\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001<code>io.Reader</code>\\u3001<code>io.Writer</code>\\u3001\\u304a\\u3088\\u3073 <code>io.ReadAll</code> \\u306f\\u6587\\u5b57\\u5217\\u3067\\u306f\\u306a\\u304f <code>[]byte</code> \\u3092\\u51e6\\u7406\\u3057\\u307e\\u3059\\u3002 </p> <p>\\u6587\\u5b57\\u5217\\u3068 <code>[]byte</code> \\u306e\\u3069\\u3061\\u3089\\u3092\\u6271\\u3046\\u3079\\u304d\\u304b\\u8ff7\\u3063\\u305f\\u3068\\u304d\\u3001<code>[]byte</code> \\u3092\\u6271\\u3046\\u65b9\\u304c\\u5fc5\\u305a\\u3057\\u3082\\u9762\\u5012\\u3060\\u3068\\u3044\\u3046\\u308f\\u3051\\u3067\\u306f\\u306a\\u3044\\u3053\\u3068\\u3092\\u601d\\u3044\\u51fa\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002strings \\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u304b\\u3089\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3055\\u308c\\u305f\\u3059\\u3079\\u3066\\u306e\\u95a2\\u6570\\u306b\\u306f\\u3001<code>bytes</code> \\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306b\\u4ee3\\u66ff\\u6a5f\\u80fd\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002 <code>Split</code>\\u3001<code>Count</code>\\u3001<code>Contains</code>\\u3001<code>Index</code> \\u306a\\u3069\\u3067\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001I/O \\u3092\\u5b9f\\u884c\\u3057\\u3066\\u3044\\u308b\\u304b\\u3069\\u3046\\u304b\\u306b\\u95a2\\u4fc2\\u306a\\u304f\\u3001\\u6587\\u5b57\\u5217\\u306e\\u4ee3\\u308f\\u308a\\u306b\\u30d0\\u30a4\\u30c8\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u30ef\\u30fc\\u30af\\u30d5\\u30ed\\u30fc\\u5168\\u4f53\\u3092\\u5b9f\\u88c5\\u3067\\u304d\\u3001\\u8ffd\\u52a0\\u306e\\u5909\\u63db\\u30b3\\u30b9\\u30c8\\u3092\\u56de\\u907f\\u3067\\u304d\\u308b\\u304b\\u3069\\u3046\\u304b\\u3092\\u6700\\u521d\\u306b\\u78ba\\u8a8d\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#41\",\"title\":\"\\u90e8\\u5206\\u6587\\u5b57\\u5217\\u3068\\u30e1\\u30e2\\u30ea\\u30ea\\u30fc\\u30af (#41)\",\"text\":\"\\u8981\\u7d04 <p>\\u90e8\\u5206\\u6587\\u5b57\\u5217\\u306e\\u4ee3\\u308f\\u308a\\u306b\\u30b3\\u30d4\\u30fc\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u3001\\u90e8\\u5206\\u6587\\u5b57\\u5217\\u64cd\\u4f5c\\u306b\\u3088\\u3063\\u3066\\u8fd4\\u3055\\u308c\\u308b\\u6587\\u5b57\\u5217\\u304c\\u540c\\u3058\\u30d0\\u30a4\\u30c8\\u914d\\u5217\\u306b\\u3088\\u3063\\u3066\\u30b5\\u30dd\\u30fc\\u30c8\\u3055\\u308c\\u308b\\u305f\\u3081\\u3001\\u30e1\\u30e2\\u30ea\\u30ea\\u30fc\\u30af\\u3092\\u9632\\u3050\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30b9\\u30e9\\u30a4\\u30b9\\u3068\\u30e1\\u30e2\\u30ea\\u30ea\\u30fc\\u30af (#26) \\u3067\\u306f\\u3001\\u30b9\\u30e9\\u30a4\\u30b9\\u307e\\u305f\\u306f\\u914d\\u5217\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u304c\\u30e1\\u30e2\\u30ea\\u30ea\\u30fc\\u30af\\u306e\\u72b6\\u6cc1\\u3092\\u5f15\\u304d\\u8d77\\u3053\\u3059\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u3053\\u3068\\u3092\\u78ba\\u8a8d\\u3057\\u307e\\u3057\\u305f\\u3002\\u3053\\u306e\\u539f\\u5247\\u306f\\u3001\\u6587\\u5b57\\u5217\\u304a\\u3088\\u3073\\u90e8\\u5206\\u6587\\u5b57\\u5217\\u306e\\u64cd\\u4f5c\\u306b\\u3082\\u5f53\\u3066\\u306f\\u307e\\u308a\\u307e\\u3059\\u3002 </p> <p>Go\\u8a00\\u8a9e\\u3067\\u90e8\\u5206\\u6587\\u5b57\\u5217\\u64cd\\u4f5c\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u304d\\u306f\\u30012 \\u3064\\u306e\\u3053\\u3068\\u306b\\u7559\\u610f\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u307e\\u305a\\u3001\\u63d0\\u4f9b\\u3055\\u308c\\u308b\\u9593\\u9694\\u306f\\u30eb\\u30fc\\u30f3\\u6570\\u3067\\u306f\\u306a\\u304f\\u3001\\u30d0\\u30a4\\u30c8\\u6570\\u306b\\u57fa\\u3065\\u3044\\u3066\\u3044\\u307e\\u3059\\u3002\\u6b21\\u306b\\u3001\\u7d50\\u679c\\u306e\\u90e8\\u5206\\u6587\\u5b57\\u5217\\u304c\\u6700\\u521d\\u306e\\u6587\\u5b57\\u5217\\u3068\\u540c\\u3058\\u30d0\\u30c3\\u30ad\\u30f3\\u30b0\\u914d\\u5217\\u3092\\u5171\\u6709\\u3059\\u308b\\u305f\\u3081\\u3001\\u90e8\\u5206\\u6587\\u5b57\\u5217\\u64cd\\u4f5c\\u306b\\u3088\\u308a\\u30e1\\u30e2\\u30ea\\u30ea\\u30fc\\u30af\\u304c\\u767a\\u751f\\u3059\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3053\\u308c\\u3092\\u9632\\u3050\\u65b9\\u6cd5\\u306f\\u3001\\u6587\\u5b57\\u5217\\u306e\\u30b3\\u30d4\\u30fc\\u3092\\u624b\\u52d5\\u3067\\u5b9f\\u884c\\u3059\\u308b\\u304b\\u3001Go 1.18 \\u304b\\u3089\\u5b9f\\u88c5\\u3055\\u308c\\u3066\\u3044\\u308b <code>strings.Clone</code> \\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#_7\",\"title\":\"\\u95a2\\u6570\\u3068\\u30e1\\u30bd\\u30c3\\u30c9\",\"text\":\"\"},{\"location\":\"ja/#42\",\"title\":\"\\u3069\\u306e\\u578b\\u306e\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u3092\\u4f7f\\u7528\\u3059\\u308c\\u3070\\u3088\\u3044\\u304b\\u308f\\u304b\\u3063\\u3066\\u3044\\u306a\\u3044 (#42)\",\"text\":\"\\u8981\\u7d04 <p>\\u5024\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u3068\\u30dd\\u30a4\\u30f3\\u30bf\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u306e\\u3069\\u3061\\u3089\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u304b\\u306f\\u3001\\u3069\\u306e\\u578b\\u306a\\u306e\\u304b\\u3001\\u5909\\u5316\\u3055\\u305b\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u304b\\u3069\\u3046\\u304b\\u3001\\u30b3\\u30d4\\u30fc\\u3067\\u304d\\u306a\\u3044\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u304c\\u542b\\u307e\\u308c\\u3066\\u3044\\u308b\\u304b\\u3069\\u3046\\u304b\\u3001\\u30aa\\u30d6\\u30b8\\u30a7\\u30af\\u30c8\\u306f\\u3069\\u308c\\u304f\\u3089\\u3044\\u5927\\u304d\\u3044\\u306e\\u304b\\u3001\\u306a\\u3069\\u306e\\u8981\\u7d20\\u306b\\u57fa\\u3065\\u3044\\u3066\\u6c7a\\u5b9a\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u5206\\u304b\\u3089\\u306a\\u3044\\u5834\\u5408\\u306f\\u3001\\u30dd\\u30a4\\u30f3\\u30bf\\u30ec\\u30b7\\u30fc\\u30d0\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u5024\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u3068\\u30dd\\u30a4\\u30f3\\u30bf\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u306e\\u3069\\u3061\\u3089\\u3092\\u9078\\u629e\\u3059\\u308b\\u304b\\u306f\\u3001\\u5fc5\\u305a\\u3057\\u3082\\u7c21\\u5358\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u9078\\u629e\\u306b\\u5f79\\u7acb\\u3064\\u3044\\u304f\\u3064\\u304b\\u306e\\u6761\\u4ef6\\u306b\\u3064\\u3044\\u3066\\u8aac\\u660e\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002 </p> <p>\\u30dd\\u30a4\\u30f3\\u30bf\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u3067\\u306a\\u3051\\u308c\\u3070\\u306a\\u3089\\u306a\\u3044 \\u3068\\u304d</p> <ul> <li>\\u30e1\\u30bd\\u30c3\\u30c9\\u304c\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u3092\\u5909\\u5316\\u3055\\u305b\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u5834\\u5408\\u3002\\u3053\\u306e\\u30eb\\u30fc\\u30eb\\u306f\\u3001\\u53d7\\u4fe1\\u5074\\u304c\\u30b9\\u30e9\\u30a4\\u30b9\\u3067\\u3042\\u308a\\u3001\\u30e1\\u30bd\\u30c3\\u30c9\\u304c\\u8981\\u7d20\\u3092\\u8ffd\\u52a0\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u5834\\u5408\\u306b\\u3082\\u6709\\u52b9\\u3067\\u3059\\u3002</li> </ul> <pre><code>type slice []int\\n\\nfunc (s *slice) add(element int) {\\n    *s = append(*s, element)\\n}\\n</code></pre> <ul> <li>\\u30e1\\u30bd\\u30c3\\u30c9\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u306b\\u30b3\\u30d4\\u30fc\\u3067\\u304d\\u306a\\u3044\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u304c\\u542b\\u307e\\u308c\\u3066\\u3044\\u308b\\u5834\\u5408\\u3002sync \\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306e\\u578b\\u90e8\\u5206\\u306f\\u305d\\u306e\\u4e00\\u4f8b\\u306b\\u306a\\u308a\\u307e\\u3059\\uff08 sync \\u578b\\u306e\\u30b3\\u30d4\\u30fc (#74) \\u3092\\u53c2\\u7167\\uff09\\u3002</li> </ul> <p>\\u30dd\\u30a4\\u30f3\\u30bf\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u3067\\u3042\\u308b\\u3079\\u304d \\u3068\\u304d</p> <ul> <li>\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u304c\\u5927\\u304d\\u306a\\u30aa\\u30d6\\u30b8\\u30a7\\u30af\\u30c8\\u306e\\u5834\\u5408\\u3002\\u30dd\\u30a4\\u30f3\\u30bf\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u3001\\u5927\\u898f\\u6a21\\u306a\\u30b3\\u30d4\\u30fc\\u306e\\u4f5c\\u6210\\u304c\\u9632\\u6b62\\u3055\\u308c\\u308b\\u305f\\u3081\\u3001\\u547c\\u3073\\u51fa\\u3057\\u304c\\u3088\\u308a\\u52b9\\u7387\\u7684\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002\\u3069\\u308c\\u304f\\u3089\\u3044\\u306e\\u5927\\u304d\\u3055\\u306a\\u306e\\u304b\\u78ba\\u8a3c\\u304c\\u306a\\u3044\\u5834\\u5408\\u306f\\u3001\\u30d9\\u30f3\\u30c1\\u30de\\u30fc\\u30af\\u304c\\u89e3\\u6c7a\\u7b56\\u306b\\u306a\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u591a\\u304f\\u306e\\u8981\\u56e0\\u306b\\u4f9d\\u5b58\\u3059\\u308b\\u305f\\u3081\\u3001\\u7279\\u5b9a\\u306e\\u30b5\\u30a4\\u30ba\\u3092\\u6307\\u5b9a\\u3059\\u308b\\u3053\\u3068\\u306f\\u307b\\u3068\\u3093\\u3069\\u4e0d\\u53ef\\u80fd\\u3067\\u3059\\u3002 </li> </ul> <p>\\u5024\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u3067\\u306a\\u3051\\u308c\\u3070\\u306a\\u3089\\u306a\\u3044 \\u3068\\u304d</p> <ul> <li>\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u306e\\u4e0d\\u5909\\u6027\\u3092\\u5f37\\u5236\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u5834\\u5408\\u3002 </li> <li>\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u304c\\u30de\\u30c3\\u30d7\\u3001\\u95a2\\u6570\\u3001\\u30c1\\u30e3\\u30cd\\u30eb\\u306e\\u5834\\u5408\\u3002\\u305d\\u308c\\u4ee5\\u5916\\u306e\\u5834\\u5408\\u306f\\u30b3\\u30f3\\u30d1\\u30a4\\u30eb\\u30a8\\u30e9\\u30fc\\u304c\\u767a\\u751f\\u3057\\u307e\\u3059\\u3002 </li> </ul> <p>\\u5024\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u3067\\u3042\\u308b\\u3079\\u304d \\u3068\\u304d</p> <ul> <li>\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u304c\\u5909\\u5316\\u3055\\u305b\\u308b\\u5fc5\\u8981\\u306e\\u306a\\u3044\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u5834\\u5408\\u3002 </li> <li>\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u304c\\u3001<code>time.Time</code> \\u306a\\u3069\\u306e\\u5c0f\\u3055\\u306a\\u914d\\u5217\\u307e\\u305f\\u306f\\u69cb\\u9020\\u4f53\\u3067\\u3001\\u53ef\\u5909\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u3092\\u6301\\u305f\\u306a\\u3044\\u5024\\u578b\\u3067\\u3042\\u308b\\u5834\\u5408\\u3002 </li> <li>\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u304c <code>int</code>\\u3001<code>float64</code>\\u3001\\u307e\\u305f\\u306f <code>string</code> \\u306a\\u3069\\u306e\\u57fa\\u672c\\u578b\\u306e\\u5834\\u5408\\u3002 </li> </ul> <p>\\u3082\\u3061\\u308d\\u3093\\u3001\\u7279\\u6b8a\\u306a\\u30b1\\u30fc\\u30b9\\u306f\\u5e38\\u306b\\u5b58\\u5728\\u3059\\u308b\\u305f\\u3081\\u3001\\u3059\\u3079\\u3066\\u3092\\u7db2\\u7f85\\u3059\\u308b\\u3053\\u3068\\u306f\\u4e0d\\u53ef\\u80fd\\u3067\\u3059\\u304c\\u3001\\u3053\\u306e\\u30bb\\u30af\\u30b7\\u30e7\\u30f3\\u306e\\u76ee\\u6a19\\u306f\\u3001\\u307b\\u3068\\u3093\\u3069\\u306e\\u30b1\\u30fc\\u30b9\\u3092\\u30ab\\u30d0\\u30fc\\u3059\\u308b\\u305f\\u3081\\u306e\\u30ac\\u30a4\\u30c0\\u30f3\\u30b9\\u3092\\u63d0\\u4f9b\\u3059\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002\\u901a\\u5e38\\u306f\\u3001\\u305d\\u3046\\u3057\\u306a\\u3044\\u6b63\\u5f53\\u306a\\u7406\\u7531\\u304c\\u306a\\u3044\\u9650\\u308a\\u3001\\u5024\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u9593\\u9055\\u3044\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u5206\\u304b\\u3089\\u306a\\u3044\\u5834\\u5408\\u306f\\u3001\\u30dd\\u30a4\\u30f3\\u30bf\\u30ec\\u30b7\\u30fc\\u30d0\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#43\",\"title\":\"\\u540d\\u524d\\u4ed8\\u304d\\u7d50\\u679c\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u3092\\u307e\\u3063\\u305f\\u304f\\u4f7f\\u7528\\u3057\\u3066\\u3044\\u306a\\u3044 (#43)\",\"text\":\"\\u8981\\u7d04 <p>\\u540d\\u524d\\u4ed8\\u304d\\u7d50\\u679c\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u30fc\\u306e\\u4f7f\\u7528\\u306f\\u3001\\u7279\\u306b\\u8907\\u6570\\u306e\\u7d50\\u679c\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u30fc\\u304c\\u540c\\u3058\\u578b\\u3092\\u6301\\u3064\\u5834\\u5408\\u3001\\u95a2\\u6570\\u30fb\\u30e1\\u30bd\\u30c3\\u30c9\\u306e\\u8aad\\u307f\\u3084\\u3059\\u3055\\u3092\\u5411\\u4e0a\\u3055\\u305b\\u308b\\u52b9\\u7387\\u7684\\u306a\\u65b9\\u6cd5\\u3067\\u3059\\u3002\\u5834\\u5408\\u306b\\u3088\\u3063\\u3066\\u306f\\u3001\\u540d\\u524d\\u4ed8\\u304d\\u7d50\\u679c\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u306f\\u30bc\\u30ed\\u5024\\u306b\\u521d\\u671f\\u5316\\u3055\\u308c\\u308b\\u305f\\u3081\\u3001\\u3053\\u306e\\u65b9\\u6cd5\\u304c\\u4fbf\\u5229\\u3067\\u3059\\u3089\\u3042\\u308b\\u3053\\u3068\\u3082\\u3042\\u308a\\u307e\\u3059\\u3002\\u305f\\u3060\\u3057\\u6f5c\\u5728\\u7684\\u306a\\u526f\\u4f5c\\u7528\\u306b\\u306f\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u95a2\\u6570\\u307e\\u305f\\u306f\\u30e1\\u30bd\\u30c3\\u30c9\\u3067\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u3092\\u8fd4\\u3059\\u3068\\u304d\\u3001\\u3053\\u308c\\u3089\\u306e\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u306b\\u540d\\u524d\\u3092\\u4ed8\\u3051\\u3066\\u3001\\u901a\\u5e38\\u306e\\u5909\\u6570\\u3068\\u3057\\u3066\\u4f7f\\u7528\\u3067\\u304d\\u307e\\u3059\\u3002\\u7d50\\u679c\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u30fc\\u306b\\u540d\\u524d\\u3092\\u4ed8\\u3051\\u308b\\u3068\\u3001\\u95a2\\u6570\\u30fb\\u30e1\\u30bd\\u30c3\\u30c9\\u306e\\u958b\\u59cb\\u6642\\u306b\\u305d\\u306e\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u30fc\\u306f\\u30bc\\u30ed\\u5024\\u306b\\u521d\\u671f\\u5316\\u3055\\u308c\\u307e\\u3059\\u3002\\u540d\\u524d\\u4ed8\\u304d\\u7d50\\u679c\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u3001 \\u3080\\u304d\\u51fa\\u3057\\u306e return \\u6587\\uff08\\u5f15\\u6570\\u306a\\u3057\\uff09 \\u3092\\u547c\\u3073\\u51fa\\u3059\\u3053\\u3068\\u3082\\u3067\\u304d\\u307e\\u3059\\u3002\\u305d\\u306e\\u5834\\u5408\\u3001\\u7d50\\u679c\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u306e\\u73fe\\u5728\\u306e\\u5024\\u304c\\u623b\\u308a\\u5024\\u3068\\u3057\\u3066\\u4f7f\\u7528\\u3055\\u308c\\u307e\\u3059\\u3002 </p> <p>\\u4ee5\\u4e0b\\u306f\\u3001\\u540d\\u524d\\u4ed8\\u304d\\u7d50\\u679c\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf <code>b</code> \\u3092\\u7528\\u3044\\u305f\\u4f8b\\u3067\\u3059\\u3002</p> <pre><code>func f(a int) (b int) {\\n    b = a\\n    return\\n}\\n</code></pre> <p>\\u3053\\u306e\\u4f8b\\u3067\\u306f\\u3001\\u7d50\\u679c\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u306b\\u540d\\u524d <code>b</code> \\u3092\\u4ed8\\u3051\\u3066\\u3044\\u307e\\u3059\\u3002\\u5f15\\u6570\\u306a\\u3057\\u3067 return \\u3092\\u547c\\u3073\\u51fa\\u3059\\u3068\\u3001<code>b</code> \\u306e\\u73fe\\u5728\\u306e\\u5024\\u304c\\u8fd4\\u3055\\u308c\\u307e\\u3059\\u3002 </p> <p>\\u5834\\u5408\\u306b\\u3088\\u3063\\u3066\\u306f\\u3001\\u540d\\u524d\\u4ed8\\u304d\\u306e\\u7d50\\u679c\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u30fc\\u306b\\u3088\\u3063\\u3066\\u53ef\\u8aad\\u6027\\u304c\\u5411\\u4e0a\\u3059\\u308b\\u3053\\u3068\\u3082\\u3042\\u308a\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u30012 \\u3064\\u306e\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u30fc\\u304c\\u540c\\u3058\\u578b\\u3067\\u3042\\u308b\\u5834\\u5408\\u306a\\u3069\\u3067\\u3059\\u3002\\u305d\\u306e\\u4ed6\\u306b\\u3082\\u3001\\u5229\\u4fbf\\u6027\\u306e\\u305f\\u3081\\u306b\\u7528\\u3044\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002\\u3086\\u3048\\u306b\\u3001\\u660e\\u78ba\\u306a\\u5229\\u70b9\\u304c\\u3042\\u308b\\u5834\\u5408\\u306f\\u3001\\u614e\\u91cd\\u306b\\u306a\\u308a\\u306a\\u304c\\u3089\\u3082\\u540d\\u524d\\u4ed8\\u304d\\u7d50\\u679c\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#44\",\"title\":\"\\u540d\\u524d\\u4ed8\\u304d\\u7d50\\u679c\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u306b\\u3088\\u308b\\u4e88\\u60f3\\u5916\\u306e\\u526f\\u4f5c\\u7528 (#44)\",\"text\":\"\\u8981\\u7d04 <p>#43 \\u3092\\u53c2\\u7167\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u540d\\u524d\\u4ed8\\u304d\\u7d50\\u679c\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u304c\\u72b6\\u6cc1\\u306b\\u3088\\u3063\\u3066\\u306f\\u5f79\\u7acb\\u3064\\u7406\\u7531\\u306b\\u3064\\u3044\\u3066\\u8aac\\u660e\\u3057\\u307e\\u3057\\u305f\\u3002 \\u305f\\u3060\\u3057\\u3001\\u3053\\u308c\\u3089\\u306f\\u30bc\\u30ed\\u5024\\u306b\\u521d\\u671f\\u5316\\u3055\\u308c\\u308b\\u305f\\u3081\\u3001\\u5341\\u5206\\u306b\\u6ce8\\u610f\\u3057\\u306a\\u3044\\u3068\\u3001\\u8efd\\u5fae\\u306a\\u30d0\\u30b0\\u304c\\u767a\\u751f\\u3059\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001\\u3053\\u306e\\u30b3\\u30fc\\u30c9\\u306f\\u3069\\u3053\\u304c\\u9593\\u9055\\u3063\\u3066\\u3044\\u308b\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002</p> <pre><code>func (l loc) getCoordinates(ctx context.Context, address string) (\\n    lat, lng float32, err error) {\\n    isValid := l.validateAddress(address) (1)\\n    if !isValid {\\n        return 0, 0, errors.New(\\\"invalid address\\\")\\n    }\\n\\n    if ctx.Err() != nil { (2)\\n        return 0, 0, err\\n    }\\n\\n    // \\u5ea7\\u6a19\\u3092\\u53d6\\u5f97\\u3057\\u3066\\u8fd4\\u3059\\n}\\n</code></pre> <p>\\u4e00\\u77a5\\u3057\\u305f\\u3060\\u3051\\u3067\\u306f\\u30a8\\u30e9\\u30fc\\u306f\\u660e\\u3089\\u304b\\u3067\\u306f\\u306a\\u3044\\u304b\\u3082\\u3057\\u308c\\u307e\\u305b\\u3093\\u3002<code>if ctx.Err() != nil</code> \\u30b9\\u30b3\\u30fc\\u30d7\\u3067\\u8fd4\\u3055\\u308c\\u308b\\u30a8\\u30e9\\u30fc\\u306f <code>err</code> \\u3067\\u3059\\u3002\\u3057\\u304b\\u3057\\u3001<code>err</code> \\u5909\\u6570\\u306b\\u306f\\u5024\\u3092\\u5272\\u308a\\u5f53\\u3066\\u3066\\u3044\\u307e\\u305b\\u3093\\u3002<code>error</code> \\u578b\\u306e\\u30bc\\u30ed\\u5024\\u3001 <code>nil</code> \\u306b\\u5272\\u308a\\u5f53\\u3066\\u3089\\u308c\\u305f\\u307e\\u307e\\u3067\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u3053\\u306e\\u30b3\\u30fc\\u30c9\\u306f\\u5e38\\u306b nil \\u30a8\\u30e9\\u30fc\\u3092\\u8fd4\\u3057\\u307e\\u3059\\u3002 </p> <p>\\u540d\\u524d\\u4ed8\\u304d\\u7d50\\u679c\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u5834\\u5408\\u3001\\u5404\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u306f\\u30bc\\u30ed\\u5024\\u306b\\u521d\\u671f\\u5316\\u3055\\u308c\\u308b\\u3053\\u3068\\u306b\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u3053\\u306e\\u30bb\\u30af\\u30b7\\u30e7\\u30f3\\u3067\\u8aac\\u660e\\u3057\\u305f\\u3088\\u3046\\u306b\\u3001\\u3053\\u308c\\u306b\\u3088\\u308a\\u3001\\u898b\\u3064\\u3051\\u308b\\u306e\\u304c\\u5fc5\\u305a\\u3057\\u3082\\u7c21\\u5358\\u3067\\u306f\\u306a\\u3044\\u8efd\\u5fae\\u306a\\u30d0\\u30b0\\u304c\\u767a\\u751f\\u3059\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3086\\u3048\\u306b\\u3001\\u6f5c\\u5728\\u7684\\u306a\\u526f\\u4f5c\\u7528\\u3092\\u907f\\u3051\\u308b\\u305f\\u3081\\u306b\\u3001\\u540d\\u524d\\u4ed8\\u304d\\u7d50\\u679c\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u30fc\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u304d\\u306f\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#nil-45\",\"title\":\"nil \\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u3092\\u8fd4\\u3059 (#45)\",\"text\":\"\\u8981\\u7d04 <p>\\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3092\\u8fd4\\u3059\\u3068\\u304d\\u306f\\u3001nil \\u30dd\\u30a4\\u30f3\\u30bf\\u3092\\u8fd4\\u3059\\u306e\\u3067\\u306f\\u306a\\u304f\\u3001\\u660e\\u793a\\u7684\\u306a nil \\u5024\\u3092\\u8fd4\\u3059\\u3088\\u3046\\u306b\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u305d\\u3046\\u3057\\u306a\\u3051\\u308c\\u3070\\u3001\\u610f\\u56f3\\u3057\\u306a\\u3044\\u7d50\\u679c\\u304c\\u767a\\u751f\\u3057\\u3001\\u547c\\u3073\\u51fa\\u3057\\u5143\\u304c nil \\u3067\\u306f\\u306a\\u3044\\u5024\\u3092\\u53d7\\u3051\\u53d6\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#46\",\"title\":\"\\u95a2\\u6570\\u5165\\u529b\\u306b\\u30d5\\u30a1\\u30a4\\u30eb\\u540d\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3044\\u308b (#46)\",\"text\":\"\\u8981\\u7d04 <p>\\u30d5\\u30a1\\u30a4\\u30eb\\u540d\\u306e\\u4ee3\\u308f\\u308a\\u306b <code>io.Reader</code> \\u578b\\u3092\\u53d7\\u3051\\u53d6\\u308b\\u3088\\u3046\\u306b\\u95a2\\u6570\\u3092\\u8a2d\\u8a08\\u3059\\u308b\\u3068\\u3001\\u95a2\\u6570\\u306e\\u518d\\u5229\\u7528\\u6027\\u304c\\u5411\\u4e0a\\u3057\\u3001\\u30c6\\u30b9\\u30c8\\u304c\\u5bb9\\u6613\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002</p> <p>\\u30d5\\u30a1\\u30a4\\u30eb\\u540d\\u3092\\u30d5\\u30a1\\u30a4\\u30eb\\u304b\\u3089\\u8aad\\u307f\\u53d6\\u308b\\u305f\\u3081\\u306e\\u95a2\\u6570\\u5165\\u529b\\u3068\\u3057\\u3066\\u53d7\\u3051\\u5165\\u308c\\u308b\\u3053\\u3068\\u306f\\u3001\\u307b\\u3068\\u3093\\u3069\\u306e\\u5834\\u5408\\u3001\\u300c\\u30b3\\u30fc\\u30c9\\u306e\\u81ed\\u3044\\u300d\\u3068\\u307f\\u306a\\u3055\\u308c\\u308b\\u3079\\u304d\\u3067\\u3059\\uff08 <code>os.Open</code> \\u306a\\u3069\\u306e\\u7279\\u5b9a\\u306e\\u95a2\\u6570\\u3092\\u9664\\u304f\\uff09\\u3002\\u8907\\u6570\\u306e\\u30d5\\u30a1\\u30a4\\u30eb\\u3092\\u4f5c\\u6210\\u3059\\u308b\\u3053\\u3068\\u306b\\u306b\\u306a\\u308b\\u304b\\u3082\\u3057\\u308c\\u305a\\u3001\\u5358\\u4f53\\u30c6\\u30b9\\u30c8\\u304c\\u3088\\u308a\\u8907\\u96d1\\u306b\\u306a\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u304b\\u3089\\u3067\\u3059\\u3002\\u307e\\u305f\\u3001\\u95a2\\u6570\\u306e\\u518d\\u5229\\u7528\\u6027\\u3082\\u4f4e\\u4e0b\\u3057\\u307e\\u3059 \\uff08\\u305f\\u3060\\u3057\\u3001\\u3059\\u3079\\u3066\\u306e\\u95a2\\u6570\\u304c\\u518d\\u5229\\u7528\\u3055\\u308c\\u308b\\u308f\\u3051\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\uff09\\u3002 <code>io.Reader</code> \\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u3001\\u30c7\\u30fc\\u30bf\\u30bd\\u30fc\\u30b9\\u304c\\u62bd\\u8c61\\u5316\\u3055\\u308c\\u307e\\u3059\\u3002\\u5165\\u529b\\u304c\\u30d5\\u30a1\\u30a4\\u30eb\\u3001\\u6587\\u5b57\\u5217\\u3001HTTP \\u30ea\\u30af\\u30a8\\u30b9\\u30c8\\u3001gRPC \\u30ea\\u30af\\u30a8\\u30b9\\u30c8\\u306e\\u3044\\u305a\\u308c\\u3067\\u3042\\u308b\\u304b\\u306b\\u95a2\\u4fc2\\u306a\\u304f\\u3001\\u5b9f\\u88c5\\u306f\\u518d\\u5229\\u7528\\u3067\\u304d\\u3001\\u7c21\\u5358\\u306b\\u30c6\\u30b9\\u30c8\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#defer-47\",\"title\":\"<code>defer</code> \\u5f15\\u6570\\u3068\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u304c\\u3069\\u306e\\u3088\\u3046\\u306b\\u8a55\\u4fa1\\u3055\\u308c\\u308b\\u304b\\u3092\\u77e5\\u3089\\u306a\\u3044\\uff08\\u5f15\\u6570\\u306e\\u8a55\\u4fa1\\u3001\\u30dd\\u30a4\\u30f3\\u30bf\\u30fc\\u3001\\u304a\\u3088\\u3073\\u5024\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\uff09 (#47)\",\"text\":\"\\u8981\\u7d04 <p>\\u30dd\\u30a4\\u30f3\\u30bf\\u3092 <code>defer</code> \\u95a2\\u6570\\u306b\\u6e21\\u3059\\u3053\\u3068\\u3068\\u3001\\u547c\\u3073\\u51fa\\u3057\\u3092\\u30af\\u30ed\\u30fc\\u30b8\\u30e3\\u5185\\u306b\\u30e9\\u30c3\\u30d7\\u3059\\u308b\\u3053\\u3068\\u304c\\u3001\\u5f15\\u6570\\u3068\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u306e\\u5373\\u6642\\u8a55\\u4fa1\\u3092\\u514b\\u670d\\u3059\\u308b\\u305f\\u3081\\u306b\\u5b9f\\u73fe\\u53ef\\u80fd\\u306a\\u89e3\\u6c7a\\u7b56\\u3067\\u3059\\u3002 </p> <p><code>defer</code> \\u95a2\\u6570\\u3067\\u306f\\u3001\\u5f15\\u6570\\u306f\\u3001\\u4e0a\\u4f4d\\u30d6\\u30ed\\u30c3\\u30af\\u306e\\u95a2\\u6570\\u304c\\u623b\\u3063\\u3066\\u304b\\u3089\\u3067\\u306f\\u306a\\u304f\\u3001\\u3059\\u3050\\u306b\\u8a55\\u4fa1\\u3055\\u308c\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001\\u3053\\u306e\\u30b3\\u30fc\\u30c9\\u3067\\u306f\\u3001\\u5e38\\u306b\\u540c\\u3058\\u30b9\\u30c6\\u30fc\\u30bf\\u30b9\\u2015\\u2015\\u7a7a\\u306e\\u6587\\u5b57\\u5217\\u2015\\u2015\\u3067 <code>notify</code> \\u3068 <code>incrementCounter</code> \\u3092\\u547c\\u3073\\u51fa\\u3057\\u307e\\u3059\\u3002</p> <pre><code>const (\\n    StatusSuccess  = \\\"success\\\"\\n    StatusErrorFoo = \\\"error_foo\\\"\\n    StatusErrorBar = \\\"error_bar\\\"\\n)\\n\\nfunc f() error {\\n    var status string\\n    defer notify(status)\\n    defer incrementCounter(status)\\n\\n    if err := foo(); err != nil {\\n        status = StatusErrorFoo\\n        return err\\n    }\\n\\n    if err := bar(); err != nil {\\n        status = StatusErrorBar\\n        return err\\n    }\\n\\n    status = StatusSuccess\\n    return nil\\n}\\n</code></pre> <p>\\u305f\\u3057\\u304b\\u306b\\u3001<code>notify(status)</code> \\u3068 <code>incrementCounter(status)</code> \\u3092 <code>defer</code> \\u95a2\\u6570\\u3068\\u3057\\u3066\\u547c\\u3073\\u51fa\\u3057\\u3066\\u3044\\u307e\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001Go\\u8a00\\u8a9e\\u306f\\u3001defer \\u3092\\u4f7f\\u7528\\u3057\\u305f\\u6bb5\\u968e\\u3067 <code>f</code> \\u304c\\u30b9\\u30c6\\u30fc\\u30bf\\u30b9\\u306e\\u73fe\\u5728\\u306e\\u5024\\u3092\\u8fd4\\u3059\\u3068\\u3001\\u3053\\u308c\\u3089\\u306e\\u547c\\u3073\\u51fa\\u3057\\u306e\\u5b9f\\u884c\\u3092\\u9045\\u3089\\u305b\\u3001\\u7a7a\\u306e\\u6587\\u5b57\\u5217\\u3092\\u6e21\\u3057\\u307e\\u3059\\u3002 </p> <p><code>defer</code> \\u3092\\u4f7f\\u3044\\u7d9a\\u3051\\u305f\\u3044\\u5834\\u5408\\u306e\\u4e3b\\u306a\\u65b9\\u6cd5\\u306f 2 \\u3064\\u3042\\u308a\\u307e\\u3059\\u3002 </p> <p>\\u6700\\u521d\\u306e\\u89e3\\u6c7a\\u7b56\\u306f\\u6587\\u5b57\\u5217\\u30dd\\u30a4\\u30f3\\u30bf\\u3092\\u6e21\\u3059\\u3053\\u3068\\u3067\\u3059\\u3002</p> <pre><code>func f() error {\\n    var status string\\n    defer notify(&amp;status) \\n    defer incrementCounter(&amp;status)\\n\\n    // \\u95a2\\u6570\\u306e\\u305d\\u308c\\u4ee5\\u5916\\u306e\\u90e8\\u5206\\u306f\\u5909\\u66f4\\u306a\\u3057\\n}\\n</code></pre> <p><code>defer</code> \\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u3001\\u5f15\\u6570\\uff08\\u3053\\u3053\\u3067\\u306f\\u30b9\\u30c6\\u30fc\\u30bf\\u30b9\\u306e\\u30a2\\u30c9\\u30ec\\u30b9\\uff09\\u304c\\u3059\\u3050\\u306b\\u8a55\\u4fa1\\u3055\\u308c\\u307e\\u3059\\u3002\\u30b9\\u30c6\\u30fc\\u30bf\\u30b9\\u81ea\\u4f53\\u306f\\u95a2\\u6570\\u5168\\u4f53\\u3067\\u5909\\u66f4\\u3055\\u308c\\u307e\\u3059\\u304c\\u3001\\u305d\\u306e\\u30a2\\u30c9\\u30ec\\u30b9\\u306f\\u5272\\u308a\\u5f53\\u3066\\u306b\\u95a2\\u4fc2\\u306a\\u304f\\u4e00\\u5b9a\\u306e\\u307e\\u307e\\u3067\\u3059\\u3002\\u3088\\u3063\\u3066\\u3001<code>notify</code> \\u307e\\u305f\\u306f <code>incrementCounter</code> \\u304c\\u6587\\u5b57\\u5217\\u30dd\\u30a4\\u30f3\\u30bf\\u306b\\u3088\\u3063\\u3066\\u53c2\\u7167\\u3055\\u308c\\u308b\\u5024\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u5834\\u5408\\u3001\\u671f\\u5f85\\u3069\\u304a\\u308a\\u306b\\u52d5\\u4f5c\\u3057\\u307e\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u3053\\u306e\\u89e3\\u6c7a\\u7b56\\u3067\\u306f 2 \\u3064\\u306e\\u95a2\\u6570\\u306e\\u30b7\\u30b0\\u30cd\\u30c1\\u30e3\\u3092\\u5909\\u66f4\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u3001\\u305d\\u308c\\u304c\\u5e38\\u306b\\u53ef\\u80fd\\u3067\\u3042\\u308b\\u3068\\u306f\\u9650\\u308a\\u307e\\u305b\\u3093\\u3002 </p> <p>\\u5225\\u306e\\u89e3\\u6c7a\\u7b56\\u304c\\u3042\\u308a\\u307e\\u3059\\u2015\\u2015\\u30af\\u30ed\\u30fc\\u30b8\\u30e3\\uff08\\u672c\\u4f53\\u306e\\u5916\\u90e8\\u304b\\u3089\\u5909\\u6570\\u3092\\u53c2\\u7167\\u3059\\u308b\\u533f\\u540d\\u95a2\\u6570\\u5024\\uff09\\u3092 <code>defer</code> \\u6587\\u3068\\u3057\\u3066\\u547c\\u3073\\u51fa\\u3059\\u3053\\u3068\\u3067\\u3059\\u3002</p> <pre><code>func f() error {\\n    var status string\\n    defer func() {\\n        notify(status)\\n        incrementCounter(status)\\n    }()\\n\\n    // \\u95a2\\u6570\\u306e\\u305d\\u308c\\u4ee5\\u5916\\u306e\\u90e8\\u5206\\u306f\\u5909\\u66f4\\u306a\\u3057\\n}\\n</code></pre> <p>\\u3053\\u3053\\u3067\\u306f\\u3001<code>notify</code> \\u3068 <code>incrementCounter</code> \\u306e\\u4e21\\u65b9\\u306e\\u547c\\u3073\\u51fa\\u3057\\u3092\\u30af\\u30ed\\u30fc\\u30b8\\u30e3\\u5185\\u306b\\u30e9\\u30c3\\u30d7\\u3057\\u307e\\u3059\\u3002\\u3053\\u306e\\u30af\\u30ed\\u30fc\\u30b8\\u30e3\\u306f\\u3001\\u672c\\u4f53\\u306e\\u5916\\u90e8\\u304b\\u3089\\u30b9\\u30c6\\u30fc\\u30bf\\u30b9\\u5909\\u6570\\u3092\\u53c2\\u7167\\u3057\\u307e\\u3059\\u3002\\u3086\\u3048\\u306b\\u3001<code>status</code> \\u306f\\u3001<code>defer</code> \\u3092\\u547c\\u3073\\u51fa\\u3057\\u305f\\u3068\\u304d\\u3067\\u306f\\u306a\\u304f\\u3001\\u30af\\u30ed\\u30fc\\u30b8\\u30e3\\u304c\\u5b9f\\u884c\\u3055\\u308c\\u305f\\u3068\\u304d\\u306b\\u8a55\\u4fa1\\u3055\\u308c\\u307e\\u3059\\u3002\\u3053\\u306e\\u89e3\\u6c7a\\u7b56\\u306f\\u6b63\\u3057\\u304f\\u6a5f\\u80fd\\u3059\\u308b\\u4e0a\\u306b\\u3001\\u30b7\\u30b0\\u30cd\\u30c1\\u30e3\\u3092\\u5909\\u66f4\\u3059\\u308b\\u305f\\u3081\\u306b <code>notify</code> \\u3084 <code>incrementCounter</code> \\u3092\\u5fc5\\u8981\\u3068\\u3057\\u307e\\u305b\\u3093\\u3002 </p> <p>\\u3053\\u306e\\u52d5\\u4f5c\\u306f\\u30e1\\u30bd\\u30c3\\u30c9\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u306b\\u3082\\u9069\\u7528\\u3055\\u308c\\u308b\\u3053\\u3068\\u306b\\u3082\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u30ec\\u30b7\\u30fc\\u30d0\\u30fc\\u306f\\u3059\\u3050\\u306b\\u8a55\\u4fa1\\u3055\\u308c\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#_8\",\"title\":\"\\u30a8\\u30e9\\u30fc\\u51e6\\u7406\",\"text\":\"\"},{\"location\":\"ja/#48\",\"title\":\"\\u30d1\\u30cb\\u30c3\\u30af (#48)\",\"text\":\"\\u8981\\u7d04 <p><code>panic</code> \\u306e\\u4f7f\\u7528\\u306f\\u3001Go\\u8a00\\u8a9e\\u3067\\u30a8\\u30e9\\u30fc\\u306b\\u5bfe\\u51e6\\u3059\\u308b\\u305f\\u3081\\u306e\\u624b\\u6bb5\\u3067\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u3053\\u308c\\u306f\\u56de\\u5fa9\\u4e0d\\u80fd\\u306a\\u72b6\\u6cc1\\u3067\\u306e\\u307f\\u4f7f\\u7528\\u3059\\u308b\\u3088\\u3046\\u306b\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001\\u30d2\\u30e5\\u30fc\\u30de\\u30f3\\u30a8\\u30e9\\u30fc\\u3092\\u901a\\u77e5\\u3059\\u308b\\u5834\\u5408\\u3084\\u3001\\u5fc5\\u9808\\u306e\\u4f9d\\u5b58\\u95a2\\u4fc2\\u306e\\u8aad\\u307f\\u8fbc\\u307f\\u306b\\u5931\\u6557\\u3057\\u305f\\u5834\\u5408\\u306a\\u3069\\u3067\\u3059\\u3002</p> <p>Go\\u8a00\\u8a9e\\u3067\\u306f\\u3001panic \\u306f\\u901a\\u5e38\\u306e\\u6d41\\u308c\\u3092\\u505c\\u6b62\\u3059\\u308b\\u7d44\\u307f\\u8fbc\\u307f\\u95a2\\u6570\\u3067\\u3059\\u3002</p> <pre><code>func main() {\\n    fmt.Println(\\\"a\\\")\\n    panic(\\\"foo\\\")\\n    fmt.Println(\\\"b\\\")\\n}\\n</code></pre> <p>\\u3053\\u306e\\u30b3\\u30fc\\u30c9\\u306f a \\u3092\\u51fa\\u529b\\u3057\\u3001b \\u3092\\u51fa\\u529b\\u3059\\u308b\\u524d\\u306b\\u505c\\u6b62\\u3057\\u307e\\u3059\\u3002</p> <pre><code>a\\npanic: foo\\n\\ngoroutine 1 [running]:\\nmain.main()\\n        main.go:7 +0xb3\\n</code></pre> <p>panic \\u306e\\u4f7f\\u7528\\u306f\\u614e\\u91cd\\u306b\\u3059\\u3079\\u304d\\u3067\\u3059\\u3002\\u4ee3\\u8868\\u7684\\u306a\\u30b1\\u30fc\\u30b9\\u304c 2 \\u3064\\u3042\\u308a\\u30011 \\u3064\\u306f\\u30d2\\u30e5\\u30fc\\u30de\\u30f3\\u30a8\\u30e9\\u30fc\\u3092\\u901a\\u77e5\\u3059\\u308b\\u5834\\u5408\\uff08\\u4f8b: <code>sql.Register</code>\\u30c9\\u30e9\\u30a4\\u30d0\\u30fc\\u304c <code>nil</code> \\u307e\\u305f\\u306f\\u65e2\\u306b\\u767b\\u9332\\u3055\\u308c\\u3066\\u3044\\u308b\\u5834\\u5408\\u306b panic \\u3092\\u8d77\\u3053\\u3057\\u307e\\u3059\\uff09\\u3001\\u3082\\u3046 1 \\u3064\\u306f\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u304c\\u5fc5\\u9808\\u306e\\u4f9d\\u5b58\\u95a2\\u4fc2\\u306e\\u751f\\u6210\\u306b\\u5931\\u6557\\u3057\\u305f\\u5834\\u5408\\u3067\\u3059\\u3002\\u7d50\\u679c\\u3068\\u3057\\u3066\\u3001\\u4f8b\\u5916\\u7684\\u306b\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u505c\\u6b62\\u3057\\u307e\\u3059\\u3002\\u305d\\u308c\\u4ee5\\u5916\\u306e\\u307b\\u3068\\u3093\\u3069\\u306e\\u5834\\u5408\\u306b\\u304a\\u3044\\u3066\\u306f\\u3001\\u30a8\\u30e9\\u30fc\\u51e6\\u7406\\u306f\\u3001\\u6700\\u5f8c\\u306e\\u623b\\u308a\\u5f15\\u6570\\u3068\\u3057\\u3066\\u9069\\u5207\\u306a\\u30a8\\u30e9\\u30fc\\u578b\\u3092\\u8fd4\\u3059\\u95a2\\u6570\\u3092\\u901a\\u3058\\u3066\\u884c\\u3046\\u3079\\u304d\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#49\",\"title\":\"\\u30a8\\u30e9\\u30fc\\u3092\\u30e9\\u30c3\\u30d7\\u3059\\u3079\\u304d\\u3068\\u304d\\u3092\\u77e5\\u3089\\u306a\\u3044 (#49)\",\"text\":\"\\u8981\\u7d04 <p>\\u30a8\\u30e9\\u30fc\\u3092\\u30e9\\u30c3\\u30d7\\u3059\\u308b\\u3068\\u3001\\u30a8\\u30e9\\u30fc\\u3092\\u30de\\u30fc\\u30af\\u3057\\u305f\\u308a\\u3001\\u8ffd\\u52a0\\u306e\\u30b3\\u30f3\\u30c6\\u30ad\\u30b9\\u30c8\\u3092\\u63d0\\u4f9b\\u3057\\u305f\\u308a\\u3067\\u304d\\u307e\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u30a8\\u30e9\\u30fc\\u30e9\\u30c3\\u30d4\\u30f3\\u30b0\\u306b\\u3088\\u308a\\u3001\\u547c\\u3073\\u51fa\\u3057\\u5143\\u304c\\u30bd\\u30fc\\u30b9\\u30a8\\u30e9\\u30fc\\u3092\\u5229\\u7528\\u3067\\u304d\\u308b\\u3088\\u3046\\u306b\\u306a\\u308b\\u305f\\u3081\\u3001\\u6f5c\\u5728\\u7684\\u306a\\u7d50\\u5408\\u304c\\u767a\\u751f\\u3057\\u307e\\u3059\\u3002\\u305d\\u308c\\u3092\\u907f\\u3051\\u305f\\u3044\\u5834\\u5408\\u306f\\u3001\\u30a8\\u30e9\\u30fc\\u30e9\\u30c3\\u30d4\\u30f3\\u30b0\\u3092\\u4f7f\\u7528\\u3057\\u306a\\u3044\\u3067\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>Go 1.13 \\u4ee5\\u964d\\u3001%w \\u30c7\\u30a3\\u30ec\\u30af\\u30c6\\u30a3\\u30d6\\u3092\\u4f7f\\u7528\\u3059\\u308c\\u3070\\u7c21\\u5358\\u306b\\u30a8\\u30e9\\u30fc\\u3092\\u30e9\\u30c3\\u30d7\\u3067\\u304d\\u308b\\u3088\\u3046\\u306b\\u306a\\u308a\\u307e\\u3057\\u305f\\u3002\\u30a8\\u30e9\\u30fc\\u30e9\\u30c3\\u30d4\\u30f3\\u30b0\\u3068\\u306f\\u3001\\u30bd\\u30fc\\u30b9\\u30a8\\u30e9\\u30fc\\u3082\\u4f7f\\u7528\\u3067\\u304d\\u308b\\u3088\\u3046\\u306b\\u3059\\u308b\\u30e9\\u30c3\\u30d1\\u30fc\\u30b3\\u30f3\\u30c6\\u30ca\\u5185\\u3067\\u30a8\\u30e9\\u30fc\\u3092\\u30e9\\u30c3\\u30d7\\u307e\\u305f\\u306f\\u30d1\\u30c3\\u30af\\u3059\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002\\u4e00\\u822c\\u306b\\u3001\\u30a8\\u30e9\\u30fc\\u30e9\\u30c3\\u30d4\\u30f3\\u30b0\\u306e\\u4e3b\\u306a\\u4f7f\\u7528\\u4f8b\\u306f\\u6b21\\u306e 2 \\u3064\\u3067\\u3059\\u3002 </p> <ul> <li>\\u30a8\\u30e9\\u30fc\\u306b\\u3055\\u3089\\u306b\\u30b3\\u30f3\\u30c6\\u30ad\\u30b9\\u30c8\\u3092\\u52a0\\u3048\\u308b</li> <li>\\u30a8\\u30e9\\u30fc\\u3092\\u7279\\u5b9a\\u306e\\u30a8\\u30e9\\u30fc\\u3068\\u3057\\u3066\\u30de\\u30fc\\u30af\\u3059\\u308b </li> </ul> <p>\\u30a8\\u30e9\\u30fc\\u3092\\u51e6\\u7406\\u3059\\u308b\\u3068\\u304d\\u3001\\u30a8\\u30e9\\u30fc\\u3092\\u30e9\\u30c3\\u30d7\\u3059\\u308b\\u304b\\u3069\\u3046\\u304b\\u3092\\u6c7a\\u5b9a\\u3067\\u304d\\u307e\\u3059\\u3002\\u30e9\\u30c3\\u30d4\\u30f3\\u30b0\\u3068\\u306f\\u3001\\u30a8\\u30e9\\u30fc\\u306b\\u3055\\u3089\\u306b\\u30b3\\u30f3\\u30c6\\u30ad\\u30b9\\u30c8\\u3092\\u8ffd\\u52a0\\u3057\\u305f\\u308a\\u3001\\u30a8\\u30e9\\u30fc\\u3092\\u7279\\u5b9a\\u306e\\u30bf\\u30a4\\u30d7\\u3068\\u3057\\u3066\\u30de\\u30fc\\u30af\\u3057\\u305f\\u308a\\u3059\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002\\u30a8\\u30e9\\u30fc\\u3092\\u30de\\u30fc\\u30af\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u5834\\u5408\\u306f\\u3001\\u72ec\\u81ea\\u306e\\u30a8\\u30e9\\u30fc\\u578b\\u3092\\u4f5c\\u6210\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3067\\u3059\\u304c\\u3001\\u65b0\\u305f\\u306b\\u30b3\\u30f3\\u30c6\\u30ad\\u30b9\\u30c8\\u3092\\u52a0\\u3048\\u305f\\u3044\\u3060\\u3051\\u306e\\u5834\\u5408\\u306f\\u3001\\u65b0\\u3057\\u3044\\u30a8\\u30e9\\u30fc\\u578b\\u3092\\u4f5c\\u6210\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u306a\\u3044\\u305f\\u3081\\u3001%w \\u30c7\\u30a3\\u30ec\\u30af\\u30c6\\u30a3\\u30d6\\u3092\\u6307\\u5b9a\\u3057\\u3066 fmt.Errorf \\u3092\\u4f7f\\u7528\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002\\u305f\\u3060\\u3057\\u3001\\u30a8\\u30e9\\u30fc\\u30e9\\u30c3\\u30d4\\u30f3\\u30b0\\u306b\\u3088\\u308a\\u3001\\u547c\\u3073\\u51fa\\u3057\\u5143\\u304c\\u30bd\\u30fc\\u30b9\\u30a8\\u30e9\\u30fc\\u3092\\u5229\\u7528\\u3067\\u304d\\u308b\\u3088\\u3046\\u306b\\u306a\\u308b\\u305f\\u3081\\u3001\\u6f5c\\u5728\\u7684\\u306a\\u7d50\\u5408\\u304c\\u751f\\u3058\\u307e\\u3059\\u3002\\u305d\\u308c\\u3092\\u907f\\u3051\\u305f\\u3044\\u5834\\u5408\\u306f\\u3001\\u30a8\\u30e9\\u30fc\\u306e\\u30e9\\u30c3\\u30d4\\u30f3\\u30b0\\u3067\\u306f\\u306a\\u304f\\u3001\\u30a8\\u30e9\\u30fc\\u306e\\u5909\\u63db\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001%v \\u30c7\\u30a3\\u30ec\\u30af\\u30c6\\u30a3\\u30d6\\u3092\\u6307\\u5b9a\\u3057\\u305f fmt.Errorf \\u3092\\u4f7f\\u7528\\u3057\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#50\",\"title\":\"\\u30a8\\u30e9\\u30fc\\u578b\\u306e\\u4e0d\\u6b63\\u306a\\u6bd4\\u8f03 (#50)\",\"text\":\"\\u8981\\u7d04 <p>Go 1.13 \\u306e\\u30a8\\u30e9\\u30fc\\u30e9\\u30c3\\u30d4\\u30f3\\u30b0\\u3092 <code>%w</code> \\u30c7\\u30a3\\u30ec\\u30af\\u30c6\\u30a3\\u30d6\\u3068 <code>fmt.Errorf</code> \\u3067\\u4f7f\\u7528\\u3059\\u308b\\u5834\\u5408\\u3001\\u578b\\u306b\\u5bfe\\u3059\\u308b\\u30a8\\u30e9\\u30fc\\u306e\\u6bd4\\u8f03\\u306f <code>errors.As</code> \\u3092\\u901a\\u3058\\u3066\\u884c\\u3046\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305d\\u3046\\u3067\\u306a\\u3051\\u308c\\u3070\\u3001\\u8fd4\\u3055\\u308c\\u305f\\u30a8\\u30e9\\u30fc\\u304c\\u30e9\\u30c3\\u30d7\\u3055\\u308c\\u3066\\u3044\\u308b\\u5834\\u5408\\u3001\\u8a55\\u4fa1\\u306b\\u5931\\u6557\\u3057\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#51\",\"title\":\"\\u30a8\\u30e9\\u30fc\\u5024\\u306e\\u4e0d\\u6b63\\u306a\\u6bd4\\u8f03 (#51)\",\"text\":\"\\u8981\\u7d04 <p>Go 1.13 \\u306e\\u30a8\\u30e9\\u30fc\\u30e9\\u30c3\\u30d4\\u30f3\\u30b0\\u3092 <code>%w</code> \\u30c7\\u30a3\\u30ec\\u30af\\u30c6\\u30a3\\u30d6\\u3068 <code>fmt.Errorf</code> \\u3067\\u4f7f\\u7528\\u3059\\u308b\\u5834\\u5408\\u3001\\u30a8\\u30e9\\u30fc\\u3068\\u5024\\u306e\\u6bd4\\u8f03\\u306f <code>errors.As</code> \\u3092\\u901a\\u3058\\u3066\\u884c\\u3046\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305d\\u3046\\u3067\\u306a\\u3051\\u308c\\u3070\\u3001\\u8fd4\\u3055\\u308c\\u305f\\u30a8\\u30e9\\u30fc\\u304c\\u30e9\\u30c3\\u30d7\\u3055\\u308c\\u3066\\u3044\\u308b\\u5834\\u5408\\u3001\\u8a55\\u4fa1\\u306b\\u5931\\u6557\\u3057\\u307e\\u3059\\u3002 </p> <p>\\u30bb\\u30f3\\u30c1\\u30cd\\u30eb\\u30a8\\u30e9\\u30fc\\u306f\\u30b0\\u30ed\\u30fc\\u30d0\\u30eb\\u5909\\u6570\\u3068\\u3057\\u3066\\u5b9a\\u7fa9\\u3055\\u308c\\u305f\\u30a8\\u30e9\\u30fc\\u306e\\u3053\\u3068\\u3067\\u3059\\u3002</p> <p></p><pre><code>import \\\"errors\\\"\\n\\nvar ErrFoo = errors.New(\\\"foo\\\")\\n</code></pre> \\u4e00\\u822c\\u306b\\u3001\\u6163\\u4f8b\\u3068\\u3057\\u3066 <code>Err</code> \\u3067\\u59cb\\u3081\\u3001\\u305d\\u306e\\u5f8c\\u306b\\u30a8\\u30e9\\u30fc\\u578b\\u3092\\u7d9a\\u3051\\u307e\\u3059\\u3002\\u3053\\u3053\\u3067\\u306f <code>ErrFoo</code> \\u3067\\u3059\\u3002\\u30bb\\u30f3\\u30c1\\u30cd\\u30eb\\u30a8\\u30e9\\u30fc\\u306f\\u3001\\u4e88\\u671f\\u3055\\u308c\\u308b \\u30a8\\u30e9\\u30fc\\u3001\\u3064\\u307e\\u308a\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u304c\\u78ba\\u8a8d\\u3059\\u308b\\u3053\\u3068\\u3092\\u671f\\u5f85\\u3059\\u308b\\u30a8\\u30e9\\u30fc\\u3092\\u4f1d\\u3048\\u307e\\u3059\\u3002\\u4e00\\u822c\\u7684\\u306a\\u30ac\\u30a4\\u30c9\\u30e9\\u30a4\\u30f3\\u3068\\u3057\\u3066<p></p> <ul> <li>\\u4e88\\u671f\\u3055\\u308c\\u308b\\u30a8\\u30e9\\u30fc\\u306f\\u30a8\\u30e9\\u30fc\\u5024\\uff08\\u30bb\\u30f3\\u30c1\\u30cd\\u30eb\\u30a8\\u30e9\\u30fc\\uff09\\u3068\\u3057\\u3066\\u8a2d\\u8a08\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\uff1a <code>var ErrFoo =errors.New(\\\"foo\\\")</code>\\u3002 </li> <li>\\u4e88\\u671f\\u3057\\u306a\\u3044\\u30a8\\u30e9\\u30fc\\u306f\\u30a8\\u30e9\\u30fc\\u578b\\u3068\\u3057\\u3066\\u8a2d\\u8a08\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\uff1a <code>BarError</code> \\u306f <code>error</code> \\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3092\\u5b9f\\u88c5\\u3057\\u305f\\u4e0a\\u3067 <code>type BarError struct { ... }</code>\\u3002 </li> </ul> <p>\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3067 <code>%w</code> \\u30c7\\u30a3\\u30ec\\u30af\\u30c6\\u30a3\\u30d6\\u3068 <code>fmt.Errorf</code> \\u3092\\u4f7f\\u7528\\u3057\\u3066\\u30a8\\u30e9\\u30fc\\u30e9\\u30c3\\u30d7\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u5834\\u5408\\u3001\\u7279\\u5b9a\\u306e\\u5024\\u306b\\u5bfe\\u3059\\u308b\\u30a8\\u30e9\\u30fc\\u306e\\u30c1\\u30a7\\u30c3\\u30af\\u306f <code>==</code> \\u306e\\u4ee3\\u308f\\u308a\\u306b <code>errors.Is</code> \\u3092\\u4f7f\\u7528\\u3057\\u3066\\u884c\\u3044\\u307e\\u3057\\u3087\\u3046\\u3002\\u305d\\u308c\\u306b\\u3088\\u3063\\u3066\\u3001\\u30bb\\u30f3\\u30c1\\u30cd\\u30eb\\u30a8\\u30e9\\u30fc\\u304c\\u30e9\\u30c3\\u30d7\\u3055\\u308c\\u3066\\u3044\\u308b\\u5834\\u5408\\u3067\\u3082\\u3001<code>errors.Is</code> \\u306f\\u305d\\u308c\\u3092\\u518d\\u5e30\\u7684\\u306b\\u30a2\\u30f3\\u30e9\\u30c3\\u30d7\\u3057\\u3001\\u30c1\\u30a7\\u30fc\\u30f3\\u5185\\u306e\\u5404\\u30a8\\u30e9\\u30fc\\u3092\\u63d0\\u4f9b\\u3055\\u308c\\u305f\\u5024\\u3068\\u6bd4\\u8f03\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#2-52\",\"title\":\"\\u30a8\\u30e9\\u30fc\\u306e 2 \\u56de\\u51e6\\u7406 (#52)\",\"text\":\"\\u8981\\u7d04 <p>\\u307b\\u3068\\u3093\\u3069\\u306e\\u5834\\u5408\\u3001\\u30a8\\u30e9\\u30fc\\u306f 1 \\u56de\\u3067\\u51e6\\u7406\\u3055\\u308c\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002\\u30a8\\u30e9\\u30fc\\u3092\\u30ed\\u30b0\\u306b\\u8a18\\u9332\\u3059\\u308b\\u3053\\u3068\\u306f\\u3001\\u30a8\\u30e9\\u30fc\\u3092\\u51e6\\u7406\\u3059\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002\\u3059\\u306a\\u308f\\u3061\\u3001\\u30ed\\u30b0\\u306b\\u8a18\\u9332\\u3059\\u308b\\u304b\\u30a8\\u30e9\\u30fc\\u3092\\u8fd4\\u3059\\u304b\\u3092\\u9078\\u629e\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u591a\\u304f\\u306e\\u5834\\u5408\\u3001\\u30a8\\u30e9\\u30fc\\u30e9\\u30c3\\u30d4\\u30f3\\u30b0\\u306f\\u3001\\u30a8\\u30e9\\u30fc\\u306b\\u8ffd\\u52a0\\u306e\\u30b3\\u30f3\\u30c6\\u30ad\\u30b9\\u30c8\\u3092\\u63d0\\u4f9b\\u3057\\u3001\\u30bd\\u30fc\\u30b9\\u30a8\\u30e9\\u30fc\\u3092\\u8fd4\\u3059\\u3053\\u3068\\u304c\\u3067\\u304d\\u308b\\u305f\\u3081\\u3001\\u89e3\\u6c7a\\u7b56\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002 </p> <p>\\u30a8\\u30e9\\u30fc\\u3092\\u8907\\u6570\\u56de\\u51e6\\u7406\\u3059\\u308b\\u3053\\u3068\\u306f\\u3001\\u7279\\u306bGo\\u8a00\\u8a9e\\u306b\\u9650\\u3089\\u305a\\u3001\\u958b\\u767a\\u8005\\u304c\\u983b\\u7e41\\u306b\\u3084\\u3063\\u3066\\u3057\\u307e\\u3046\\u30df\\u30b9\\u3067\\u3059\\u3002\\u3053\\u308c\\u306b\\u3088\\u308a\\u3001\\u540c\\u3058\\u30a8\\u30e9\\u30fc\\u304c\\u8907\\u6570\\u56de\\u30ed\\u30b0\\u306b\\u8a18\\u9332\\u3055\\u308c\\u3001\\u30c7\\u30d0\\u30c3\\u30b0\\u304c\\u56f0\\u96e3\\u306b\\u306a\\u308b\\u72b6\\u6cc1\\u304c\\u767a\\u751f\\u3059\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002 </p> <p>\\u30a8\\u30e9\\u30fc\\u51e6\\u7406\\u306f 1 \\u5ea6\\u3067\\u6e08\\u307e\\u3059\\u3079\\u304d\\u3060\\u3068\\u3044\\u3046\\u3053\\u3068\\u3092\\u899a\\u3048\\u3066\\u304a\\u304d\\u307e\\u3057\\u3087\\u3046\\u3002\\u30a8\\u30e9\\u30fc\\u3092\\u30ed\\u30b0\\u306b\\u8a18\\u9332\\u3059\\u308b\\u3053\\u3068\\u306f\\u3001\\u30a8\\u30e9\\u30fc\\u3092\\u51e6\\u7406\\u3059\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002\\u3064\\u307e\\u308a\\u3001\\u884c\\u3046\\u3079\\u304d\\u306f\\u3001\\u30ed\\u30b0\\u306b\\u8a18\\u9332\\u3059\\u308b\\u304b\\u3001\\u30a8\\u30e9\\u30fc\\u3092\\u8fd4\\u3059\\u304b\\u306e\\u3069\\u3061\\u3089\\u304b\\u3060\\u3068\\u3044\\u3046\\u3053\\u3068\\u3067\\u3059\\u3002\\u3053\\u308c\\u306b\\u3088\\u308a\\u3001\\u30b3\\u30fc\\u30c9\\u304c\\u7c21\\u7d20\\u5316\\u3055\\u308c\\u3001\\u30a8\\u30e9\\u30fc\\u306e\\u72b6\\u6cc1\\u306b\\u3064\\u3044\\u3066\\u3088\\u308a\\u9069\\u5207\\u306a\\u6d1e\\u5bdf\\u304c\\u5f97\\u3089\\u308c\\u307e\\u3059\\u3002\\u30a8\\u30e9\\u30fc\\u30e9\\u30c3\\u30d4\\u30f3\\u30b0\\u306f\\u3001\\u30bd\\u30fc\\u30b9\\u30a8\\u30e9\\u30fc\\u3092\\u4f1d\\u3048\\u3001\\u30a8\\u30e9\\u30fc\\u306b\\u30b3\\u30f3\\u30c6\\u30ad\\u30b9\\u30c8\\u3092\\u8ffd\\u52a0\\u3067\\u304d\\u308b\\u305f\\u3081\\u3001\\u6700\\u3082\\u4f7f\\u3044\\u52dd\\u624b\\u306e\\u826f\\u3044\\u624b\\u6bb5\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#53\",\"title\":\"\\u30a8\\u30e9\\u30fc\\u51e6\\u7406\\u3092\\u3057\\u306a\\u3044 (#53)\",\"text\":\"\\u8981\\u7d04 <p>\\u95a2\\u6570\\u547c\\u3073\\u51fa\\u3057\\u4e2d\\u3067\\u3042\\u3063\\u3066\\u3082\\u3001<code>defer</code> \\u95a2\\u6570\\u5185\\u3067\\u3042\\u3063\\u3066\\u3082\\u3001\\u30a8\\u30e9\\u30fc\\u3092\\u7121\\u8996\\u3059\\u308b\\u3068\\u304d\\u306f\\u3001\\u30d6\\u30e9\\u30f3\\u30af\\u8b58\\u5225\\u5b50\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u660e\\u78ba\\u306b\\u884c\\u3046\\u3079\\u304d\\u3067\\u3059\\u3002\\u305d\\u3046\\u3057\\u306a\\u3044\\u3068\\u3001\\u5c06\\u6765\\u306e\\u8aad\\u307f\\u624b\\u304c\\u305d\\u308c\\u304c\\u610f\\u56f3\\u7684\\u3060\\u3063\\u305f\\u306e\\u304b\\u3001\\u305d\\u308c\\u3068\\u3082\\u30df\\u30b9\\u3060\\u3063\\u305f\\u306e\\u304b\\u56f0\\u60d1\\u3059\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#defer-54\",\"title\":\"<code>defer</code> \\u30a8\\u30e9\\u30fc\\u3092\\u51e6\\u7406\\u3057\\u306a\\u3044 (#54)\",\"text\":\"\\u8981\\u7d04 <p>\\u591a\\u304f\\u306e\\u5834\\u5408\\u3001<code>defer</code> \\u95a2\\u6570\\u306b\\u3088\\u3063\\u3066\\u8fd4\\u3055\\u308c\\u308b\\u30a8\\u30e9\\u30fc\\u3092\\u7121\\u8996\\u3059\\u3079\\u304d\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u72b6\\u6cc1\\u306b\\u5fdc\\u3058\\u3066\\u3001\\u76f4\\u63a5\\u51e6\\u7406\\u3059\\u308b\\u304b\\u3001\\u547c\\u3073\\u51fa\\u3057\\u5143\\u306b\\u4f1d\\u3048\\u307e\\u3057\\u3087\\u3046\\u3002\\u3053\\u308c\\u3092\\u7121\\u8996\\u3059\\u308b\\u5834\\u5408\\u306f\\u3001\\u30d6\\u30e9\\u30f3\\u30af\\u8b58\\u5225\\u5b50\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002 </p> <p>\\u6b21\\u306e\\u30b3\\u30fc\\u30c9\\u3092\\u8003\\u3048\\u3066\\u307f\\u307e\\u3057\\u3087\\u3046\\u3002</p> <pre><code>func f() {\\n  // ...\\n  notify() // \\u30a8\\u30e9\\u30fc\\u51e6\\u7406\\u306f\\u7701\\u7565\\u3055\\u308c\\u3066\\u3044\\u307e\\u3059\\n}\\n\\nfunc notify() error {\\n  // ...\\n}\\n</code></pre> <p>\\u4fdd\\u5b88\\u6027\\u306e\\u89b3\\u70b9\\u304b\\u3089\\u3001\\u3053\\u306e\\u30b3\\u30fc\\u30c9\\u306f\\u3044\\u304f\\u3064\\u304b\\u306e\\u554f\\u984c\\u3092\\u5f15\\u304d\\u8d77\\u3053\\u3059\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3042\\u308b\\u4eba\\u304c\\u3053\\u308c\\u3092\\u8aad\\u3080\\u3053\\u3068\\u3092\\u8003\\u3048\\u3066\\u307f\\u307e\\u3059\\u3002\\u8aad\\u307f\\u624b\\u306f\\u3001notify \\u304c\\u30a8\\u30e9\\u30fc\\u3092\\u8fd4\\u3059\\u306b\\u3082\\u304b\\u304b\\u308f\\u3089\\u305a\\u3001\\u305d\\u306e\\u30a8\\u30e9\\u30fc\\u304c\\u89aa\\u95a2\\u6570\\u306b\\u3088\\u3063\\u3066\\u51e6\\u7406\\u3055\\u308c\\u306a\\u3044\\u3053\\u3068\\u306b\\u6c17\\u3065\\u304d\\u307e\\u3059\\u3002\\u30a8\\u30e9\\u30fc\\u51e6\\u7406\\u304c\\u610f\\u56f3\\u7684\\u3067\\u3042\\u308b\\u304b\\u3069\\u3046\\u304b\\u3092\\u679c\\u305f\\u3057\\u3066\\u63a8\\u6e2c\\u3067\\u304d\\u308b\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002\\u4ee5\\u524d\\u306e\\u958b\\u767a\\u8005\\u304c\\u305d\\u308c\\u3092\\u51e6\\u7406\\u3059\\u308b\\u306e\\u3092\\u5fd8\\u308c\\u305f\\u306e\\u304b\\u3001\\u305d\\u308c\\u3068\\u3082\\u610f\\u56f3\\u7684\\u306b\\u51e6\\u7406\\u3057\\u305f\\u306e\\u304b\\u3092\\u77e5\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u308b\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002</p> <p>\\u3053\\u308c\\u3089\\u306e\\u7406\\u7531\\u306b\\u3088\\u308a\\u3001\\u30a8\\u30e9\\u30fc\\u3092\\u7121\\u8996\\u3057\\u305f\\u3044\\u5834\\u5408\\u3001\\u30d6\\u30e9\\u30f3\\u30af\\u8b58\\u5225\\u5b50\\uff08 <code>_</code> \\uff09\\u3092\\u4f7f\\u3046\\u307b\\u304b\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002</p> <pre><code>_ = notify\\n</code></pre> <p>\\u30b3\\u30f3\\u30d1\\u30a4\\u30eb\\u3068\\u5b9f\\u884c\\u6642\\u9593\\u306e\\u70b9\\u3067\\u306f\\u3001\\u3053\\u306e\\u65b9\\u6cd5\\u306f\\u6700\\u521d\\u306e\\u30b3\\u30fc\\u30c9\\u90e8\\u5206\\u3068\\u6bd4\\u3079\\u3066\\u4f55\\u3082\\u5909\\u308f\\u308a\\u307e\\u305b\\u3093\\u3002\\u3057\\u304b\\u3057\\u3001\\u3053\\u306e\\u65b0\\u3057\\u3044\\u30d0\\u30fc\\u30b8\\u30e7\\u30f3\\u3067\\u306f\\u3001\\u79c1\\u305f\\u3061\\u304c\\u30a8\\u30e9\\u30fc\\u306b\\u95a2\\u5fc3\\u304c\\u306a\\u3044\\u3053\\u3068\\u3092\\u660e\\u3089\\u304b\\u306b\\u3057\\u3066\\u3044\\u307e\\u3059\\u3002\\u307e\\u305f\\u3001\\u30a8\\u30e9\\u30fc\\u304c\\u7121\\u8996\\u3055\\u308c\\u308b\\u7406\\u7531\\u3092\\u793a\\u3059\\u30b3\\u30e1\\u30f3\\u30c8\\u3092\\u8ffd\\u52a0\\u3059\\u308b\\u3053\\u3068\\u3082\\u3067\\u304d\\u307e\\u3059\\u3002</p> <pre><code>// \\u6700\\u5927\\u3067\\u3082 1 \\u56de\\u306e\\u4f1d\\u9054 \\n// \\u305d\\u308c\\u3086\\u3048\\u3001\\u30a8\\u30e9\\u30fc\\u304c\\u767a\\u751f\\u3057\\u305f\\u5834\\u5408\\u306b\\u305d\\u308c\\u3089\\u306e\\u4e00\\u90e8\\u304c\\u5931\\u308f\\u308c\\u308b\\u3053\\u3068\\u306f\\u8a31\\u5bb9\\u3055\\u308c\\u307e\\u3059\\n_ = notify()\\n</code></pre> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#_9\",\"title\":\"\\u4e26\\u884c\\u51e6\\u7406\\uff1a\\u57fa\\u790e\",\"text\":\"\"},{\"location\":\"ja/#55\",\"title\":\"\\u4e26\\u884c\\u51e6\\u7406\\u3068\\u4e26\\u5217\\u51e6\\u7406\\u306e\\u6df7\\u540c (#55)\",\"text\":\"\\u8981\\u7d04 <p>\\u4e26\\u884c\\u51e6\\u7406\\u3068\\u4e26\\u5217\\u51e6\\u7406\\u306e\\u57fa\\u672c\\u7684\\u306a\\u9055\\u3044\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3053\\u3068\\u306f\\u3001 Go \\u958b\\u767a\\u8005\\u306b\\u3068\\u3063\\u3066\\u5fc5\\u9808\\u3067\\u3059\\u3002\\u4e26\\u884c\\u51e6\\u7406\\u306f\\u69cb\\u9020\\u306b\\u95a2\\u3059\\u308b\\u3082\\u306e\\u3067\\u3059\\u304c\\u3001\\u4e26\\u5217\\u51e6\\u7406\\u306f\\u5b9f\\u884c\\u306b\\u95a2\\u3059\\u308b\\u3082\\u306e\\u3067\\u3059\\u3002 </p> <p>\\u4e26\\u884c\\u51e6\\u7406\\u3068\\u4e26\\u5217\\u51e6\\u7406\\u306f\\u540c\\u3058\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002 </p> <ul> <li>\\u4e26\\u884c\\u51e6\\u7406\\u306f\\u69cb\\u9020\\u306b\\u95a2\\u3059\\u308b\\u3082\\u306e\\u3067\\u3059\\u3002\\u5225\\u3005\\u306e\\u4e26\\u884c\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u304c\\u53d6\\u308a\\u7d44\\u3080\\u3053\\u3068\\u304c\\u3067\\u304d\\u308b\\u3055\\u307e\\u3056\\u307e\\u306a\\u6bb5\\u968e\\u3092\\u5c0e\\u5165\\u3059\\u308b\\u3053\\u3068\\u3067\\u3001\\u9010\\u6b21\\u51e6\\u7406\\u3092\\u4e26\\u884c\\u51e6\\u7406\\u306b\\u5909\\u66f4\\u3067\\u304d\\u307e\\u3059\\u3002 </li> <li>\\u4e26\\u5217\\u51e6\\u7406\\u306f\\u5b9f\\u884c\\u306b\\u95a2\\u3059\\u308b\\u3082\\u306e\\u3067\\u3059\\u3002\\u4e26\\u5217\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3092\\u3055\\u3089\\u306b\\u8ffd\\u52a0\\u3059\\u308b\\u3053\\u3068\\u3067\\u3001\\u6bb5\\u968e\\u30ec\\u30d9\\u30eb\\u3067\\u4e26\\u5217\\u51e6\\u7406\\u3092\\u4f7f\\u7528\\u3067\\u304d\\u307e\\u3059\\u3002 </li> </ul> <p>\\u307e\\u3068\\u3081\\u308b\\u3068\\u3001\\u4e26\\u884c\\u51e6\\u7406\\u306f\\u3001\\u4e26\\u5217\\u5316\\u3067\\u304d\\u308b\\u90e8\\u5206\\u3092\\u3082\\u3064\\u554f\\u984c\\u3092\\u89e3\\u6c7a\\u3059\\u308b\\u305f\\u3081\\u306e\\u69cb\\u9020\\u3092\\u63d0\\u4f9b\\u3057\\u307e\\u3059\\u3002\\u3059\\u306a\\u308f\\u3061\\u3001\\u4e26\\u884c\\u51e6\\u7406\\u306b\\u3088\\u308a\\u4e26\\u5217\\u51e6\\u7406\\u304c\\u53ef\\u80fd \\u306b\\u306a\\u308a\\u307e\\u3059 \\u3002</p>\"},{\"location\":\"ja/#56\",\"title\":\"\\u4e26\\u884c\\u51e6\\u7406\\u306e\\u307b\\u3046\\u304c\\u5e38\\u306b\\u65e9\\u3044\\u3068\\u8003\\u3048\\u3066\\u3044\\u308b (#56)\",\"text\":\"\\u8981\\u7d04 <p>\\u719f\\u7df4\\u3057\\u305f\\u958b\\u767a\\u8005\\u306b\\u306a\\u308b\\u306b\\u306f\\u3001\\u4e26\\u884c\\u51e6\\u7406\\u304c\\u5fc5\\u305a\\u3057\\u3082\\u9ad8\\u901f\\u3067\\u3042\\u308b\\u3068\\u306f\\u9650\\u3089\\u306a\\u3044\\u3053\\u3068\\u3092\\u8a8d\\u8b58\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u6700\\u5c0f\\u9650\\u306e\\u30ef\\u30fc\\u30af\\u30ed\\u30fc\\u30c9\\u306e\\u4e26\\u5217\\u51e6\\u7406\\u3092\\u4f34\\u3046\\u89e3\\u6c7a\\u7b56\\u306f\\u3001\\u5fc5\\u305a\\u3057\\u3082\\u9010\\u6b21\\u51e6\\u7406\\u3088\\u308a\\u9ad8\\u901f\\u3067\\u3042\\u308b\\u3068\\u306f\\u9650\\u308a\\u307e\\u305b\\u3093\\u3002\\u9010\\u6b21\\u51e6\\u7406\\u3068\\u4e26\\u884c\\u51e6\\u7406\\u306e\\u30d9\\u30f3\\u30c1\\u30de\\u30fc\\u30af\\u306f\\u3001\\u4eee\\u5b9a\\u3092\\u691c\\u8a3c\\u3059\\u308b\\u65b9\\u6cd5\\u3067\\u3042\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002</p> <p>\\u30bb\\u30af\\u30b7\\u30e7\\u30f3\\u5168\\u6587\\u306f\\u3053\\u3061\\u3089\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#57\",\"title\":\"\\u30c1\\u30e3\\u30cd\\u30eb\\u307e\\u305f\\u306f\\u30df\\u30e5\\u30fc\\u30c6\\u30c3\\u30af\\u30b9\\u3092\\u3044\\u3064\\u4f7f\\u7528\\u3059\\u308b\\u3079\\u304d\\u304b\\u306b\\u3064\\u3044\\u3066\\u6238\\u60d1\\u3063\\u3066\\u3044\\u308b (#57)\",\"text\":\"\\u8981\\u7d04 <p>\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306e\\u76f8\\u4e92\\u4f5c\\u7528\\u3092\\u8a8d\\u8b58\\u3057\\u3066\\u3044\\u308b\\u3053\\u3068\\u306f\\u3001\\u30c1\\u30e3\\u30cd\\u30eb\\u3068\\u30df\\u30e5\\u30fc\\u30c6\\u30c3\\u30af\\u30b9\\u306e\\u3069\\u3061\\u3089\\u3092\\u9078\\u629e\\u3059\\u308b\\u304b\\u3092\\u6c7a\\u5b9a\\u3059\\u308b\\u3068\\u304d\\u306b\\u3082\\u5f79\\u7acb\\u3061\\u307e\\u3059\\u3002\\u4e00\\u822c\\u306b\\u3001\\u4e26\\u5217\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306b\\u306f\\u540c\\u671f\\u304c\\u5fc5\\u8981\\u3067\\u3042\\u308a\\u3001\\u3057\\u305f\\u304c\\u3063\\u3066\\u30df\\u30e5\\u30fc\\u30c6\\u30c3\\u30af\\u30b9\\u304c\\u5fc5\\u8981\\u3067\\u3059\\u3002\\u53cd\\u5bfe\\u306b\\u3001\\u4e26\\u884c\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306f\\u901a\\u5e38\\u3001\\u8abf\\u6574\\u3068\\u30aa\\u30fc\\u30b1\\u30b9\\u30c8\\u30ec\\u30fc\\u30b7\\u30e7\\u30f3\\u3001\\u3064\\u307e\\u308a\\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u5fc5\\u8981\\u3068\\u3057\\u307e\\u3059\\u3002 </p> <p>\\u4e26\\u884c\\u51e6\\u7406\\u306e\\u554f\\u984c\\u3092\\u8003\\u616e\\u3059\\u308b\\u3068\\u3001\\u30c1\\u30e3\\u30cd\\u30eb\\u307e\\u305f\\u306f\\u30df\\u30e5\\u30fc\\u30c6\\u30c3\\u30af\\u30b9\\u3092\\u4f7f\\u7528\\u3057\\u305f\\u89e3\\u6c7a\\u7b56\\u3092\\u5b9f\\u88c5\\u3067\\u304d\\u308b\\u304b\\u3069\\u3046\\u304b\\u304c\\u5fc5\\u305a\\u3057\\u3082\\u660e\\u78ba\\u3067\\u306f\\u306a\\u3044\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002Go\\u8a00\\u8a9e\\u306f\\u901a\\u4fe1\\u306b\\u3088\\u308b\\u30e1\\u30e2\\u30ea\\u306e\\u5171\\u6709\\u3092\\u4fc3\\u9032\\u3059\\u308b\\u305f\\u3081\\u3001\\u8d77\\u3053\\u308a\\u3046\\u308b\\u9593\\u9055\\u3044\\u306e\\u3046\\u3061\\u306e\\u4e00\\u3064\\u306f\\u3001\\u30e6\\u30fc\\u30b9\\u30b1\\u30fc\\u30b9\\u306b\\u304b\\u304b\\u308f\\u3089\\u305a\\u3001\\u30c1\\u30e3\\u30cd\\u30eb\\u306e\\u4f7f\\u7528\\u3092\\u5e38\\u306b\\u5f37\\u5236\\u3059\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002\\u3057\\u304b\\u3057\\u306a\\u304c\\u3089\\u30012 \\u3064\\u306e\\u65b9\\u6cd5\\u306f\\u88dc\\u5b8c\\u7684\\u306a\\u3082\\u306e\\u3067\\u3042\\u308b\\u3068\\u898b\\u306a\\u3059\\u3079\\u304d\\u3067\\u3059\\u3002  </p> <p>\\u30c1\\u30e3\\u30cd\\u30eb\\u307e\\u305f\\u306f\\u30df\\u30e5\\u30fc\\u30c6\\u30c3\\u30af\\u30b9\\u306f\\u3069\\u306e\\u3088\\u3046\\u306a\\u5834\\u5408\\u306b\\u4f7f\\u7528\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u306e\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002\\u6b21\\u306e\\u56f3\\u306e\\u4f8b\\u3092\\u30d0\\u30c3\\u30af\\u30dc\\u30fc\\u30f3\\u3068\\u3057\\u3066\\u4f7f\\u7528\\u3057\\u307e\\u3059\\u3002\\u3053\\u306e\\u4f8b\\u306b\\u306f\\u3001\\u7279\\u5b9a\\u306e\\u95a2\\u4fc2\\u3092\\u6301\\u3064 3 \\u3064\\u306e\\u7570\\u306a\\u308b\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002 </p> <ul> <li>G1 \\u3068 G2 \\u306f\\u4e26\\u5217\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3067\\u3059\\u3002\\u30c1\\u30e3\\u30cd\\u30eb\\u304b\\u3089\\u30e1\\u30c3\\u30bb\\u30fc\\u30b8\\u3092\\u53d7\\u4fe1\\u3057\\u7d9a\\u3051\\u308b\\u540c\\u3058\\u95a2\\u6570\\u3092\\u5b9f\\u884c\\u3059\\u308b 2 \\u3064\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3001\\u3042\\u308b\\u3044\\u306f\\u540c\\u3058 HTTP \\u30cf\\u30f3\\u30c9\\u30e9\\u3092\\u540c\\u6642\\u306b\\u5b9f\\u884c\\u3059\\u308b 2 \\u3064\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u304b\\u3082\\u3057\\u308c\\u307e\\u305b\\u3093\\u3002 </li> <li>G1 \\u3068 G3 \\u306f\\u4e26\\u884c\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3067\\u3042\\u308a\\u3001G2 \\u3068 G3 \\u3082\\u540c\\u69d8\\u3067\\u3059\\u3002\\u3059\\u3079\\u3066\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306f\\u5168\\u4f53\\u306e\\u4e26\\u884c\\u69cb\\u9020\\u306e\\u4e00\\u90e8\\u3067\\u3059\\u304c\\u3001G1 \\u3068 G2 \\u304c\\u6700\\u521d\\u306e\\u30b9\\u30c6\\u30c3\\u30d7\\u3092\\u5b9f\\u884c\\u3057\\u3001G3 \\u304c\\u6b21\\u306e\\u30b9\\u30c6\\u30c3\\u30d7\\u3092\\u5b9f\\u884c\\u3057\\u307e\\u3059\\u3002 </li> </ul> <p>\\u539f\\u5247\\u3068\\u3057\\u3066\\u3001\\u4e26\\u5217\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306f\\u3001\\u30b9\\u30e9\\u30a4\\u30b9\\u306a\\u3069\\u306e\\u5171\\u6709\\u30ea\\u30bd\\u30fc\\u30b9\\u306b\\u30a2\\u30af\\u30bb\\u30b9\\u3057\\u305f\\u308a\\u5909\\u66f4\\u3057\\u305f\\u308a\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u5834\\u5408\\u306a\\u3069\\u306b\\u3001_\\u540c\\u671f_\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u540c\\u671f\\u306f\\u30df\\u30e5\\u30fc\\u30c6\\u30c3\\u30af\\u30b9\\u3067\\u306f\\u5f37\\u5236\\u3055\\u308c\\u307e\\u3059\\u304c\\u3001\\u3069\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u578b\\u3067\\u3082\\u5f37\\u5236\\u3055\\u308c\\u307e\\u305b\\u3093\\uff08\\u30d0\\u30c3\\u30d5\\u30a1\\u3042\\u308a\\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u9664\\u304f\\uff09\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u4e00\\u822c\\u306b\\u3001\\u4e26\\u5217\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u9593\\u306e\\u540c\\u671f\\u306f\\u30df\\u30e5\\u30fc\\u30c6\\u30c3\\u30af\\u30b9\\u3092\\u4ecb\\u3057\\u3066\\u9054\\u6210\\u3055\\u308c\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002 </p> <p>\\u4e00\\u65b9\\u3001\\u4e00\\u822c\\u306b\\u3001\\u4e26\\u884c\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306f \\u8abf\\u6574\\u304a\\u3088\\u3073\\u30aa\\u30fc\\u30b1\\u30b9\\u30c8\\u30ec\\u30fc\\u30b7\\u30e7\\u30f3 \\u3092\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001G3 \\u304c G1 \\u3068 G2 \\u306e\\u4e21\\u65b9\\u304b\\u3089\\u306e\\u7d50\\u679c\\u3092\\u96c6\\u7d04\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u5834\\u5408\\u3001G1 \\u3068 G2 \\u306f\\u65b0\\u3057\\u3044\\u4e2d\\u9593\\u7d50\\u679c\\u304c\\u5229\\u7528\\u53ef\\u80fd\\u3067\\u3042\\u308b\\u3053\\u3068\\u3092 G3 \\u306b\\u901a\\u77e5\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3053\\u306e\\u8abf\\u6574\\u306f\\u30b3\\u30df\\u30e5\\u30cb\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u306e\\u7bc4\\u56f2\\u3001\\u3064\\u307e\\u308a\\u30c1\\u30e3\\u30cd\\u30eb\\u306b\\u8a72\\u5f53\\u3057\\u307e\\u3059\\u3002 </p> <p>\\u4e26\\u884c\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306b\\u95a2\\u3057\\u3066\\u306f\\u3001\\u30ea\\u30bd\\u30fc\\u30b9\\u306e\\u6240\\u6709\\u6a29\\u3092\\u3042\\u308b\\u30b9\\u30c6\\u30c3\\u30d7\\uff08G1 \\u304a\\u3088\\u3073 G2\\uff09\\u304b\\u3089\\u5225\\u306e\\u30b9\\u30c6\\u30c3\\u30d7\\uff08G3\\uff09\\u306b\\u79fb\\u7ba1\\u3057\\u305f\\u3044\\u5834\\u5408\\u3082\\u3042\\u308a\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001G1 \\u3068 G2 \\u306b\\u3088\\u3063\\u3066\\u5171\\u6709\\u30ea\\u30bd\\u30fc\\u30b9\\u304c\\u8c4a\\u304b\\u306b\\u306a\\u3063\\u3066\\u3044\\u308b\\u5834\\u5408\\u3001\\u3042\\u308b\\u6642\\u70b9\\u3067\\u3053\\u306e\\u30b8\\u30e7\\u30d6\\u306f\\u5b8c\\u4e86\\u3057\\u305f\\u3068\\u898b\\u306a\\u3055\\u308c\\u307e\\u3059\\u3002\\u3053\\u3053\\u3067\\u306f\\u3001\\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3001\\u7279\\u5b9a\\u306e\\u30ea\\u30bd\\u30fc\\u30b9\\u306e\\u6e96\\u5099\\u304c\\u3067\\u304d\\u3066\\u3044\\u308b\\u3053\\u3068\\u3092\\u901a\\u77e5\\u3057\\u3001\\u6240\\u6709\\u6a29\\u306e\\u79fb\\u8ee2\\u3092\\u51e6\\u7406\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002 </p> <p>\\u30df\\u30e5\\u30fc\\u30c6\\u30c3\\u30af\\u30b9\\u3068\\u30c1\\u30e3\\u30cd\\u30eb\\u306b\\u306f\\u7570\\u306a\\u308b\\u30bb\\u30de\\u30f3\\u30c6\\u30a3\\u30af\\u30b9\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u30b9\\u30c6\\u30fc\\u30c8\\u3092\\u5171\\u6709\\u3057\\u305f\\u3044\\u3068\\u304d\\u3001\\u307e\\u305f\\u306f\\u5171\\u6709\\u30ea\\u30bd\\u30fc\\u30b9\\u306b\\u30a2\\u30af\\u30bb\\u30b9\\u3057\\u305f\\u3044\\u3068\\u304d\\u306f\\u3001\\u30df\\u30e5\\u30fc\\u30c6\\u30c3\\u30af\\u30b9\\u306b\\u3088\\u3063\\u3066\\u3053\\u306e\\u30ea\\u30bd\\u30fc\\u30b9\\u3078\\u306e\\u6392\\u4ed6\\u7684\\u30a2\\u30af\\u30bb\\u30b9\\u304c\\u4fdd\\u8a3c\\u3055\\u308c\\u307e\\u3059\\u3002\\u53cd\\u5bfe\\u306b\\u3001\\u30c1\\u30e3\\u30cd\\u30eb\\u306f\\u30c7\\u30fc\\u30bf\\u306e\\u6709\\u7121\\uff08<code>chan struct{}</code> \\u306e\\u6709\\u7121\\uff09\\u306b\\u95a2\\u4fc2\\u306a\\u304f\\u30b7\\u30b0\\u30ca\\u30eb\\u3092\\u884c\\u3046\\u4ed5\\u7d44\\u307f\\u3067\\u3059\\u3002\\u8abf\\u6574\\u3084\\u6240\\u6709\\u6a29\\u306e\\u79fb\\u8ee2\\u306f\\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u901a\\u3058\\u3066\\u884c\\u3046\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u304c\\u4e26\\u5217\\u304b\\u4e26\\u884c\\u304b\\u3092\\u77e5\\u308b\\u3053\\u3068\\u304c\\u91cd\\u8981\\u3067\\u3059\\u3002\\u4e00\\u822c\\u306b\\u3001\\u4e26\\u5217\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306b\\u306f\\u30df\\u30e5\\u30fc\\u30c6\\u30c3\\u30af\\u30b9\\u304c\\u5fc5\\u8981\\u3067\\u3001\\u4e26\\u884c\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306b\\u306f\\u30c1\\u30e3\\u30cd\\u30eb\\u304c\\u5fc5\\u8981\\u3067\\u3059\\u3002</p>\"},{\"location\":\"ja/#go-58\",\"title\":\"\\u7af6\\u5408\\u554f\\u984c\\u3092\\u7406\\u89e3\\u3057\\u3066\\u3044\\u306a\\u3044\\uff08\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u3068\\u7af6\\u5408\\u72b6\\u614b\\u3001\\u305d\\u3057\\u3066Go\\u8a00\\u8a9e\\u306e\\u30e1\\u30e2\\u30ea\\u30e2\\u30c7\\u30eb\\uff09 (#58)\",\"text\":\"\\u8981\\u7d04 <p>\\u4e26\\u884c\\u51e6\\u7406\\u306b\\u719f\\u9054\\u3059\\u308b\\u3068\\u3044\\u3046\\u3053\\u3068\\u306f\\u3001\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u3068\\u7af6\\u5408\\u72b6\\u614b\\u304c\\u7570\\u306a\\u308b\\u6982\\u5ff5\\u3067\\u3042\\u308b\\u3053\\u3068\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3053\\u3068\\u3082\\u610f\\u5473\\u3057\\u307e\\u3059\\u3002\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u306f\\u3001\\u8907\\u6570\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u304c\\u540c\\u3058\\u30e1\\u30e2\\u30ea\\u4f4d\\u7f6e\\u306b\\u540c\\u6642\\u306b\\u30a2\\u30af\\u30bb\\u30b9\\u3057\\u3001\\u305d\\u306e\\u3046\\u3061\\u306e\\u5c11\\u306a\\u304f\\u3068\\u3082 1 \\u3064\\u304c\\u66f8\\u304d\\u8fbc\\u307f\\u3092\\u884c\\u3063\\u3066\\u3044\\u308b\\u5834\\u5408\\u306b\\u767a\\u751f\\u3057\\u307e\\u3059\\u3002\\u4e00\\u65b9\\u3001\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u304c\\u306a\\u3044\\u3053\\u3068\\u304c\\u5fc5\\u305a\\u3057\\u3082\\u6c7a\\u5b9a\\u7684\\u5b9f\\u884c\\u3092\\u610f\\u5473\\u3059\\u308b\\u308f\\u3051\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u52d5\\u4f5c\\u304c\\u5236\\u5fa1\\u3067\\u304d\\u306a\\u3044\\u30a4\\u30d9\\u30f3\\u30c8\\u306e\\u9806\\u5e8f\\u3084\\u30bf\\u30a4\\u30df\\u30f3\\u30b0\\u306b\\u4f9d\\u5b58\\u3057\\u3066\\u3044\\u308b\\u5834\\u5408\\u3001\\u3053\\u308c\\u306f\\u7af6\\u5408\\u72b6\\u614b\\u3067\\u3059\\u3002</p> <p>\\u7af6\\u5408\\u554f\\u984c\\u306f\\u3001\\u30d7\\u30ed\\u30b0\\u30e9\\u30de\\u30fc\\u304c\\u76f4\\u9762\\u3059\\u308b\\u53ef\\u80fd\\u6027\\u306e\\u3042\\u308b\\u30d0\\u30b0\\u306e\\u4e2d\\u3067\\u6700\\u3082\\u56f0\\u96e3\\u304b\\u3064\\u6700\\u3082\\u6f5c\\u4f0f\\u6027\\u306e\\u9ad8\\u3044\\u30d0\\u30b0\\u306e 1 \\u3064\\u3068\\u306a\\u308a\\u307e\\u3059\\u3002Go \\u958b\\u767a\\u8005\\u3068\\u3057\\u3066\\u3001\\u79c1\\u305f\\u3061\\u306f\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u3068\\u7af6\\u5408\\u72b6\\u614b\\u3001\\u305d\\u308c\\u3089\\u304c\\u53ca\\u307c\\u3057\\u3046\\u308b\\u5f71\\u97ff\\u3001\\u304a\\u3088\\u3073\\u305d\\u308c\\u3089\\u3092\\u56de\\u907f\\u3059\\u308b\\u65b9\\u6cd5\\u306a\\u3069\\u306e\\u91cd\\u8981\\u306a\\u5074\\u9762\\u3092\\u7406\\u89e3\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p>\"},{\"location\":\"ja/#_10\",\"title\":\"\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\",\"text\":\"<p>\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u306f\\u30012 \\u3064\\u4ee5\\u4e0a\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u304c\\u540c\\u3058\\u30e1\\u30e2\\u30ea\\u4f4d\\u7f6e\\u306b\\u540c\\u6642\\u306b\\u30a2\\u30af\\u30bb\\u30b9\\u3057\\u3001\\u5c11\\u306a\\u304f\\u3068\\u3082 1 \\u3064\\u304c\\u66f8\\u304d\\u8fbc\\u307f\\u3092\\u884c\\u3063\\u3066\\u3044\\u308b\\u5834\\u5408\\u306b\\u767a\\u751f\\u3057\\u307e\\u3059\\u3002\\u3053\\u306e\\u5834\\u5408\\u3001\\u5371\\u967a\\u306a\\u7d50\\u679c\\u304c\\u751f\\u3058\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3055\\u3089\\u306b\\u60aa\\u3044\\u3053\\u3068\\u306b\\u3001\\u72b6\\u6cc1\\u306b\\u3088\\u3063\\u3066\\u306f\\u3001\\u30e1\\u30e2\\u30ea\\u4f4d\\u7f6e\\u306b\\u7121\\u610f\\u5473\\u306a\\u30d3\\u30c3\\u30c8\\u306e\\u7d44\\u307f\\u5408\\u308f\\u305b\\u3092\\u542b\\u3080\\u5024\\u304c\\u4fdd\\u6301\\u3055\\u308c\\u3066\\u3057\\u307e\\u3046\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002 </p> <p>\\u3055\\u307e\\u3056\\u307e\\u306a\\u624b\\u6cd5\\u3092\\u99c6\\u4f7f\\u3057\\u3066\\u3001\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u306e\\u767a\\u751f\\u3092\\u9632\\u3050\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070 </p> <ul> <li><code>sync/atomic</code> \\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u3092\\u4f7f\\u7528\\u3059\\u308b </li> <li>2 \\u3064\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3092\\u540c\\u671f\\u3059\\u308b\\u969b\\u306b\\u30df\\u30e5\\u30fc\\u30c6\\u30c3\\u30af\\u30b9\\u306e\\u3088\\u3046\\u306a\\u7279\\u5b9a\\u306e\\u76ee\\u7684\\u306e\\u305f\\u3081\\u306e\\u30c7\\u30fc\\u30bf\\u69cb\\u9020\\u3092\\u5229\\u7528\\u3059\\u308b</li> <li>\\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u4f7f\\u7528\\u3057\\u3066 2 \\u3064\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u304c\\u901a\\u4fe1\\u3057\\u3001\\u5909\\u6570\\u304c\\u4e00\\u5ea6\\u306b 1 \\u3064\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3060\\u3051\\u306b\\u3088\\u3063\\u3066\\u66f4\\u65b0\\u3055\\u308c\\u308b\\u3088\\u3046\\u306b\\u3059\\u308b</li> </ul>\"},{\"location\":\"ja/#_11\",\"title\":\"\\u7af6\\u5408\\u72b6\\u614b\",\"text\":\"<p>\\u5b9f\\u884c\\u3057\\u305f\\u3044\\u64cd\\u4f5c\\u306b\\u5fdc\\u3058\\u3066\\u3001\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u306e\\u306a\\u3044\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u304c\\u5fc5\\u305a\\u3057\\u3082\\u6c7a\\u5b9a\\u7684\\u306a\\u7d50\\u679c\\u3092\\u610f\\u5473\\u3059\\u308b\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002\\u305d\\u3046\\u3068\\u306f\\u3044\\u3048\\u307e\\u305b\\u3093\\u3002</p> <p>\\u7af6\\u5408\\u72b6\\u614b\\u306f\\u3001\\u52d5\\u4f5c\\u304c\\u5236\\u5fa1\\u3067\\u304d\\u306a\\u3044\\u30a4\\u30d9\\u30f3\\u30c8\\u306e\\u30b7\\u30fc\\u30b1\\u30f3\\u30b9\\u307e\\u305f\\u306f\\u30bf\\u30a4\\u30df\\u30f3\\u30b0\\u306b\\u4f9d\\u5b58\\u3059\\u308b\\u5834\\u5408\\u306b\\u767a\\u751f\\u3057\\u307e\\u3059\\u3002\\u3053\\u3053\\u3067\\u306f\\u3001\\u30a4\\u30d9\\u30f3\\u30c8\\u306e\\u30bf\\u30a4\\u30df\\u30f3\\u30b0\\u304c\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306e\\u5b9f\\u884c\\u9806\\u5e8f\\u3067\\u3059\\u3002 </p> <p>\\u307e\\u3068\\u3081\\u308b\\u3068\\u3001\\u4e26\\u884c\\u51e6\\u7406\\u306e\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3067\\u4f5c\\u696d\\u3059\\u308b\\u5834\\u5408\\u3001\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u306f\\u7af6\\u5408\\u72b6\\u614b\\u3068\\u306f\\u7570\\u306a\\u308b\\u3053\\u3068\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3053\\u3068\\u304c\\u4e0d\\u53ef\\u6b20\\u3067\\u3059\\u3002\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u306f\\u3001\\u8907\\u6570\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u304c\\u540c\\u3058\\u30e1\\u30e2\\u30ea\\u4f4d\\u7f6e\\u306b\\u540c\\u6642\\u306b\\u30a2\\u30af\\u30bb\\u30b9\\u3057\\u3001\\u305d\\u306e\\u3046\\u3061\\u306e\\u5c11\\u306a\\u304f\\u3068\\u3082 1 \\u3064\\u304c\\u66f8\\u304d\\u8fbc\\u307f\\u3092\\u884c\\u3063\\u3066\\u3044\\u308b\\u5834\\u5408\\u306b\\u767a\\u751f\\u3057\\u307e\\u3059\\u3002\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u3068\\u306f\\u3001\\u4e88\\u60f3\\u5916\\u306e\\u52d5\\u4f5c\\u3092\\u610f\\u5473\\u3057\\u307e\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u306e\\u306a\\u3044\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u304c\\u5fc5\\u305a\\u3057\\u3082\\u6c7a\\u5b9a\\u7684\\u306a\\u7d50\\u679c\\u3092\\u610f\\u5473\\u3059\\u308b\\u308f\\u3051\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u304c\\u306a\\u304f\\u3066\\u3082\\u3001\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u306f\\u5236\\u5fa1\\u3055\\u308c\\u3066\\u3044\\u306a\\u3044\\u30a4\\u30d9\\u30f3\\u30c8\\uff08\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306e\\u5b9f\\u884c\\u3001\\u30c1\\u30e3\\u30cd\\u30eb\\u3078\\u306e\\u30e1\\u30c3\\u30bb\\u30fc\\u30b8\\u306e\\u767a\\u4fe1\\u901f\\u5ea6\\u3001\\u30c7\\u30fc\\u30bf\\u30d9\\u30fc\\u30b9\\u3078\\u306e\\u547c\\u3073\\u51fa\\u3057\\u306e\\u7d99\\u7d9a\\u6642\\u9593\\u306a\\u3069\\uff09\\u306b\\u4f9d\\u5b58\\u3059\\u308b\\u6319\\u52d5\\u3092\\u6301\\u3064\\u3053\\u3068\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u305d\\u306e\\u5834\\u5408\\u306f\\u7af6\\u5408\\u72b6\\u614b\\u3067\\u3059\\u3002\\u4e26\\u884c\\u51e6\\u7406\\u306e\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u306e\\u8a2d\\u8a08\\u306b\\u719f\\u7df4\\u3059\\u308b\\u306b\\u306f\\u3001\\u4e21\\u65b9\\u306e\\u6982\\u5ff5\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3053\\u3068\\u304c\\u809d\\u8981\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#59\",\"title\":\"\\u30ef\\u30fc\\u30af\\u30ed\\u30fc\\u30c9\\u30bf\\u30a4\\u30d7\\u3054\\u3068\\u306e\\u4e26\\u884c\\u51e6\\u7406\\u306e\\u5f71\\u97ff\\u3092\\u7406\\u89e3\\u3057\\u3066\\u3044\\u306a\\u3044 (#59)\",\"text\":\"\\u8981\\u7d04 <p>\\u4e00\\u5b9a\\u6570\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3092\\u4f5c\\u6210\\u3059\\u308b\\u3068\\u304d\\u306f\\u3001\\u30ef\\u30fc\\u30af\\u30ed\\u30fc\\u30c9\\u306e\\u30bf\\u30a4\\u30d7\\u3092\\u8003\\u616e\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002CPU \\u30d0\\u30a6\\u30f3\\u30c9\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3092\\u4f5c\\u6210\\u3059\\u308b\\u3068\\u3044\\u3046\\u3053\\u3068\\u306f\\u3001\\u3053\\u306e\\u6570\\u3092 <code>GOMAXPROCS</code> \\u5909\\u6570\\uff08\\u30c7\\u30d5\\u30a9\\u30eb\\u30c8\\u3067\\u306f\\u30db\\u30b9\\u30c8\\u4e0a\\u306e CPU \\u30b3\\u30a2\\u306e\\u6570\\u306b\\u57fa\\u3065\\u304f\\uff09\\u306b\\u8fd1\\u3065\\u3051\\u308b\\u3053\\u3068\\u3092\\u610f\\u5473\\u3057\\u307e\\u3059\\u3002I/O \\u30d0\\u30a6\\u30f3\\u30c9\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306e\\u4f5c\\u6210\\u306f\\u3001\\u5916\\u90e8\\u30b7\\u30b9\\u30c6\\u30e0\\u306a\\u3069\\u306e\\u4ed6\\u306e\\u8981\\u56e0\\u306b\\u4f9d\\u5b58\\u3057\\u307e\\u3059\\u3002 </p> <p>\\u30d7\\u30ed\\u30b0\\u30e9\\u30df\\u30f3\\u30b0\\u3067\\u306f\\u3001\\u30ef\\u30fc\\u30af\\u30ed\\u30fc\\u30c9\\u306e\\u5b9f\\u884c\\u6642\\u9593\\u306f\\u6b21\\u306e\\u3044\\u305a\\u308c\\u304b\\u306b\\u3088\\u3063\\u3066\\u5236\\u9650\\u3055\\u308c\\u307e\\u3059\\u3002 </p> <ul> <li>CPU \\u306e\\u901f\\u5ea6 - \\u305f\\u3068\\u3048\\u3070\\u3001\\u30de\\u30fc\\u30b8\\u30bd\\u30fc\\u30c8\\u30a2\\u30eb\\u30b4\\u30ea\\u30ba\\u30e0\\u306e\\u5b9f\\u884c\\u304c\\u3053\\u308c\\u306b\\u3042\\u305f\\u308a\\u307e\\u3059\\u3002\\u3053\\u306e\\u30ef\\u30fc\\u30af\\u30ed\\u30fc\\u30c9\\u306f CPU \\u30d0\\u30a6\\u30f3\\u30c9\\u3068\\u547c\\u3070\\u308c\\u307e\\u3059\\u3002 </li> <li>I/O \\u306e\\u901f\\u5ea6 - \\u305f\\u3068\\u3048\\u3070\\u3001REST \\u547c\\u3073\\u51fa\\u3057\\u3084\\u30c7\\u30fc\\u30bf\\u30d9\\u30fc\\u30b9\\u30af\\u30a8\\u30ea\\u306e\\u5b9f\\u884c\\u304c\\u3053\\u308c\\u306b\\u3042\\u305f\\u308a\\u307e\\u3059\\u3002\\u3053\\u306e\\u30ef\\u30fc\\u30af\\u30ed\\u30fc\\u30c9\\u306f I/O \\u30d0\\u30a6\\u30f3\\u30c9\\u3068\\u547c\\u3070\\u308c\\u307e\\u3059\\u3002 </li> <li>\\u5229\\u7528\\u53ef\\u80fd\\u306a\\u30e1\\u30e2\\u30ea\\u306e\\u91cf - \\u3053\\u306e\\u30ef\\u30fc\\u30af\\u30ed\\u30fc\\u30c9\\u306f\\u30e1\\u30e2\\u30ea\\u30d0\\u30a6\\u30f3\\u30c9\\u3068\\u547c\\u3070\\u308c\\u307e\\u3059\\u3002</li> </ul> \\u88dc\\u8db3 <p>\\u3053\\u3053\\u6570\\u5341\\u5e74\\u3067\\u30e1\\u30e2\\u30ea\\u304c\\u975e\\u5e38\\u306b\\u5b89\\u4fa1\\u306b\\u306a\\u3063\\u305f\\u3053\\u3068\\u3092\\u8003\\u616e\\u3059\\u308b\\u3068\\u3001 3 \\u3064\\u76ee\\u306f\\u73fe\\u5728\\u3067\\u306f\\u6700\\u3082\\u307e\\u308c\\u3067\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u3053\\u306e\\u30bb\\u30af\\u30b7\\u30e7\\u30f3\\u3067\\u306f\\u3001\\u6700\\u521d\\u306e 2 \\u3064\\u306e\\u30ef\\u30fc\\u30af\\u30ed\\u30fc\\u30c9\\u30bf\\u30a4\\u30d7\\u3001CPU \\u30d0\\u30a6\\u30f3\\u30c9\\u3068 I/O \\u30d0\\u30a6\\u30f3\\u30c9\\u306b\\u7126\\u70b9\\u3092\\u5f53\\u3066\\u307e\\u3059\\u3002 </p> <p>\\u30ef\\u30fc\\u30ab\\u30fc\\u306b\\u3088\\u3063\\u3066\\u5b9f\\u884c\\u3055\\u308c\\u308b\\u30ef\\u30fc\\u30af\\u30ed\\u30fc\\u30c9\\u304c I/O \\u30d0\\u30a6\\u30f3\\u30c9\\u3067\\u3042\\u308b\\u5834\\u5408\\u3001\\u5024\\u306f\\u4e3b\\u306b\\u5916\\u90e8\\u30b7\\u30b9\\u30c6\\u30e0\\u306b\\u4f9d\\u5b58\\u3057\\u307e\\u3059\\u3002\\u9006\\u306b\\u3001\\u30ef\\u30fc\\u30af\\u30ed\\u30fc\\u30c9\\u304c CPU \\u306b\\u4f9d\\u5b58\\u3057\\u3066\\u3044\\u308b\\u5834\\u5408\\u3001\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306e\\u6700\\u9069\\u306a\\u6570\\u306f\\u5229\\u7528\\u53ef\\u80fd\\u306a CPU \\u30b3\\u30a2\\u306e\\u6570\\u306b\\u8fd1\\u304f\\u306a\\u308a\\u307e\\u3059\\uff08\\u30d9\\u30b9\\u30c8\\u30d7\\u30e9\\u30af\\u30c6\\u30a3\\u30b9\\u306f <code>runtime.GOMAXPROCS</code> \\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u3067\\u3059\\uff09\\u3002\\u4e26\\u884c\\u51e6\\u7406\\u306e\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u8a2d\\u8a08\\u3059\\u308b\\u5834\\u5408\\u3001\\u30ef\\u30fc\\u30af\\u30ed\\u30fc\\u30c9\\u306e\\u30bf\\u30a4\\u30d7\\uff08 I/O \\u3042\\u308b\\u3044\\u306f CPU \\uff09\\u3092\\u77e5\\u308b\\u3053\\u3068\\u304c\\u91cd\\u8981\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#go-context-60\",\"title\":\"Go Context \\u306b\\u5bfe\\u3059\\u308b\\u8aa4\\u89e3 (#60)\",\"text\":\"\\u8981\\u7d04 <p>Go Context \\u306f\\u3001Go\\u8a00\\u8a9e\\u306e\\u4e26\\u884c\\u51e6\\u7406\\u306e\\u57fa\\u790e\\u306e\\u4e00\\u90e8\\u3067\\u3082\\u3042\\u308a\\u307e\\u3059\\u3002 Context \\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u3001\\u30c7\\u30c3\\u30c9\\u30e9\\u30a4\\u30f3\\u3001\\u30ad\\u30fc\\u3068\\u5024\\u306e\\u30ea\\u30b9\\u30c8\\u3092\\u4fdd\\u6301\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>https://pkg.go.dev/context</p> <p>Context \\u306f\\u3001\\u30c7\\u30c3\\u30c9\\u30e9\\u30a4\\u30f3\\u3001\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u30b7\\u30b0\\u30ca\\u30eb\\u3001\\u305d\\u306e\\u4ed6\\u306e\\u5024\\u3092 API \\u306e\\u5883\\u754c\\u3092\\u8d8a\\u3048\\u3066\\u4f1d\\u9054\\u3057\\u307e\\u3059\\u3002</p>\"},{\"location\":\"ja/#_12\",\"title\":\"\\u30c7\\u30c3\\u30c9\\u30e9\\u30a4\\u30f3\",\"text\":\"<p>\\u30c7\\u30c3\\u30c9\\u30e9\\u30a4\\u30f3\\u3068\\u306f\\u3001\\u6b21\\u306e\\u3044\\u305a\\u308c\\u304b\\u3067\\u6c7a\\u5b9a\\u3055\\u308c\\u308b\\u7279\\u5b9a\\u306e\\u6642\\u70b9\\u3092\\u6307\\u3057\\u307e\\u3059\\u3002 </p> <ul> <li>\\u73fe\\u5728\\u304b\\u3089\\u306e <code>time.Duration</code> \\uff08\\u4f8b\\uff1a250 ms\\uff09</li> <li><code>time.Time</code> \\uff08\\u4f8b\\uff1a2023-02-07 00:00:00 UTC\\uff09 </li> </ul> <p>\\u30c7\\u30c3\\u30c9\\u30e9\\u30a4\\u30f3\\u306e\\u30bb\\u30de\\u30f3\\u30c6\\u30a3\\u30af\\u30b9\\u306f\\u3001\\u3053\\u308c\\u3092\\u904e\\u304e\\u305f\\u5834\\u5408\\u306f\\u9032\\u884c\\u4e2d\\u306e\\u30a2\\u30af\\u30c6\\u30a3\\u30d3\\u30c6\\u30a3\\u3092\\u505c\\u6b62\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u3053\\u3068\\u3092\\u4f1d\\u3048\\u307e\\u3059\\u3002\\u30a2\\u30af\\u30c6\\u30a3\\u30d3\\u30c6\\u30a3\\u3068\\u306f\\u3001\\u305f\\u3068\\u3048\\u3070\\u3001\\u30c1\\u30e3\\u30cd\\u30eb\\u304b\\u3089\\u306e\\u30e1\\u30c3\\u30bb\\u30fc\\u30b8\\u306e\\u53d7\\u4fe1\\u3092\\u5f85\\u6a5f\\u3057\\u3066\\u3044\\u308b I/O \\u30ea\\u30af\\u30a8\\u30b9\\u30c8\\u3084\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3067\\u3059\\u3002 </p>\"},{\"location\":\"ja/#_13\",\"title\":\"\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u30b7\\u30b0\\u30ca\\u30eb\",\"text\":\"<p>Go Context \\u306e\\u3082\\u3046 1 \\u3064\\u306e\\u4f7f\\u7528\\u4f8b\\u306f\\u3001\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u30b7\\u30b0\\u30ca\\u30eb\\u3092\\u4f1d\\u9001\\u3059\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002\\u5225\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u5185\\u3067 <code>CreateFileWatcher(ctx context.Context, filename string)</code> \\u3092\\u547c\\u3073\\u51fa\\u3059\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u4f5c\\u6210\\u3059\\u308b\\u3053\\u3068\\u3092\\u60f3\\u50cf\\u3057\\u3066\\u307f\\u307e\\u3057\\u3087\\u3046\\u3002\\u3053\\u306e\\u95a2\\u6570\\u306f\\u3001\\u30d5\\u30a1\\u30a4\\u30eb\\u304b\\u3089\\u8aad\\u307f\\u53d6\\u308a\\u3092\\u7d9a\\u3051\\u3066\\u66f4\\u65b0\\u3092\\u30ad\\u30e3\\u30c3\\u30c1\\u3059\\u308b\\u7279\\u5b9a\\u306e\\u30d5\\u30a1\\u30a4\\u30eb\\u30a6\\u30a9\\u30c3\\u30c1\\u30e3\\u30fc\\u3092\\u4f5c\\u6210\\u3057\\u307e\\u3059\\u3002\\u63d0\\u4f9b\\u3055\\u308c\\u305f Context \\u304c\\u671f\\u9650\\u5207\\u308c\\u306b\\u306a\\u308b\\u304b\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3055\\u308c\\u308b\\u3068\\u3001\\u3053\\u306e\\u95a2\\u6570\\u306f\\u305d\\u308c\\u3092\\u51e6\\u7406\\u3057\\u3066\\u30d5\\u30a1\\u30a4\\u30eb\\u8a18\\u8ff0\\u5b50\\u3092\\u9589\\u3058\\u307e\\u3059\\u3002 </p>\"},{\"location\":\"ja/#context-value\",\"title\":\"Context Value\",\"text\":\"<p>Go Context \\u306e\\u6700\\u5f8c\\u306e\\u4f7f\\u7528\\u4f8b\\u306f\\u3001\\u30ad\\u30fc\\u3068\\u5024\\u306e\\u30ea\\u30b9\\u30c8\\u3092\\u904b\\u3076\\u3053\\u3068\\u3067\\u3059\\u3002 Context \\u306b\\u30ad\\u30fc\\u3068\\u5024\\u306e\\u30ea\\u30b9\\u30c8\\u3092\\u542b\\u3081\\u308b\\u610f\\u5473\\u306f\\u4f55\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002Go Context \\u306f\\u6c4e\\u7528\\u7684\\u3067\\u3042\\u308b\\u305f\\u3081\\u3001\\u4f7f\\u7528\\u4f8b\\u306f\\u7121\\u9650\\u306b\\u3042\\u308a\\u307e\\u3059\\u3002 </p> <p>\\u305f\\u3068\\u3048\\u3070\\u3001\\u30c8\\u30ec\\u30fc\\u30b9\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u5834\\u5408\\u3001\\u7570\\u306a\\u308b\\u30b5\\u30d6\\u95a2\\u6570\\u306e\\u9593\\u3067\\u540c\\u3058\\u76f8\\u95a2 ID \\u3092\\u5171\\u6709\\u3057\\u305f\\u3044\\u3053\\u3068\\u304c\\u3042\\u308b\\u304b\\u3082\\u3057\\u308c\\u307e\\u305b\\u3093\\u3002\\u4e00\\u90e8\\u306e\\u958b\\u767a\\u8005\\u306f\\u3001\\u3053\\u306e ID \\u3092\\u95a2\\u6570\\u30b7\\u30b0\\u30cd\\u30c1\\u30e3\\u306e\\u4e00\\u90e8\\u306b\\u3059\\u308b\\u306b\\u306f\\u3042\\u307e\\u308a\\u306b\\u4fb5\\u7565\\u7684\\u3060\\u3068\\u8003\\u3048\\u308b\\u304b\\u3082\\u3057\\u308c\\u307e\\u305b\\u3093\\u3002\\u3053\\u306e\\u70b9\\u306b\\u95a2\\u3057\\u3066\\u3001\\u4e0e\\u3048\\u3089\\u308c\\u305f Context \\u306e\\u4e00\\u90e8\\u3068\\u3057\\u3066\\u305d\\u308c\\u3092\\u542b\\u3081\\u308b\\u3053\\u3068\\u3092\\u6c7a\\u5b9a\\u3059\\u308b\\u3053\\u3068\\u3082\\u3067\\u304d\\u307e\\u3059\\u3002 </p>\"},{\"location\":\"ja/#context\",\"title\":\"Context \\u306e\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3092\\u30ad\\u30e3\\u30c3\\u30c1\\u3059\\u308b\",\"text\":\"<p><code>context.Context</code> \\u30bf\\u30a4\\u30d7\\u306f\\u3001\\u53d7\\u4fe1\\u5c02\\u7528\\u306e\\u901a\\u77e5\\u30c1\\u30e3\\u30cd\\u30eb <code>&lt;-chan struct{}</code> \\u3092\\u8fd4\\u3059 <code>Done</code> \\u30e1\\u30bd\\u30c3\\u30c9\\u3092\\u30a8\\u30af\\u30b9\\u30dd\\u30fc\\u30c8\\u3057\\u307e\\u3059\\u3002\\u3053\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u306f\\u3001 Context \\u306b\\u95a2\\u9023\\u4ed8\\u3051\\u3089\\u308c\\u305f\\u4f5c\\u696d\\u3092\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u5834\\u5408\\u306b\\u9589\\u3058\\u3089\\u308c\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070 </p> <ul> <li><code>context.WithCancel</code>\\u3067\\u4f5c\\u6210\\u3055\\u308c\\u305f Context \\u306b\\u95a2\\u9023\\u3059\\u308b Done \\u30c1\\u30e3\\u30cd\\u30eb\\u306f\\u3001cancel\\u95a2\\u6570\\u304c\\u547c\\u3073\\u51fa\\u3055\\u308c\\u308b\\u3068\\u9589\\u3058\\u3089\\u308c\\u307e\\u3059\\u3002 </li> <li><code>context.WithDeadline</code>\\u3067\\u4f5c\\u6210\\u3057\\u305f Context \\u306b\\u95a2\\u9023\\u3059\\u308b Done \\u30c1\\u30e3\\u30cd\\u30eb\\u306f\\u3001\\u30c7\\u30c3\\u30c9\\u30e9\\u30a4\\u30f3\\u3092\\u904e\\u304e\\u308b\\u3068\\u9589\\u3058\\u3089\\u308c\\u307e\\u3059\\u3002 </li> </ul> <p>\\u6ce8\\u610f\\u3059\\u3079\\u304d\\u70b9\\u306e 1 \\u3064\\u306f\\u3001\\u5185\\u90e8\\u30c1\\u30e3\\u30cd\\u30eb\\u306f\\u3001\\u7279\\u5b9a\\u306e\\u5024\\u3092\\u53d7\\u3051\\u53d6\\u3063\\u305f\\u3068\\u304d\\u3067\\u306f\\u306a\\u304f\\u3001 Context \\u304c\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3055\\u308c\\u305f\\u3068\\u304d\\u3001\\u307e\\u305f\\u306f\\u30c7\\u30c3\\u30c9\\u30e9\\u30a4\\u30f3\\u306b\\u9054\\u3057\\u305f\\u3068\\u304d\\u306b\\u9589\\u3058\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u3068\\u3044\\u3046\\u3053\\u3068\\u3067\\u3059\\u3002\\u30c1\\u30e3\\u30cd\\u30eb\\u306e\\u30af\\u30ed\\u30fc\\u30ba\\u306f\\u3001\\u3059\\u3079\\u3066\\u306e\\u6d88\\u8cbb\\u8005\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u304c\\u53d7\\u3051\\u53d6\\u308b\\u552f\\u4e00\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u30a2\\u30af\\u30b7\\u30e7\\u30f3\\u3067\\u3042\\u308b\\u305f\\u3081\\u3067\\u3059\\u3002\\u3053\\u306e\\u3088\\u3046\\u306b\\u3057\\u3066\\u3001 Context \\u304c\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3055\\u308c\\u308b\\u304b\\u3001\\u30c7\\u30c3\\u30c9\\u30e9\\u30a4\\u30f3\\u306b\\u9054\\u3059\\u308b\\u3068\\u3001\\u3059\\u3079\\u3066\\u306e\\u6d88\\u8cbb\\u8005\\u306b\\u901a\\u77e5\\u304c\\u5c4a\\u304d\\u307e\\u3059\\u3002 </p> <p>\\u307e\\u3068\\u3081\\u308b\\u3068\\u3001\\u719f\\u7df4\\u3057\\u305f Go \\u958b\\u767a\\u8005\\u306b\\u306a\\u308b\\u306b\\u306f\\u3001 Context \\u3068\\u305d\\u306e\\u4f7f\\u7528\\u65b9\\u6cd5\\u306b\\u3064\\u3044\\u3066\\u7406\\u89e3\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u539f\\u5247\\u3068\\u3057\\u3066\\u3001\\u30e6\\u30fc\\u30b6\\u30fc\\u304c\\u5f85\\u6a5f\\u3055\\u305b\\u3089\\u308c\\u308b\\u95a2\\u6570\\u306f Context \\u3092\\u53d6\\u5f97\\u3059\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002\\u3053\\u308c\\u306b\\u3088\\u308a\\u3001\\u4e0a\\u6d41\\u306e\\u547c\\u3073\\u51fa\\u3057\\u5143\\u304c\\u3053\\u306e\\u95a2\\u6570\\u3092\\u3044\\u3064\\u547c\\u3073\\u51fa\\u3059\\u304b\\u3092\\u6c7a\\u5b9a\\u3067\\u304d\\u308b\\u3088\\u3046\\u306b\\u306a\\u308b\\u304b\\u3089\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#_14\",\"title\":\"\\u4e26\\u884c\\u51e6\\u7406\\uff1a\\u5b9f\\u8df5\",\"text\":\"\"},{\"location\":\"ja/#context-61\",\"title\":\"\\u4e0d\\u9069\\u5207\\u306a Context \\u3092\\u5e83\\u3081\\u3066\\u3057\\u307e\\u3046 (#61)\",\"text\":\"\\u8981\\u7d04 <p>Context \\u3092\\u4f1d\\u64ad\\u3059\\u308b\\u969b\\u306b\\u306f\\u3001Context \\u3092\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3067\\u304d\\u308b\\u6761\\u4ef6\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3053\\u3068\\u304c\\u91cd\\u8981\\u3067\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001\\u30ec\\u30b9\\u30dd\\u30f3\\u30b9\\u304c\\u9001\\u4fe1\\u3055\\u308c\\u305f\\u969b\\u306b HTTP \\u30cf\\u30f3\\u30c9\\u30e9\\u304c Context \\u3092\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3059\\u308b\\u3068\\u304d\\u306a\\u3069\\u3067\\u3059\\u3002 </p> <p>\\u591a\\u304f\\u306e\\u72b6\\u6cc1\\u3067\\u306f\\u3001Go Context \\u3092\\u4f1d\\u64ad\\u3059\\u308b\\u3053\\u3068\\u304c\\u63a8\\u5968\\u3055\\u308c\\u307e\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001Context \\u306e\\u4f1d\\u64ad\\u306b\\u3088\\u3063\\u3066\\u8efd\\u5fae\\u306a\\u30d0\\u30b0\\u304c\\u767a\\u751f\\u3057\\u3001\\u30b5\\u30d6\\u95a2\\u6570\\u304c\\u6b63\\u3057\\u304f\\u5b9f\\u884c\\u3055\\u308c\\u306a\\u304f\\u306a\\u308b\\u5834\\u5408\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002 </p> <p>\\u6b21\\u306e\\u4f8b\\u3092\\u8003\\u3048\\u3066\\u307f\\u307e\\u3057\\u3087\\u3046\\u3002\\u3044\\u304f\\u3064\\u304b\\u306e\\u30bf\\u30b9\\u30af\\u3092\\u5b9f\\u884c\\u3057\\u3066\\u30ec\\u30b9\\u30dd\\u30f3\\u30b9\\u3092\\u8fd4\\u3059 HTTP \\u30cf\\u30f3\\u30c9\\u30e9\\u3092\\u516c\\u958b\\u3057\\u307e\\u3059\\u3002\\u305f\\u3060\\u3057\\u3001\\u30ec\\u30b9\\u30dd\\u30f3\\u30b9\\u3092\\u8fd4\\u3059\\u76f4\\u524d\\u306b\\u3001\\u305d\\u308c\\u3092 Kafka \\u30c8\\u30d4\\u30c3\\u30af\\u306b\\u9001\\u4fe1\\u3057\\u305f\\u3044\\u3068\\u601d\\u3063\\u3066\\u3044\\u307e\\u3059\\u3002HTTP \\u30b3\\u30f3\\u30b7\\u30e5\\u30fc\\u30de\\u306b\\u30ec\\u30a4\\u30c6\\u30f3\\u30b7\\u306e\\u70b9\\u3067\\u30da\\u30ca\\u30eb\\u30c6\\u30a3\\u3092\\u8ab2\\u3057\\u305f\\u304f\\u306a\\u3044\\u306e\\u3067\\u3001publish \\u30a2\\u30af\\u30b7\\u30e7\\u30f3\\u3092\\u65b0\\u3057\\u3044\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u5185\\u3067\\u975e\\u540c\\u671f\\u306b\\u51e6\\u7406\\u3057\\u305f\\u3044\\u3068\\u8003\\u3048\\u3066\\u3044\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001Context \\u304c\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3055\\u308c\\u305f\\u5834\\u5408\\u306b\\u30e1\\u30c3\\u30bb\\u30fc\\u30b8\\u306e publish \\u30a2\\u30af\\u30b7\\u30e7\\u30f3\\u3092\\u4e2d\\u65ad\\u3067\\u304d\\u308b\\u3088\\u3046\\u306b\\u3001Context \\u3092\\u53d7\\u3051\\u5165\\u308c\\u308b <code>publish</code> \\u95a2\\u6570\\u3092\\u81ea\\u7531\\u306b\\u4f7f\\u3048\\u308b\\u3068\\u3057\\u307e\\u3059\\u3002\\u53ef\\u80fd\\u306a\\u5b9f\\u88c5\\u306f\\u6b21\\u306e\\u3068\\u304a\\u308a\\u3067\\u3059\\u3002</p> <pre><code>func handler(w http.ResponseWriter, r *http.Request) {\\n    response, err := doSomeTask(r.Context(), r)\\n    if err != nil {\\n        http.Error(w, err.Error(), http.StatusInternalServerError)\\n    return\\n    }\\n    go func() {\\n        err := publish(r.Context(), response)\\n        // err \\u306e\\u51e6\\u7406\\u3092\\u3059\\u308b\\n    }()\\n    writeResponse(response)\\n}\\n</code></pre> <p>\\u3053\\u306e\\u30b3\\u30fc\\u30c9\\u306e\\u4f55\\u304c\\u554f\\u984c\\u306a\\u306e\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002HTTP \\u30ea\\u30af\\u30a8\\u30b9\\u30c8\\u306b\\u4ed8\\u3055\\u308c\\u305f Context \\u306f\\u3001\\u3055\\u307e\\u3056\\u307e\\u306a\\u72b6\\u6cc1\\u3067\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3055\\u308c\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u3053\\u3068\\u3092\\u77e5\\u3063\\u3066\\u304a\\u304f\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002 </p> <ul> <li>\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u306e\\u63a5\\u7d9a\\u304c\\u7d42\\u4e86\\u3057\\u305f\\u3068\\u304d </li> <li>HTTP/2\\u30ea\\u30af\\u30a8\\u30b9\\u30c8\\u306e\\u5834\\u5408\\u3001\\u30ea\\u30af\\u30a8\\u30b9\\u30c8\\u304c\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3055\\u308c\\u305f\\u3068\\u304d</li> <li>\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u306b\\u30ec\\u30b9\\u30dd\\u30f3\\u30b9\\u304c\\u66f8\\u304d\\u623b\\u3055\\u308c\\u305f\\u3068\\u304d </li> </ul> <p>\\u6700\\u521d\\u306e 2 \\u3064\\u306e\\u30b1\\u30fc\\u30b9\\u3067\\u306f\\u3001\\u51e6\\u7406\\u306f\\u304a\\u305d\\u3089\\u304f\\u6b63\\u3057\\u304f\\u884c\\u308f\\u308c\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001doSomeTask \\u304b\\u3089\\u30ec\\u30b9\\u30dd\\u30f3\\u30b9\\u3092\\u53d7\\u3051\\u53d6\\u3063\\u305f\\u3082\\u306e\\u306e\\u3001\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u304c\\u63a5\\u7d9a\\u3092\\u9589\\u3058\\u305f\\u5834\\u5408\\u3001\\u30e1\\u30c3\\u30bb\\u30fc\\u30b8\\u304c publish \\u3055\\u308c\\u306a\\u3044\\u3088\\u3046\\u306b\\u3001Context \\u304c\\u65e2\\u306b\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3055\\u308c\\u305f\\u72b6\\u614b\\u3067 publish \\u3092\\u547c\\u3073\\u51fa\\u3057\\u3066\\u3082\\u554f\\u984c\\u306f\\u304a\\u305d\\u3089\\u304f\\u8d77\\u304d\\u307e\\u305b\\u3093\\u3002\\u3057\\u304b\\u3057\\u3001\\u6700\\u5f8c\\u306e\\u30b1\\u30fc\\u30b9\\u306f\\u3069\\u3046\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002</p> <p>\\u30ec\\u30b9\\u30dd\\u30f3\\u30b9\\u304c\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u306b\\u66f8\\u304d\\u8fbc\\u307e\\u308c\\u308b\\u3068\\u3001\\u8981\\u6c42\\u306b\\u95a2\\u9023\\u4ed8\\u3051\\u3089\\u308c\\u305f Context \\u304c\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3055\\u308c\\u307e\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u7af6\\u5408\\u72b6\\u614b\\u306b\\u76f4\\u9762\\u3057\\u307e\\u3059\\u3002 </p> <ul> <li>\\u30ec\\u30b9\\u30dd\\u30f3\\u30b9\\u304c Kafka \\u306e publish \\u5f8c\\u306b\\u66f8\\u304b\\u308c\\u305f\\u5834\\u5408\\u3001\\u30ec\\u30b9\\u30dd\\u30f3\\u30b9\\u3092\\u8fd4\\u3057\\u3001\\u30e1\\u30c3\\u30bb\\u30fc\\u30b8\\u3092\\u6b63\\u5e38\\u306b\\u516c\\u958b\\u3057\\u307e\\u3059\\u3002 </li> <li>\\u305f\\u3060\\u3057\\u3001Kafka \\u306e publish \\u524d\\u307e\\u305f\\u306f publish \\u4e2d\\u306b\\u30ec\\u30b9\\u30dd\\u30f3\\u30b9\\u304c\\u66f8\\u304b\\u308c\\u305f\\u5834\\u5408\\u3001\\u30e1\\u30c3\\u30bb\\u30fc\\u30b8\\u306f publish \\u3055\\u308c\\u308b\\u3079\\u304d\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002 </li> </ul> <p>\\u5f8c\\u8005\\u306e\\u5834\\u5408\\u3001HTTP \\u30ec\\u30b9\\u30dd\\u30f3\\u30b9\\u3092\\u3059\\u3050\\u306b\\u8fd4\\u3059\\u306e\\u3067\\u3001publish \\u3092\\u547c\\u3073\\u51fa\\u3059\\u3068\\u30a8\\u30e9\\u30fc\\u304c\\u8fd4\\u3055\\u308c\\u307e\\u3059\\u3002</p> \\u88dc\\u8db3 <p>Go 1.21 \\u304b\\u3089\\u306f\\u3001\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u305b\\u305a\\u306b\\u65b0\\u3057\\u3044 Context \\u3092\\u4f5c\\u6210\\u3059\\u308b\\u65b9\\u6cd5\\u304c\\u8ffd\\u52a0\\u3055\\u308c\\u307e\\u3057\\u305f\\u3002 <code>context.WithoutCancel</code> \\u306f\\u3001\\u89aa\\u304c\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3055\\u308c\\u305f\\u3068\\u304d\\u306b\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3055\\u308c\\u3066\\u3044\\u306a\\u3044\\u89aa\\u306e\\u30b3\\u30d4\\u30fc\\u3092\\u8fd4\\u3057\\u307e\\u3059\\u3002 </p> <p>\\u307e\\u3068\\u3081\\u308b\\u3068\\u3001Context \\u306e\\u4f1d\\u64ad\\u306f\\u614e\\u91cd\\u306b\\u884c\\u3046\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#62\",\"title\":\"\\u505c\\u6b62\\u3059\\u3079\\u304d\\u3068\\u304d\\u3092\\u77e5\\u3089\\u305a\\u306b\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3092\\u958b\\u59cb\\u3057\\u3066\\u3057\\u307e\\u3046 (#62)\",\"text\":\"\\u8981\\u7d04 <p>\\u30ea\\u30fc\\u30af\\u3092\\u907f\\u3051\\u308b\\u3053\\u3068\\u306f\\u3001\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u304c\\u958b\\u59cb\\u3055\\u308c\\u308b\\u305f\\u3073\\u306b\\u3001\\u6700\\u7d42\\u7684\\u306b\\u505c\\u6b62\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u3053\\u3068\\u3092\\u610f\\u5473\\u3057\\u307e\\u3059\\u3002</p> <p>\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306f\\u7c21\\u5358\\u306b\\u884c\\u3046\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002\\u975e\\u5e38\\u306b\\u7c21\\u5358\\u3067\\u3042\\u308b\\u305f\\u3081\\u3001\\u65b0\\u3057\\u3044\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3092\\u3044\\u3064\\u505c\\u6b62\\u3059\\u308b\\u304b\\u306b\\u3064\\u3044\\u3066\\u306e\\u8a08\\u753b\\u3092\\u5fc5\\u305a\\u3057\\u3082\\u7acb\\u3066\\u3066\\u3044\\u306a\\u3044\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u3001\\u30ea\\u30fc\\u30af\\u306b\\u3064\\u306a\\u304c\\u308b\\u3053\\u3068\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3092\\u3044\\u3064\\u505c\\u6b62\\u3059\\u308c\\u3070\\u3088\\u3044\\u304b\\u308f\\u304b\\u3089\\u306a\\u3044\\u306e\\u306f\\u3001Go\\u8a00\\u8a9e\\u3067\\u3088\\u304f\\u3042\\u308b\\u8a2d\\u8a08\\u4e0a\\u306e\\u554f\\u984c\\u3067\\u3042\\u308a\\u3001\\u4e26\\u884c\\u51e6\\u7406\\u306b\\u304a\\u3051\\u308b\\u30df\\u30b9\\u3067\\u3059\\u3002 </p> <p>\\u5177\\u4f53\\u7684\\u306a\\u4f8b\\u306b\\u3064\\u3044\\u3066\\u8aac\\u660e\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002\\u5916\\u90e8\\u8a2d\\u5b9a\\uff08\\u30c7\\u30fc\\u30bf\\u30d9\\u30fc\\u30b9\\u63a5\\u7d9a\\u306a\\u3069\\u3092\\u4f7f\\u7528\\u3057\\u305f\\u3082\\u306e\\u306a\\u3069\\uff09\\u3092\\u76e3\\u8996\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u8a2d\\u8a08\\u3057\\u307e\\u3059\\u3002\\u307e\\u305a\\u3001\\u6b21\\u306e\\u3088\\u3046\\u306a\\u5b9f\\u88c5\\u3092\\u3057\\u3066\\u307f\\u307e\\u3059\\u3002</p> <pre><code>func main() {\\n    newWatcher()\\n    // \\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u5b9f\\u884c\\u3059\\u308b\\n}\\n\\ntype watcher struct { /* \\u3044\\u304f\\u3064\\u304b\\u306e\\u30ea\\u30bd\\u30fc\\u30b9 */ }\\n\\nfunc newWatcher() {\\n    w := watcher{}\\n    go w.watch() // \\u5916\\u90e8\\u8a2d\\u5b9a\\u3092\\u76e3\\u8996\\u3059\\u308b\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3092\\u4f5c\\u6210\\u3059\\u308b\\n}\\n</code></pre> <p>\\u3053\\u306e\\u30b3\\u30fc\\u30c9\\u306e\\u554f\\u984c\\u306f\\u3001\\u30e1\\u30a4\\u30f3\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u304c\\u7d42\\u4e86\\u3059\\u308b\\u3068\\uff08\\u304a\\u305d\\u3089\\u304f OS \\u30b7\\u30b0\\u30ca\\u30eb\\u307e\\u305f\\u306f\\u6709\\u9650\\u306e\\u30ef\\u30fc\\u30af\\u30ed\\u30fc\\u30c9\\u306e\\u305f\\u3081\\uff09\\u3001\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u304c\\u505c\\u6b62\\u3057\\u3066\\u3057\\u307e\\u3046\\u3053\\u3068\\u3067\\u3059\\u3002\\u3057\\u305f\\u304c\\u3063\\u3066\\u3001\\u30a6\\u30a9\\u30c3\\u30c1\\u30e3\\u30fc\\u306b\\u3088\\u3063\\u3066\\u4f5c\\u6210\\u3055\\u308c\\u305f\\u30ea\\u30bd\\u30fc\\u30b9\\u306f\\u6b63\\u5e38\\u306b\\u9589\\u3058\\u3089\\u308c\\u307e\\u305b\\u3093\\u3002\\u3053\\u308c\\u3092\\u9632\\u3050\\u306b\\u306f\\u3069\\u3046\\u3059\\u308c\\u3070\\u3088\\u3044\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002</p> <p>1 \\u3064\\u306e\\u65b9\\u6cd5\\u3068\\u3057\\u3066\\u306f\\u3001main \\u304c\\u623b\\u3063\\u305f\\u3068\\u304d\\u306b\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3055\\u308c\\u308b Context \\u3092 newWatcher \\u306b\\u6e21\\u3059\\u3053\\u3068\\u304c\\u6319\\u3052\\u3089\\u308c\\u307e\\u3059\\u3002</p> <pre><code>func main() {\\n    ctx, cancel := context.WithCancel(context.Background())\\n    defer cancel()\\n    newWatcher(ctx)\\n    // \\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u5b9f\\u884c\\u3059\\u308b\\n}\\n\\nfunc newWatcher(ctx context.Context) {\\n    w := watcher{}\\n    go w.watch(ctx)\\n}\\n</code></pre> <p>\\u4f5c\\u6210\\u3057\\u305f Context \\u3092 watch \\u30e1\\u30bd\\u30c3\\u30c9\\u306b\\u4f1d\\u64ad\\u3057\\u307e\\u3059\\u3002Context \\u304c\\u30ad\\u30e3\\u30f3\\u30bb\\u30eb\\u3055\\u308c\\u308b\\u3068\\u3001\\u30a6\\u30a9\\u30c3\\u30c1\\u30e3\\u30fc\\u69cb\\u9020\\u4f53\\u306f\\u305d\\u306e\\u30ea\\u30bd\\u30fc\\u30b9\\u3092\\u9589\\u3058\\u307e\\u3059\\u3002\\u3057\\u304b\\u3057\\u3001watch \\u304c\\u305d\\u308c\\u3092\\u884c\\u3046\\u6642\\u9593\\u304c\\u78ba\\u5b9f\\u306b\\u3042\\u308b\\u3068\\u306f\\u3044\\u3048\\u307e\\u305b\\u3093\\u3002\\u3053\\u308c\\u306f\\u8a2d\\u8a08\\u4e0a\\u306e\\u6b20\\u9665\\u3067\\u3059\\u3002 </p> <p>\\u554f\\u984c\\u306f\\u3001\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3092\\u505c\\u6b62\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u3053\\u3068\\u3092\\u4f1d\\u3048\\u308b\\u305f\\u3081\\u306b\\u30b7\\u30b0\\u30ca\\u30eb\\u3092\\u4f7f\\u7528\\u3057\\u305f\\u3053\\u3068\\u3067\\u3059\\u3002\\u30ea\\u30bd\\u30fc\\u30b9\\u304c\\u9589\\u3058\\u3089\\u308c\\u308b\\u307e\\u3067\\u3001\\u89aa\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3092\\u30d6\\u30ed\\u30c3\\u30af\\u3057\\u307e\\u305b\\u3093\\u3067\\u3057\\u305f\\u3002\\u305d\\u3046\\u306a\\u3089\\u306a\\u3044\\u3088\\u3046\\u306b\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> <pre><code>func main() {\\n    w := newWatcher()\\n    defer w.close()\\n    // \\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u5b9f\\u884c\\u3059\\u308b\\n}\\n\\nfunc newWatcher() watcher {\\n    w := watcher{}\\n    go w.watch()\\n    return w\\n}\\n\\nfunc (w watcher) close() {\\n    // \\u30ea\\u30bd\\u30fc\\u30b9\\u3092\\u9589\\u3058\\u308b\\n}\\n</code></pre> <p>\\u30ea\\u30bd\\u30fc\\u30b9\\u3092\\u9589\\u3058\\u308b\\u6642\\u9593\\u306b\\u306a\\u3063\\u305f\\u3053\\u3068\\u3092 <code>watcher</code> \\u306b\\u901a\\u77e5\\u3059\\u308b\\u4ee3\\u308f\\u308a\\u306b\\u3001 <code>defer</code> \\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3053\\u306e\\u3000<code>close</code> \\u30e1\\u30bd\\u30c3\\u30c9\\u3092\\u547c\\u3073\\u51fa\\u3057\\u3001\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u304c\\u7d42\\u4e86\\u3059\\u308b\\u524d\\u306b\\u30ea\\u30bd\\u30fc\\u30b9\\u304c\\u78ba\\u5b9f\\u306b\\u9589\\u3058\\u3089\\u308c\\u308b\\u3088\\u3046\\u306b\\u3057\\u307e\\u3059\\u3002 </p> <p>\\u307e\\u3068\\u3081\\u308b\\u3068\\u3001\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306f\\u4ed6\\u306e\\u30ea\\u30bd\\u30fc\\u30b9\\u3068\\u540c\\u69d8\\u3001\\u30e1\\u30e2\\u30ea\\u3084\\u4ed6\\u306e\\u30ea\\u30bd\\u30fc\\u30b9\\u3092\\u89e3\\u653e\\u3059\\u308b\\u305f\\u3081\\u306b\\u6700\\u7d42\\u7684\\u306b\\u9589\\u3058\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u3053\\u3068\\u306b\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3092\\u3044\\u3064\\u505c\\u6b62\\u3059\\u308b\\u304b\\u3092\\u77e5\\u3089\\u305a\\u306b\\u958b\\u59cb\\u3059\\u308b\\u306e\\u306f\\u8a2d\\u8a08\\u4e0a\\u306e\\u554f\\u984c\\u3067\\u3059\\u3002\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u304c\\u958b\\u59cb\\u3055\\u308c\\u308b\\u3068\\u304d\\u306f\\u5e38\\u306b\\u3001\\u3044\\u3064\\u505c\\u6b62\\u3059\\u308b\\u304b\\u306b\\u3064\\u3044\\u3066\\u660e\\u78ba\\u306a\\u8a08\\u753b\\u3092\\u7acb\\u3066\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u6700\\u5f8c\\u306b\\u306a\\u308a\\u307e\\u3057\\u305f\\u304c\\u3001\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u304c\\u30ea\\u30bd\\u30fc\\u30b9\\u3092\\u4f5c\\u6210\\u3057\\u3001\\u305d\\u306e\\u6709\\u52b9\\u671f\\u9593\\u304c\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u306e\\u5b58\\u7d9a\\u671f\\u9593\\u306b\\u30d0\\u30a4\\u30f3\\u30c9\\u3055\\u308c\\u3066\\u3044\\u308b\\u5834\\u5408\\u306f\\u3001\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u7d42\\u4e86\\u3059\\u308b\\u524d\\u306b\\u305d\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u304c\\u5b8c\\u4e86\\u3059\\u308b\\u306e\\u3092\\u5f85\\u3063\\u305f\\u65b9\\u304c\\u304a\\u305d\\u3089\\u304f\\u78ba\\u5b9f\\u3067\\u3059\\u3002\\u305d\\u3046\\u3059\\u308b\\u3053\\u3068\\u3067\\u3001\\u30ea\\u30bd\\u30fc\\u30b9\\u3092\\u9593\\u9055\\u3044\\u306a\\u304f\\u89e3\\u653e\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#63\",\"title\":\"\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3068\\u30eb\\u30fc\\u30d7\\u5909\\u6570\\u306b\\u6ce8\\u610f\\u3057\\u306a\\u3044 (#63)\",\"text\":\"\\u6ce8\\u610f <p>\\u3053\\u306e\\u30df\\u30b9\\u306f Go\\u30001.22 \\u304b\\u3089\\u306f\\u6c17\\u306b\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u305b\\u3093\\uff08\\u8a73\\u7d30\\uff09\\u3002</p>\"},{\"location\":\"ja/#select-64\",\"title\":\"<code>select</code> \\u3068\\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u6c7a\\u5b9a\\u7684\\u52d5\\u4f5c\\u3092\\u671f\\u5f85\\u3059\\u308b (#64)\",\"text\":\"\\u8981\\u7d04 <p>\\u8907\\u6570\\u306e\\u30aa\\u30d7\\u30b7\\u30e7\\u30f3\\u304c\\u53ef\\u80fd\\u306a\\u5834\\u5408\\u3001\\u8907\\u6570\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u3067 <code>select</code> \\u3059\\u308b\\u3068\\u30b1\\u30fc\\u30b9\\u304c\\u30e9\\u30f3\\u30c0\\u30e0\\u306b\\u9078\\u629e\\u3055\\u308c\\u308b\\u3053\\u3068\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3068\\u3001\\u4e26\\u884c\\u51e6\\u7406\\u306b\\u304a\\u3051\\u308b\\u8efd\\u5fae\\u306a\\u30d0\\u30b0\\u306b\\u3064\\u306a\\u304c\\u308b\\u53ef\\u80fd\\u6027\\u306e\\u3042\\u308b\\u8aa4\\u3063\\u305f\\u4eee\\u5b9a\\u3092\\u7acb\\u3066\\u308b\\u3053\\u3068\\u304c\\u306a\\u304f\\u306a\\u308a\\u307e\\u3059\\u3002</p> <p>Go \\u958b\\u767a\\u8005\\u304c\\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u64cd\\u4f5c\\u3059\\u308b\\u3068\\u304d\\u306b\\u3042\\u308a\\u304c\\u3061\\u306a\\u9593\\u9055\\u3044\\u306e 1 \\u3064\\u306f\\u3001select \\u304c\\u8907\\u6570\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u3067\\u3069\\u306e\\u3088\\u3046\\u306b\\u52d5\\u4f5c\\u3059\\u308b\\u304b\\u306b\\u3064\\u3044\\u3066\\u8aa4\\u3063\\u305f\\u7406\\u89e3\\u3092\\u3059\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002 </p> <p>\\u305f\\u3068\\u3048\\u3070\\u3001\\u6b21\\u306e\\u5834\\u5408\\u3092\\u8003\\u3048\\u3066\\u307f\\u307e\\u3057\\u3087\\u3046\\uff08 <code>disconnectCh</code> \\u306f\\u30d0\\u30c3\\u30d5\\u30a1\\u306a\\u3057\\u30c1\\u30e3\\u30cd\\u30eb\\u3067\\u3059\\uff09\\u3002</p> <pre><code>go func() {\\n  for i := 0; i &lt; 10; i++ {\\n      messageCh &lt;- i\\n    }\\n    disconnectCh &lt;- struct{}{}\\n}()\\n\\nfor {\\n    select {\\n    case v := &lt;-messageCh:\\n        fmt.Println(v)\\n    case &lt;-disconnectCh:\\n        fmt.Println(\\\"disconnection, return\\\")\\n        return\\n    }\\n}\\n</code></pre> <p>\\u3053\\u306e\\u4f8b\\u3092\\u8907\\u6570\\u56de\\u5b9f\\u884c\\u3057\\u305f\\u5834\\u5408\\u3001\\u7d50\\u679c\\u306f\\u30e9\\u30f3\\u30c0\\u30e0\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002</p> <pre><code>0\\n1\\n2\\ndisconnection, return\\n\\n0\\ndisconnection, return\\n</code></pre> <p>\\u3069\\u3046\\u3044\\u3046\\u308f\\u3051\\u304b 10 \\u901a\\u306e\\u30e1\\u30c3\\u30bb\\u30fc\\u30b8\\u3092\\u6d88\\u8cbb\\u3059\\u308b\\u306e\\u3067\\u306f\\u306a\\u304f\\u3001\\u305d\\u306e\\u3046\\u3061\\u306e\\u6570\\u901a\\u3060\\u3051\\u3092\\u53d7\\u4fe1\\u3057\\u307e\\u3057\\u305f\\u3002\\u3053\\u308c\\u306f\\u3001\\u8907\\u6570\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u3068\\u4f75\\u7528\\u3057\\u305f\\u5834\\u5408\\u306e select \\u6587\\u306e\\u4ed5\\u69d8\\u306b\\u3088\\u308b\\u3082\\u306e\\u3067\\u3059\\uff08https:// go.dev/ref/spec\\uff09\\u3002</p> <p>Quote</p> <p>1 \\u3064\\u4ee5\\u4e0a\\u306e\\u901a\\u4fe1\\u3092\\u7d9a\\u884c\\u3067\\u304d\\u308b\\u5834\\u5408\\u3001\\u5747\\u4e00\\u306e\\u64ec\\u4f3c\\u30e9\\u30f3\\u30c0\\u30e0\\u9078\\u629e\\u306b\\u3088\\u3063\\u3066\\u3001\\u7d9a\\u884c\\u3067\\u304d\\u308b 1 \\u3064\\u306e\\u901a\\u4fe1\\u304c\\u9078\\u629e\\u3055\\u308c\\u307e\\u3059\\u3002 </p> <p>\\u6700\\u521d\\u306b\\u4e00\\u81f4\\u3057\\u305f\\u30b1\\u30fc\\u30b9\\u304c\\u512a\\u5148\\u3055\\u308c\\u308b switch \\u6587\\u3068\\u306f\\u7570\\u306a\\u308a\\u3001select \\u6587\\u306f\\u8907\\u6570\\u306e\\u30aa\\u30d7\\u30b7\\u30e7\\u30f3\\u304c\\u53ef\\u80fd\\u306a\\u5834\\u5408\\u306b\\u30e9\\u30f3\\u30c0\\u30e0\\u306b\\u9078\\u629e\\u3057\\u307e\\u3059\\u3002 </p> <p>\\u3053\\u306e\\u52d5\\u4f5c\\u306f\\u6700\\u521d\\u306f\\u5947\\u5999\\u306b\\u601d\\u3048\\u308b\\u304b\\u3082\\u3057\\u308c\\u307e\\u305b\\u3093\\u3002\\u3057\\u304b\\u3057\\u3001\\u3053\\u308c\\u306f\\u30b9\\u30bf\\u30d9\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u9632\\u3050\\u3068\\u3044\\u3046\\u7406\\u7531\\u304c\\u3042\\u3063\\u3066\\u306e\\u3053\\u3068\\u3067\\u3059\\u3002\\u6700\\u521d\\u306b\\u9078\\u629e\\u3055\\u308c\\u305f\\u901a\\u4fe1\\u304c\\u30bd\\u30fc\\u30b9\\u306e\\u9806\\u5e8f\\u306b\\u57fa\\u3065\\u3044\\u3066\\u3044\\u308b\\u3068\\u3057\\u307e\\u3059\\u3002\\u305d\\u306e\\u5834\\u5408\\u3001\\u9001\\u4fe1\\u901f\\u5ea6\\u304c\\u901f\\u3044\\u305f\\u3081\\u306b\\u3001\\u305f\\u3068\\u3048\\u3070 1 \\u3064\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u304b\\u3089\\u3057\\u304b\\u53d7\\u4fe1\\u3067\\u304d\\u306a\\u3044\\u3068\\u3044\\u3046\\u72b6\\u6cc1\\u306b\\u9665\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u3053\\u308c\\u3092\\u9632\\u3050\\u305f\\u3081\\u306b\\u3001Go\\u8a00\\u8a9e\\u306e\\u8a2d\\u8a08\\u8005\\u306f\\u30e9\\u30f3\\u30c0\\u30e0\\u9078\\u629e\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u306b\\u3057\\u307e\\u3057\\u305f\\u3002 </p> <p>\\u8907\\u6570\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u3067 <code>select</code> \\u3092\\u4f7f\\u7528\\u3059\\u308b\\u5834\\u5408\\u3001\\u8907\\u6570\\u306e\\u30aa\\u30d7\\u30b7\\u30e7\\u30f3\\u304c\\u3042\\u308b\\u306a\\u3089\\u3001\\u30bd\\u30fc\\u30b9\\u9806\\u5e8f\\u306e\\u6700\\u521d\\u306e\\u30b1\\u30fc\\u30b9\\u304c\\u81ea\\u52d5\\u7684\\u306b\\u512a\\u5148\\u3055\\u308c\\u308b\\u308f\\u3051\\u3067\\u306f\\u306a\\u3044\\u3053\\u3068\\u306b\\u6ce8\\u610f\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002\\u4ee3\\u308f\\u308a\\u306b\\u3001Go\\u8a00\\u8a9e\\u306f\\u30e9\\u30f3\\u30c0\\u30e0\\u306b\\u9078\\u629e\\u3059\\u308b\\u305f\\u3081\\u3001\\u3069\\u306e\\u30aa\\u30d7\\u30b7\\u30e7\\u30f3\\u304c\\u9078\\u629e\\u3055\\u308c\\u308b\\u304b\\u306f\\u4fdd\\u8a3c\\u3055\\u308c\\u307e\\u305b\\u3093\\u3002\\u3053\\u306e\\u52d5\\u4f5c\\u3092\\u514b\\u670d\\u3059\\u308b\\u306b\\u306f\\u3001\\u5358\\u4e00\\u306e\\u751f\\u7523\\u8005\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306e\\u5834\\u5408\\u3001\\u30d0\\u30c3\\u30d5\\u30a1\\u306a\\u3057\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u307e\\u305f\\u306f\\u5358\\u4e00\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#65\",\"title\":\"\\u901a\\u77e5\\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3044\\u306a\\u3044 (#65)\",\"text\":\"\\u8981\\u7d04 <p><code>chan struct{}</code> \\u578b\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u901a\\u77e5\\u3092\\u9001\\u4fe1\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002 </p> <p>\\u30c1\\u30e3\\u30cd\\u30eb\\u306f\\u3001\\u30b7\\u30b0\\u30ca\\u30eb\\u3092\\u4ecb\\u3057\\u3066\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u9593\\u3067\\u901a\\u4fe1\\u3059\\u308b\\u305f\\u3081\\u306e\\u30e1\\u30ab\\u30cb\\u30ba\\u30e0\\u3067\\u3059\\u3002\\u30b7\\u30b0\\u30ca\\u30eb\\u306b\\u306f\\u30c7\\u30fc\\u30bf\\u304c\\u542b\\u307e\\u308c\\u3066\\u3044\\u308b\\u304b\\u3069\\u3046\\u304b\\u306f\\u95a2\\u4fc2\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002 </p> <p>\\u5177\\u4f53\\u7684\\u306a\\u4f8b\\u3092\\u898b\\u3066\\u307f\\u307e\\u3057\\u3087\\u3046\\u3002\\u901a\\u4fe1\\u306e\\u5207\\u65ad\\u304c\\u767a\\u751f\\u3059\\u308b\\u305f\\u3073\\u306b\\u305d\\u308c\\u3092\\u901a\\u77e5\\u3059\\u308b\\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u4f5c\\u6210\\u3057\\u307e\\u3059\\u3002 1 \\u3064\\u306e\\u65b9\\u6cd5\\u3068\\u3057\\u3066\\u3001\\u3053\\u308c\\u3092 <code>chan bool</code> \\u3068\\u3057\\u3066\\u6271\\u3046\\u3053\\u3068\\u304c\\u6319\\u3052\\u3089\\u308c\\u307e\\u3059\\u3002</p> <pre><code>disconnectCh := make(chan bool)\\n</code></pre> <p>\\u3053\\u3053\\u3067\\u3001\\u305d\\u306e\\u3088\\u3046\\u306a\\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u63d0\\u4f9b\\u3059\\u308b API \\u3068\\u5bfe\\u8a71\\u3059\\u308b\\u3068\\u3057\\u307e\\u3059\\u3002\\u3053\\u308c\\u306f\\u771f\\u507d\\u5024\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u3067\\u3042\\u308b\\u305f\\u3081\\u3001<code>true</code> \\u307e\\u305f\\u306f <code>false</code> \\u306e\\u30e1\\u30c3\\u30bb\\u30fc\\u30b8\\u3092\\u53d7\\u4fe1\\u3067\\u304d\\u307e\\u3059\\u3002<code>true</code> \\u304c\\u4f55\\u3092\\u4f1d\\u3048\\u3066\\u3044\\u308b\\u304b\\u306f\\u304a\\u305d\\u3089\\u304f\\u660e\\u3089\\u304b\\u3067\\u3057\\u3087\\u3046\\u3002\\u3057\\u304b\\u3057\\u3001 <code>false</code> \\u3068\\u306f\\u4f55\\u3092\\u610f\\u5473\\u3059\\u308b\\u306e\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002\\u901a\\u4fe1\\u304c\\u5207\\u65ad\\u3055\\u308c\\u3066\\u3044\\u306a\\u3044\\u3068\\u3044\\u3046\\u3053\\u3068\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002\\u305d\\u306e\\u5834\\u5408\\u3001\\u3069\\u308c\\u304f\\u3089\\u3044\\u306e\\u983b\\u5ea6\\u3067\\u305d\\u306e\\u3088\\u3046\\u306a\\u30b7\\u30b0\\u30ca\\u30eb\\u3092\\u53d7\\u4fe1\\u3059\\u308b\\u306e\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002\\u3042\\u308b\\u3044\\u306f\\u518d\\u63a5\\u7d9a\\u3057\\u305f\\u3068\\u3044\\u3046\\u3053\\u3068\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002\\u305d\\u3082\\u305d\\u3082 <code>false</code> \\u3092\\u53d7\\u3051\\u53d6\\u308b\\u3053\\u3068\\u3092\\u671f\\u5f85\\u3059\\u3079\\u304d\\u306a\\u306e\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002\\u304a\\u305d\\u3089\\u304f <code>true</code> \\u30e1\\u30c3\\u30bb\\u30fc\\u30b8\\u3092\\u53d7\\u3051\\u53d6\\u308b\\u3053\\u3068\\u3060\\u3051\\u3092\\u671f\\u5f85\\u3059\\u3079\\u304d\\u3067\\u3057\\u3087\\u3046\\u3002 </p> <p>\\u305d\\u306e\\u5834\\u5408\\u3001\\u60c5\\u5831\\u3092\\u4f1d\\u3048\\u308b\\u305f\\u3081\\u306b\\u7279\\u5b9a\\u306e\\u5024\\u306f\\u5fc5\\u8981\\u306a\\u3044\\u3053\\u3068\\u3092\\u610f\\u5473\\u3057\\u3001\\u30c7\\u30fc\\u30bf\\u306e \\u306a\\u3044 \\u30c1\\u30e3\\u30cd\\u30eb\\u304c\\u5fc5\\u8981\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002\\u3053\\u308c\\u3092\\u51e6\\u7406\\u3059\\u308b\\u6163\\u7528\\u7684\\u306a\\u65b9\\u6cd5\\u306f\\u3001\\u7a7a\\u306e\\u69cb\\u9020\\u4f53\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u2015\\u2015 <code>chan struct{}</code>\\u2015\\u2015\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u3067\\u3059\\u3002</p>\"},{\"location\":\"ja/#nil-66\",\"title\":\"nil \\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3044\\u306a\\u3044 (#66)\",\"text\":\"\\u8981\\u7d04 <p>nil \\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u306b\\u3088\\u3063\\u3066\\u3001\\u305f\\u3068\\u3048\\u3070 <code>select</code> \\u6587\\u304b\\u3089\\u30b1\\u30fc\\u30b9\\u3092 \\u524a\\u9664 \\u3067\\u304d\\u308b\\u305f\\u3081\\u3001\\u4e26\\u884c\\u51e6\\u7406\\u3092\\u884c\\u3046\\u969b\\u306e\\u9053\\u5177\\u306e\\u4e00\\u3064\\u3068\\u3057\\u3066\\u4f7f\\u3048\\u308b\\u3088\\u3046\\u306b\\u306a\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002 </p> <p>\\u6b21\\u306e\\u30b3\\u30fc\\u30c9\\u306b\\u3088\\u3063\\u3066\\u4f55\\u304c\\u884c\\u308f\\u308c\\u308b\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002</p> <pre><code>var ch chan int\\n&lt;-ch\\n</code></pre> <p><code>ch</code> \\u306f <code>chan int</code> \\u578b\\u3067\\u3059\\u3002\\u30c1\\u30e3\\u30cd\\u30eb\\u306e\\u30bc\\u30ed\\u5024\\u306f nil \\u3067\\u3042\\u308b\\u306e\\u3067\\u3001 <code>ch</code> \\u306f <code>nil</code> \\u3067\\u3059\\u3002\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306f panic \\u3092\\u8d77\\u3053\\u3057\\u307e\\u305b\\u3093\\u3002\\u305f\\u3060\\u3057\\u3001\\u6c38\\u4e45\\u306b\\u30d6\\u30ed\\u30c3\\u30af\\u3057\\u307e\\u3059\\u3002 </p> <p>nil \\u30c1\\u30e3\\u30cd\\u30eb\\u306b\\u30e1\\u30c3\\u30bb\\u30fc\\u30b8\\u3092\\u9001\\u4fe1\\u3059\\u308b\\u5834\\u5408\\u3082\\u539f\\u7406\\u306f\\u540c\\u3058\\u3067\\u3059\\u3002\\u4ee5\\u4e0b\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306f\\u6c38\\u4e45\\u306b\\u30d6\\u30ed\\u30c3\\u30af\\u3057\\u307e\\u3059\\u3002</p> <pre><code>var ch chan int\\nch &lt;- 0\\n</code></pre> <p>\\u3067\\u306f\\u3001Go\\u8a00\\u8a9e\\u304c nil \\u30c1\\u30e3\\u30cd\\u30eb\\u3068\\u306e\\u9593\\u3067\\u30e1\\u30c3\\u30bb\\u30fc\\u30b8\\u306e\\u9001\\u53d7\\u4fe1\\u3092\\u8a31\\u53ef\\u3059\\u308b\\u76ee\\u7684\\u306f\\u4f55\\u3067\\u3057\\u3087\\u3046\\u304b\\u3002\\u305f\\u3068\\u3048\\u3070\\u30012 \\u3064\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u30de\\u30fc\\u30b8\\u3059\\u308b\\u6163\\u7528\\u7684\\u306a\\u65b9\\u6cd5\\u3092\\u5b9f\\u88c5\\u3059\\u308b\\u306e\\u306b\\u3001 nil \\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002</p> <pre><code>func merge(ch1, ch2 &lt;-chan int) &lt;-chan int {\\n    ch := make(chan int, 1)\\n\\n    go func() {\\n        for ch1 != nil || ch2 != nil { // \\u6700\\u4f4e\\u3067\\u3082\\u4e00\\u3064\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u304c nil \\u3067\\u306a\\u3051\\u308c\\u3070\\u7d9a\\u884c\\u3059\\u308b\\n            select {\\n            case v, open := &lt;-ch1:\\n                if !open {\\n                    ch1 = nil // \\u9589\\u3058\\u305f\\u3089 ch1 \\u3092 nil \\u30c1\\u30e3\\u30cd\\u30eb\\u306b\\u5272\\u308a\\u5f53\\u3066\\u308b\\n                    break\\n                }\\n                ch &lt;- v\\n            case v, open := &lt;-ch2:\\n                if !open {\\n                    ch2 = nil // \\u9589\\u3058\\u305f\\u3089 ch2 \\u3092 nil \\u30c1\\u30e3\\u30cd\\u30eb\\u306b\\u5272\\u308a\\u5f53\\u3066\\u308b\\n                    break\\n                }\\n                ch &lt;- v\\n            }\\n        }\\n        close(ch)\\n    }()\\n\\n    return ch\\n}\\n</code></pre> <p>\\u3053\\u306e\\u6d17\\u7df4\\u3055\\u308c\\u305f\\u89e3\\u6c7a\\u7b56\\u306f\\u3001nil \\u30c1\\u30e3\\u30cd\\u30eb\\u3092\\u5229\\u7528\\u3057\\u3066\\u3001\\u4f55\\u3089\\u304b\\u306e\\u65b9\\u6cd5\\u3067 <code>select</code> \\u6587\\u304b\\u3089 1 \\u3064\\u306e\\u30b1\\u30fc\\u30b9\\u3092 \\u524a\\u9664 \\u3057\\u307e\\u3059\\u3002 </p> <p>nil \\u30c1\\u30e3\\u30cd\\u30eb\\u306f\\u72b6\\u6cc1\\u306b\\u3088\\u3063\\u3066\\u306f\\u4fbf\\u5229\\u3067\\u3042\\u308a\\u3001Go \\u958b\\u767a\\u8005\\u306f\\u4e26\\u884c\\u51e6\\u7406\\u3092\\u6271\\u3046\\u969b\\u306b\\u4f7f\\u3044\\u3053\\u306a\\u305b\\u308b\\u3088\\u3046\\u306b\\u306a\\u3063\\u3066\\u304a\\u304f\\u3079\\u304d\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#67\",\"title\":\"\\u30c1\\u30e3\\u30cd\\u30eb\\u306e\\u5bb9\\u91cf\\u306b\\u3064\\u3044\\u3066\\u56f0\\u60d1\\u3057\\u3066\\u3044\\u308b (#67)\",\"text\":\"\\u8981\\u7d04 <p>\\u554f\\u984c\\u304c\\u767a\\u751f\\u3057\\u305f\\u5834\\u5408\\u306f\\u3001\\u4f7f\\u7528\\u3059\\u308b\\u30c1\\u30e3\\u30cd\\u30eb\\u306e\\u578b\\u3092\\u614e\\u91cd\\u306b\\u6c7a\\u5b9a\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u540c\\u671f\\u3092\\u5f37\\u529b\\u306b\\u4fdd\\u8a3c\\u3057\\u3066\\u304f\\u308c\\u308b\\u306e\\u306f\\u30d0\\u30c3\\u30d5\\u30a1\\u306a\\u3057\\u30c1\\u30e3\\u30cd\\u30eb\\u306e\\u307f\\u3067\\u3059\\u3002 </p> <p>\\u30d0\\u30c3\\u30d5\\u30a1\\u3042\\u308a\\u30c1\\u30e3\\u30cd\\u30eb\\u4ee5\\u5916\\u306e\\u30c1\\u30e3\\u30cd\\u30eb\\u306e\\u5bb9\\u91cf\\u3092\\u6307\\u5b9a\\u3059\\u308b\\u306b\\u306f\\u6b63\\u5f53\\u306a\\u7406\\u7531\\u304c\\u3042\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002</p>\"},{\"location\":\"ja/#etcd-68\",\"title\":\"\\u6587\\u5b57\\u5217\\u30d5\\u30a9\\u30fc\\u30de\\u30c3\\u30c8\\u3067\\u8d77\\u3053\\u308a\\u5f97\\u308b\\u526f\\u4f5c\\u7528\\u3092\\u5fd8\\u308c\\u3066\\u3057\\u307e\\u3046\\uff08 etcd \\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u306e\\u4f8b\\u3068\\u30c7\\u30c3\\u30c9\\u30ed\\u30c3\\u30af\\uff09 (#68)\",\"text\":\"\\u8981\\u7d04 <p>\\u6587\\u5b57\\u5217\\u306e\\u66f8\\u5f0f\\u8a2d\\u5b9a\\u304c\\u65e2\\u5b58\\u306e\\u95a2\\u6570\\u304c\\u547c\\u3073\\u51fa\\u3059\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u3053\\u3068\\u3092\\u8a8d\\u8b58\\u3059\\u308b\\u3053\\u3068\\u306f\\u3001\\u30c7\\u30c3\\u30c9\\u30ed\\u30c3\\u30af\\u3084\\u305d\\u306e\\u4ed6\\u306e\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u306e\\u53ef\\u80fd\\u6027\\u306b\\u6ce8\\u610f\\u3059\\u308b\\u3053\\u3068\\u3092\\u610f\\u5473\\u3057\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#append-69\",\"title\":\"<code>append</code> \\u3067\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u3092\\u8d77\\u3053\\u3057\\u3066\\u3057\\u307e\\u3046 (#69)\",\"text\":\"\\u8981\\u7d04 <p><code>append</code> \\u306e\\u547c\\u3073\\u51fa\\u3057\\u306f\\u5fc5\\u305a\\u3057\\u3082\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u304c\\u306a\\u3044\\u308f\\u3051\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002\\u3086\\u3048\\u306b\\u3001\\u5171\\u6709\\u30b9\\u30e9\\u30a4\\u30b9\\u4e0a\\u3067\\u540c\\u6642\\u306b\\u4f7f\\u7528\\u3057\\u3066\\u306f\\u3044\\u3051\\u307e\\u305b\\u3093\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#70\",\"title\":\"\\u30b9\\u30e9\\u30a4\\u30b9\\u3068\\u30de\\u30c3\\u30d7\\u3067\\u30df\\u30e5\\u30fc\\u30c6\\u30c3\\u30af\\u30b9\\u3092\\u6b63\\u3057\\u304f\\u4f7f\\u7528\\u3057\\u3066\\u3044\\u306a\\u3044 (#70)\",\"text\":\"\\u8981\\u7d04 <p>\\u30b9\\u30e9\\u30a4\\u30b9\\u3068\\u30de\\u30c3\\u30d7\\u306f\\u30dd\\u30a4\\u30f3\\u30bf\\u3067\\u3042\\u308b\\u3053\\u3068\\u3092\\u899a\\u3048\\u3066\\u304a\\u304f\\u3068\\u3001\\u5178\\u578b\\u7684\\u306a\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u3092\\u9632\\u3050\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#syncwaitgroup-71\",\"title\":\"<code>sync.WaitGroup</code> \\u3092\\u6b63\\u3057\\u304f\\u4f7f\\u7528\\u3057\\u3066\\u3044\\u306a\\u3044 (#71)\",\"text\":\"\\u8981\\u7d04 <p><code>sync.WaitGroup</code> \\u3092\\u6b63\\u3057\\u304f\\u4f7f\\u7528\\u3059\\u308b\\u306b\\u306f\\u3001\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u3092\\u8d77\\u52d5\\u3059\\u308b\\u524d\\u306b <code>Add</code> \\u30e1\\u30bd\\u30c3\\u30c9\\u3092\\u547c\\u3073\\u51fa\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#synccond-72\",\"title\":\"<code>sync.Cond</code> \\u306b\\u3064\\u3044\\u3066\\u5fd8\\u308c\\u3066\\u3057\\u307e\\u3046 (#72)\",\"text\":\"\\u8981\\u7d04 <p><code>sync.Cond</code> \\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u3001\\u8907\\u6570\\u306e\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306b\\u7e70\\u308a\\u8fd4\\u3057\\u901a\\u77e5\\u3092\\u9001\\u4fe1\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#errgroup-73\",\"title\":\"<code>errgroup</code> \\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3044\\u306a\\u3044 (#73)\",\"text\":\"\\u8981\\u7d04 <p><code>errgroup</code> \\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3001\\u30b4\\u30eb\\u30fc\\u30c1\\u30f3\\u306e\\u30b0\\u30eb\\u30fc\\u30d7\\u3092\\u540c\\u671f\\u3057\\u3001\\u30a8\\u30e9\\u30fc\\u3068 Context \\u3092\\u51e6\\u7406\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#sync-74\",\"title\":\"<code>sync</code> \\u578b\\u306e\\u30b3\\u30d4\\u30fc (#74)\",\"text\":\"\\u8981\\u7d04 <p><code>sync</code> \\u578b\\u306f\\u30b3\\u30d4\\u30fc\\u3055\\u308c\\u308b\\u3079\\u304d\\u3067\\u306f\\u3042\\u308a\\u307e\\u305b\\u3093\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#_15\",\"title\":\"\\u6a19\\u6e96\\u30e9\\u30a4\\u30d6\\u30e9\\u30ea\",\"text\":\"\"},{\"location\":\"ja/#75\",\"title\":\"\\u9593\\u9055\\u3063\\u305f\\u6642\\u9593\\u3092\\u6307\\u5b9a\\u3059\\u308b (#75)\",\"text\":\"\\u8981\\u7d04 <p><code>time.Duration</code> \\u3092\\u53d7\\u3051\\u5165\\u308c\\u308b\\u95a2\\u6570\\u306b\\u306f\\u6ce8\\u610f\\u3092\\u6255\\u3063\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002\\u6574\\u6570\\u3092\\u6e21\\u3059\\u3053\\u3068\\u306f\\u8a31\\u53ef\\u3055\\u308c\\u3066\\u3044\\u307e\\u3059\\u304c\\u3001\\u6df7\\u4e71\\u3092\\u62db\\u304b\\u306a\\u3044\\u3088\\u3046\\u306b time API \\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3088\\u3046\\u52aa\\u3081\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u6a19\\u6e96\\u30e9\\u30a4\\u30d6\\u30e9\\u30ea\\u306e\\u591a\\u304f\\u306e\\u95a2\\u6570\\u306f\\u3001<code>int64</code> \\u578b\\u306e\\u30a8\\u30a4\\u30ea\\u30a2\\u30b9\\u3067\\u3042\\u308b <code>time.Duration</code> \\u3092\\u53d7\\u3051\\u5165\\u308c\\u307e\\u3059\\u3002\\u305f\\u3060\\u3057\\u30011 \\u5358\\u4f4d\\u306e <code>time.Duration</code> \\u306f\\u3001\\u4ed6\\u306e\\u30d7\\u30ed\\u30b0\\u30e9\\u30df\\u30f3\\u30b0\\u8a00\\u8a9e\\u3067\\u4e00\\u822c\\u7684\\u306b\\u898b\\u3089\\u308c\\u308b 1 \\u30df\\u30ea\\u79d2\\u3067\\u306f\\u306a\\u304f\\u30011 \\u30ca\\u30ce\\u79d2\\u3092\\u8868\\u3057\\u307e\\u3059\\u3002\\u305d\\u306e\\u7d50\\u679c\\u3001<code>time.Duration</code> API \\u3092\\u4f7f\\u7528\\u3059\\u308b\\u4ee3\\u308f\\u308a\\u306b\\u6570\\u5024\\u578b\\u3092\\u6e21\\u3059\\u3068\\u3001\\u4e88\\u60f3\\u5916\\u306e\\u52d5\\u4f5c\\u304c\\u767a\\u751f\\u3059\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002 </p> <p>\\u4ed6\\u8a00\\u8a9e\\u3092\\u4f7f\\u7528\\u3057\\u305f\\u3053\\u3068\\u306e\\u3042\\u308b\\u958b\\u767a\\u8005\\u306e\\u65b9\\u306f\\u3001\\u6b21\\u306e\\u30b3\\u30fc\\u30c9\\u306b\\u3088\\u3063\\u3066 1 \\u79d2\\u5468\\u671f\\u306e\\u65b0\\u3057\\u3044 <code>time.Ticker</code> \\u304c\\u751f\\u6210\\u3055\\u308c\\u308b\\u3068\\u8003\\u3048\\u308b\\u304b\\u3082\\u3057\\u308c\\u307e\\u305b\\u3093\\u3002</p> <pre><code>ticker := time.NewTicker(1000)\\nfor {\\n    select {\\n    case &lt;-ticker.C:\\n        // \\u51e6\\u7406\\u3092\\u3059\\u308b\\n    }\\n}\\n</code></pre> <p>\\u3057\\u304b\\u3057\\u306a\\u304c\\u3089\\u30011,000 <code>time.Duration</code> = 1,000 \\u30ca\\u30ce\\u79d2\\u3067\\u3042\\u308b\\u305f\\u3081\\u3001\\u60f3\\u5b9a\\u3055\\u308c\\u3066\\u3044\\u308b 1\\u79d2 \\u3067\\u306f\\u306a\\u304f\\u30011,000 \\u30ca\\u30ce\\u79d2 = 1 \\u30de\\u30a4\\u30af\\u30ed\\u79d2\\u306e\\u5468\\u671f\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002 </p> <p>\\u6df7\\u4e71\\u3084\\u4e88\\u60f3\\u5916\\u306e\\u52d5\\u4f5c\\u3092\\u62db\\u304b\\u306a\\u3044\\u3088\\u3046\\u3001\\u3044\\u3064\\u3082 <code>time.Duration</code> API \\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3079\\u304d\\u3067\\u3059\\u3002</p> <pre><code>ticker = time.NewTicker(time.Microsecond)\\n// \\u3082\\u3057\\u304f\\u306f\\nticker = time.NewTicker(1000 * time.Nanosecond)\\n</code></pre> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#timeafter-76\",\"title\":\"<code>time.After</code> \\u3068\\u30e1\\u30e2\\u30ea\\u30ea\\u30fc\\u30af (#76)\",\"text\":\"\\u8981\\u7d04 <p>\\u7e70\\u308a\\u8fd4\\u3055\\u308c\\u308b\\u95a2\\u6570\\uff08\\u30eb\\u30fc\\u30d7\\u3084 HTTP \\u30cf\\u30f3\\u30c9\\u30e9\\u306a\\u3069\\uff09\\u3067 <code>time.After</code> \\u306e\\u547c\\u3073\\u51fa\\u3057\\u3092\\u56de\\u907f\\u3059\\u308b\\u3068\\u3001\\u30d4\\u30fc\\u30af\\u6642\\u306e\\u30e1\\u30e2\\u30ea\\u6d88\\u8cbb\\u3092\\u56de\\u907f\\u3067\\u304d\\u307e\\u3059\\u3002<code>time.After</code> \\u306b\\u3088\\u3063\\u3066\\u751f\\u6210\\u3055\\u308c\\u305f\\u30ea\\u30bd\\u30fc\\u30b9\\u306f\\u3001 timer \\u304c\\u7d42\\u4e86\\u3057\\u305f\\u3068\\u304d\\u306b\\u306e\\u307f\\u89e3\\u653e\\u3055\\u308c\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#json-77\",\"title\":\"JSON \\u51e6\\u7406\\u3067\\u3042\\u308a\\u304c\\u3061\\u306a\\u9593\\u9055\\u3044 (#77)\",\"text\":\"<ul> <li>\\u578b\\u306e\\u57cb\\u3081\\u8fbc\\u307f\\u306b\\u3088\\u308b\\u4e88\\u60f3\\u5916\\u306e\\u52d5\\u4f5c </li> </ul> <p>Go \\u69cb\\u9020\\u4f53\\u3067\\u57cb\\u3081\\u8fbc\\u307f\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u5834\\u5408\\u306f\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002 \\u306a\\u305c\\u306a\\u3089 <code>json.Marshaler</code> \\u30a4\\u30f3\\u30bf\\u30d5\\u30a7\\u30fc\\u30b9\\u3092\\u5b9f\\u88c5\\u3059\\u308b time.Time \\u57cb\\u3081\\u8fbc\\u307f\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u306e\\u3088\\u3046\\u306a\\u3084\\u3063\\u304b\\u3044\\u306a\\u30d0\\u30b0\\u304c\\u767a\\u751f\\u3057\\u3066\\u3001\\u30c7\\u30d5\\u30a9\\u30eb\\u30c8\\u306e\\u30de\\u30fc\\u30b7\\u30e3\\u30ea\\u30f3\\u30b0\\u52d5\\u4f5c\\u304c\\u30aa\\u30fc\\u30d0\\u30fc\\u30e9\\u30a4\\u30c9\\u3055\\u308c\\u308b\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u304b\\u3089\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p> <ul> <li>JSON \\u3068 monotonic clock</li> </ul> <p>2 \\u3064\\u306e <code>time.Time</code> \\u69cb\\u9020\\u4f53\\u3092\\u6bd4\\u8f03\\u3059\\u308b\\u5834\\u5408\\u3001<code>time.Time</code> \\u306b\\u306f wall clock \\u3068 monotonic clock \\u306e\\u4e21\\u65b9\\u304c\\u542b\\u307e\\u308c\\u3066\\u304a\\u308a\\u3001== \\u6f14\\u7b97\\u5b50\\u3092\\u4f7f\\u7528\\u3057\\u305f\\u6bd4\\u8f03\\u306f\\u4e21\\u65b9\\u306e clock \\u306b\\u5bfe\\u3057\\u3066\\u884c\\u308f\\u308c\\u308b\\u3053\\u3068\\u3092\\u601d\\u3044\\u51fa\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p> <ul> <li><code>any</code> \\u306e\\u30de\\u30c3\\u30d7</li> </ul> <p>JSON \\u30c7\\u30fc\\u30bf\\u306e\\u30a2\\u30f3\\u30de\\u30fc\\u30b7\\u30e3\\u30ea\\u30f3\\u30b0\\u4e2d\\u306b\\u30de\\u30c3\\u30d7\\u3092\\u63d0\\u4f9b\\u3059\\u308b\\u3068\\u304d\\u306b\\u9593\\u9055\\u3044\\u3092\\u907f\\u3051\\u308b\\u305f\\u3081\\u306b\\u3001\\u6570\\u5024\\u306f\\u30c7\\u30d5\\u30a9\\u30eb\\u30c8\\u3067 <code>float64</code> \\u306b\\u5909\\u63db\\u3055\\u308c\\u308b\\u3053\\u3068\\u306b\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#sql-78\",\"title\":\"SQL \\u3067\\u3042\\u308a\\u304c\\u3061\\u306a\\u9593\\u9055\\u3044 (#78)\",\"text\":\"<ul> <li><code>sql.Open</code> \\u304c\\u5fc5\\u305a\\u3057\\u3082\\u30c7\\u30fc\\u30bf\\u30d9\\u30fc\\u30b9\\u3078\\u306e\\u63a5\\u7d9a\\u3092\\u78ba\\u7acb\\u3059\\u308b\\u308f\\u3051\\u3067\\u306f\\u306a\\u3044\\u3053\\u3068\\u3092\\u5fd8\\u308c\\u3066\\u3044\\u308b</li> </ul> <p>\\u8a2d\\u5b9a\\u3092\\u8a66\\u3057\\u3001\\u30c7\\u30fc\\u30bf\\u30d9\\u30fc\\u30b9\\u306b\\u30a2\\u30af\\u30bb\\u30b9\\u3067\\u304d\\u308b\\u3053\\u3068\\u3092\\u78ba\\u8a8d\\u3059\\u308b\\u5fc5\\u8981\\u304c\\u3042\\u308b\\u5834\\u5408\\u306f\\u3001 <code>Ping</code> \\u307e\\u305f\\u306f <code>PingContext</code> \\u30e1\\u30bd\\u30c3\\u30c9\\u3092\\u547c\\u3073\\u51fa\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p> <ul> <li>\\u30b3\\u30cd\\u30af\\u30b7\\u30e7\\u30f3\\u30d7\\u30fc\\u30ea\\u30f3\\u30b0\\u306e\\u3053\\u3068\\u3092\\u5fd8\\u308c\\u308b </li> </ul> <p>\\u5b9f\\u904b\\u7528\\u6c34\\u6e96\\u306e\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3067\\u306f\\u3001\\u30c7\\u30fc\\u30bf\\u30d9\\u30fc\\u30b9\\u63a5\\u7d9a\\u30d1\\u30e9\\u30e1\\u30fc\\u30bf\\u3092\\u8a2d\\u5b9a\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> <ul> <li>\\u30d7\\u30ea\\u30da\\u30a2\\u30c9\\u30b9\\u30c6\\u30fc\\u30c8\\u30e1\\u30f3\\u30c8\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3044\\u306a\\u3044</li> </ul> <p>SQL \\u306e\\u30d7\\u30ea\\u30da\\u30a2\\u30c9\\u30b9\\u30c6\\u30fc\\u30c8\\u30e1\\u30f3\\u30c8\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u3001\\u30af\\u30a8\\u30ea\\u304c\\u3088\\u308a\\u52b9\\u7387\\u7684\\u304b\\u3064\\u78ba\\u5b9f\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p> <ul> <li>null \\u5024\\u3092\\u8aa4\\u3063\\u305f\\u65b9\\u6cd5\\u3067\\u51e6\\u7406\\u3057\\u3066\\u3044\\u308b</li> </ul> <p>\\u30c6\\u30fc\\u30d6\\u30eb\\u5185\\u306e null \\u304c\\u8a31\\u5bb9\\u3055\\u308c\\u3066\\u3044\\u308b\\u5217\\u306f\\u3001\\u30dd\\u30a4\\u30f3\\u30bf\\u307e\\u305f\\u306f <code>sql.NullXXX</code> \\u578b\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u51e6\\u7406\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p> <ul> <li>\\u884c\\u306e\\u53cd\\u5fa9\\u51e6\\u7406\\u306b\\u3088\\u308b\\u30a8\\u30e9\\u30fc\\u3092\\u51e6\\u7406\\u3057\\u306a\\u3044 </li> </ul> <p>\\u884c\\u306e\\u53cd\\u5fa9\\u51e6\\u7406\\u306e\\u5f8c\\u306b <code>sql.Rows</code> \\u306e <code>Err</code> \\u30e1\\u30bd\\u30c3\\u30c9\\u3092\\u547c\\u3073\\u51fa\\u3057\\u3066\\u3001\\u6b21\\u306e\\u884c\\u306e\\u6e96\\u5099\\u4e2d\\u306b\\u30a8\\u30e9\\u30fc\\u3092\\u898b\\u9003\\u3057\\u3066\\u3044\\u306a\\u3044\\u3053\\u3068\\u3092\\u78ba\\u8a8d\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#http-bodysqlrows-osfile-79\",\"title\":\"\\u4e00\\u6642\\u7684\\u306a\\u30ea\\u30bd\\u30fc\\u30b9\\uff08 HTTP body\\u3001<code>sql.Rows</code>\\u3001\\u304a\\u3088\\u3073 <code>os.File</code> \\uff09\\u3092\\u9589\\u3058\\u3066\\u3044\\u306a\\u3044 (#79)\",\"text\":\"\\u8981\\u7d04 <p>\\u30ea\\u30fc\\u30af\\u3092\\u907f\\u3051\\u308b\\u305f\\u3081\\u306b\\u3001 <code>io.Closer</code> \\u3092\\u5b9f\\u88c5\\u3057\\u3066\\u3044\\u308b\\u3059\\u3079\\u3066\\u306e\\u69cb\\u9020\\u4f53\\u3092\\u6700\\u5f8c\\u306b\\u306f\\u9589\\u3058\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#http-return-80\",\"title\":\"HTTP \\u30ea\\u30af\\u30a8\\u30b9\\u30c8\\u306b\\u5fdc\\u7b54\\u3057\\u305f\\u5f8c\\u306e return \\u6587\\u3092\\u5fd8\\u308c\\u3066\\u3057\\u307e\\u3046 (#80)\",\"text\":\"\\u8981\\u7d04 <p>HTTP \\u30cf\\u30f3\\u30c9\\u30e9\\u306e\\u5b9f\\u88c5\\u3067\\u306e\\u4e88\\u60f3\\u5916\\u306e\\u52d5\\u4f5c\\u3092\\u907f\\u3051\\u308b\\u305f\\u3081\\u3001<code>http.Error</code> \\u306e\\u5f8c\\u306b\\u30cf\\u30f3\\u30c9\\u30e9\\u3092\\u505c\\u6b62\\u3057\\u305f\\u3044\\u5834\\u5408\\u306f\\u3001<code>return</code> \\u6587\\u3092\\u5fd8\\u308c\\u306a\\u3044\\u3088\\u3046\\u306b\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#http-81\",\"title\":\"\\u6a19\\u6e96\\u306e HTTP \\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u3068\\u30b5\\u30fc\\u30d0\\u30fc\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3044\\u308b (#81)\",\"text\":\"\\u8981\\u7d04 <p>\\u5b9f\\u904b\\u7528\\u6c34\\u6e96\\u306e\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u6c42\\u3081\\u3066\\u3044\\u308b\\u5834\\u5408\\u306f\\u3001\\u6a19\\u6e96\\u306e HTTP \\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u3068\\u30b5\\u30fc\\u30d0\\u30fc\\u306e\\u5b9f\\u88c5\\u3092\\u4f7f\\u7528\\u3057\\u306a\\u3044\\u3067\\u304f\\u3060\\u3055\\u3044\\u3002\\u3053\\u308c\\u3089\\u306e\\u5b9f\\u88c5\\u306b\\u306f\\u3001\\u30bf\\u30a4\\u30e0\\u30a2\\u30a6\\u30c8\\u3084\\u7a3c\\u50cd\\u74b0\\u5883\\u3067\\u5fc5\\u9808\\u3067\\u3042\\u308b\\u3079\\u304d\\u52d5\\u4f5c\\u304c\\u6b20\\u843d\\u3057\\u3066\\u3044\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#_16\",\"title\":\"\\u30c6\\u30b9\\u30c8\",\"text\":\"\"},{\"location\":\"ja/#82\",\"title\":\"\\u30c6\\u30b9\\u30c8\\u3092\\u5206\\u985e\\u3057\\u3066\\u3044\\u306a\\u3044\\uff08\\u30d3\\u30eb\\u30c9\\u30bf\\u30b0\\u3001\\u74b0\\u5883\\u5909\\u6570\\u3001\\u30b7\\u30e7\\u30fc\\u30c8\\u30e2\\u30fc\\u30c9\\uff09 (#82)\",\"text\":\"\\u8981\\u7d04 <p>\\u30d3\\u30eb\\u30c9\\u30d5\\u30e9\\u30b0\\u3001\\u74b0\\u5883\\u5909\\u6570\\u3001\\u307e\\u305f\\u306f\\u30b7\\u30e7\\u30fc\\u30c8\\u30e2\\u30fc\\u30c9\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u30c6\\u30b9\\u30c8\\u3092\\u5206\\u985e\\u3059\\u308b\\u3068\\u3001\\u30c6\\u30b9\\u30c8\\u30d7\\u30ed\\u30bb\\u30b9\\u304c\\u3088\\u308a\\u52b9\\u7387\\u7684\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002\\u30d3\\u30eb\\u30c9\\u30d5\\u30e9\\u30b0\\u307e\\u305f\\u306f\\u74b0\\u5883\\u5909\\u6570\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u30c6\\u30b9\\u30c8\\u30ab\\u30c6\\u30b4\\u30ea\\uff08\\u305f\\u3068\\u3048\\u3070\\u3001\\u5358\\u4f53\\u30c6\\u30b9\\u30c8\\u3068\\u7d71\\u5408\\u30c6\\u30b9\\u30c8\\uff09\\u3092\\u4f5c\\u6210\\u3057\\u3001\\u77ed\\u671f\\u9593\\u306e\\u30c6\\u30b9\\u30c8\\u3068\\u9577\\u6642\\u9593\\u306e\\u30c6\\u30b9\\u30c8\\u3092\\u533a\\u5225\\u3059\\u308b\\u3053\\u3068\\u3067\\u3001\\u5b9f\\u884c\\u3059\\u308b\\u30c6\\u30b9\\u30c8\\u306e\\u7a2e\\u985e\\u3092\\u6c7a\\u5b9a\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#-race-83\",\"title\":\"<code>-race</code> \\u30d5\\u30e9\\u30b0\\u3092\\u6709\\u52b9\\u306b\\u3057\\u3066\\u3044\\u306a\\u3044 (#83)\",\"text\":\"\\u8981\\u7d04 <p>\\u4e26\\u884c\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u4f5c\\u6210\\u3059\\u308b\\u5834\\u5408\\u306f\\u3001 <code>-race</code> \\u30d5\\u30e9\\u30b0\\u3092\\u6709\\u52b9\\u306b\\u3059\\u308b\\u3053\\u3068\\u3092\\u5f37\\u304f\\u304a\\u52e7\\u3081\\u3057\\u307e\\u3059\\u3002\\u305d\\u3046\\u3059\\u308b\\u3053\\u3068\\u3067\\u3001\\u30bd\\u30d5\\u30c8\\u30a6\\u30a7\\u30a2\\u306e\\u30d0\\u30b0\\u306b\\u3064\\u306a\\u304c\\u308b\\u53ef\\u80fd\\u6027\\u306e\\u3042\\u308b\\u6f5c\\u5728\\u7684\\u306a\\u30c7\\u30fc\\u30bf\\u7af6\\u5408\\u3092\\u767a\\u898b\\u3067\\u304d\\u308b\\u3088\\u3046\\u306b\\u306a\\u308a\\u307e\\u3059\\u3002</p>\"},{\"location\":\"ja/#-parallel-shuffle-84\",\"title\":\"\\u30c6\\u30b9\\u30c8\\u5b9f\\u884c\\u30e2\\u30fc\\u30c9\\uff08 <code>-parallel</code> \\u304a\\u3088\\u3073 <code>-shuffle</code> \\uff09\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3044\\u306a\\u3044 (#84)\",\"text\":\"\\u8981\\u7d04 <p><code>-parallel</code> \\u30d5\\u30e9\\u30b0\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u306e\\u306f\\u3001\\u7279\\u306b\\u9577\\u6642\\u9593\\u5b9f\\u884c\\u3055\\u308c\\u308b\\u30c6\\u30b9\\u30c8\\u3092\\u9ad8\\u901f\\u5316\\u3059\\u308b\\u306e\\u306b\\u52b9\\u679c\\u7684\\u3067\\u3059\\u3002 <code>-shuffle</code> \\u30d5\\u30e9\\u30b0\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3068\\u3001\\u30c6\\u30b9\\u30c8\\u30b9\\u30a4\\u30fc\\u30c8\\u304c\\u30d0\\u30b0\\u3092\\u96a0\\u3059\\u53ef\\u80fd\\u6027\\u306e\\u3042\\u308b\\u9593\\u9055\\u3063\\u305f\\u4eee\\u5b9a\\u306b\\u4f9d\\u5b58\\u3057\\u306a\\u3044\\u3088\\u3046\\u306b\\u3059\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002</p>\"},{\"location\":\"ja/#85\",\"title\":\"\\u30c6\\u30fc\\u30d6\\u30eb\\u99c6\\u52d5\\u30c6\\u30b9\\u30c8\\u3092\\u4f7f\\u7528\\u3057\\u306a\\u3044 (#85)\",\"text\":\"\\u8981\\u7d04 <p>\\u30c6\\u30fc\\u30d6\\u30eb\\u99c6\\u52d5\\u30c6\\u30b9\\u30c8\\u306f\\u3001\\u30b3\\u30fc\\u30c9\\u306e\\u91cd\\u8907\\u3092\\u9632\\u304e\\u3001\\u5c06\\u6765\\u306e\\u66f4\\u65b0\\u306e\\u51e6\\u7406\\u3092\\u5bb9\\u6613\\u306b\\u3059\\u308b\\u305f\\u3081\\u306b\\u3001\\u4e00\\u9023\\u306e\\u985e\\u4f3c\\u3057\\u305f\\u30c6\\u30b9\\u30c8\\u3092\\u30b0\\u30eb\\u30fc\\u30d7\\u5316\\u3059\\u308b\\u52b9\\u7387\\u7684\\u306a\\u65b9\\u6cd5\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#86\",\"title\":\"\\u5358\\u4f53\\u30c6\\u30b9\\u30c8\\u3067\\u306e\\u30b9\\u30ea\\u30fc\\u30d7 (#86)\",\"text\":\"\\u8981\\u7d04 <p>\\u30c6\\u30b9\\u30c8\\u306e\\u4e0d\\u5b89\\u5b9a\\u3055\\u3092\\u306a\\u304f\\u3057\\u3001\\u3088\\u308a\\u5805\\u7262\\u306b\\u3059\\u308b\\u305f\\u3081\\u306b\\u3001\\u540c\\u671f\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u30b9\\u30ea\\u30fc\\u30d7\\u3092\\u56de\\u907f\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002\\u540c\\u671f\\u304c\\u4e0d\\u53ef\\u80fd\\u306a\\u5834\\u5408\\u306f\\u3001\\u30ea\\u30c8\\u30e9\\u30a4\\u624b\\u6cd5\\u3092\\u691c\\u8a0e\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#time-api-87\",\"title\":\"time API \\u3092\\u52b9\\u7387\\u7684\\u306b\\u51e6\\u7406\\u3067\\u304d\\u3066\\u3044\\u306a\\u3044 (#87)\",\"text\":\"\\u8981\\u7d04 <p>time API \\u3092\\u4f7f\\u7528\\u3057\\u3066\\u95a2\\u6570\\u3092\\u51e6\\u7406\\u3059\\u308b\\u65b9\\u6cd5\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3053\\u3068\\u3067\\u3001\\u30c6\\u30b9\\u30c8\\u306e\\u4e0d\\u5b89\\u5b9a\\u3055\\u3092\\u8efd\\u6e1b\\u3059\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002\\u96a0\\u308c\\u305f\\u4f9d\\u5b58\\u95a2\\u4fc2\\u306e\\u4e00\\u90e8\\u3068\\u3057\\u3066 time \\u3092\\u51e6\\u7406\\u3057\\u305f\\u308a\\u3001\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u306b time \\u3092\\u63d0\\u4f9b\\u3059\\u308b\\u3088\\u3046\\u306b\\u8981\\u6c42\\u3057\\u305f\\u308a\\u3059\\u308b\\u306a\\u3069\\u3001\\u6a19\\u6e96\\u7684\\u306a\\u624b\\u6bb5\\u3092\\u5229\\u7528\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#httptest-iotest-88\",\"title\":\"\\u30c6\\u30b9\\u30c8\\u306b\\u95a2\\u3059\\u308b\\u30e6\\u30fc\\u30c6\\u30a3\\u30ea\\u30c6\\u30a3\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\uff08 <code>httptest</code> \\u304a\\u3088\\u3073 <code>iotest</code> \\uff09\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3044\\u306a\\u3044 (#88)\",\"text\":\"<ul> <li><code>httptest</code> \\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306f\\u3001HTTP \\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u6271\\u3046\\u306e\\u306b\\u5f79\\u7acb\\u3061\\u307e\\u3059\\u3002\\u30af\\u30e9\\u30a4\\u30a2\\u30f3\\u30c8\\u3068\\u30b5\\u30fc\\u30d0\\u30fc\\u306e\\u4e21\\u65b9\\u3092\\u30c6\\u30b9\\u30c8\\u3059\\u308b\\u305f\\u3081\\u306e\\u4e00\\u9023\\u306e\\u30e6\\u30fc\\u30c6\\u30a3\\u30ea\\u30c6\\u30a3\\u3092\\u63d0\\u4f9b\\u3057\\u307e\\u3059\\u3002</li> </ul> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p> <ul> <li><code>iotest</code> \\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306f\\u3001io.Reader \\u3092\\u4f5c\\u6210\\u3057\\u3001\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u306e\\u30a8\\u30e9\\u30fc\\u8010\\u6027\\u3092\\u30c6\\u30b9\\u30c8\\u3059\\u308b\\u306e\\u306b\\u5f79\\u7acb\\u3061\\u307e\\u3059\\u3002</li> </ul> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#89\",\"title\":\"\\u4e0d\\u6b63\\u78ba\\u306a\\u30d9\\u30f3\\u30c1\\u30de\\u30fc\\u30af\\u306e\\u4f5c\\u6210 (#89)\",\"text\":\"\\u8981\\u7d04 <p>\\u30d9\\u30f3\\u30c1\\u30de\\u30fc\\u30af\\u306b\\u3064\\u3044\\u3066</p> <ul> <li>\\u30d9\\u30f3\\u30c1\\u30de\\u30fc\\u30af\\u306e\\u7cbe\\u5ea6\\u3092\\u7dad\\u6301\\u3059\\u308b\\u306b\\u306f\\u3001time \\u30e1\\u30bd\\u30c3\\u30c9\\u3092\\u4f7f\\u7528\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002 </li> <li>\\u30d9\\u30f3\\u30c1\\u30bf\\u30a4\\u30e0\\u3092\\u5897\\u3084\\u3059\\u304b\\u3001benchstat \\u306a\\u3069\\u306e\\u30c4\\u30fc\\u30eb\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3053\\u3068\\u3067\\u3001\\u30de\\u30a4\\u30af\\u30ed\\u30d9\\u30f3\\u30c1\\u30de\\u30fc\\u30af\\u304c\\u6271\\u3044\\u3084\\u3059\\u304f\\u306a\\u308a\\u307e\\u3059\\u3002 </li> <li>\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u6700\\u7d42\\u7684\\u306b\\u5b9f\\u884c\\u3059\\u308b\\u30b7\\u30b9\\u30c6\\u30e0\\u304c\\u30de\\u30a4\\u30af\\u30ed\\u30d9\\u30f3\\u30c1\\u30de\\u30fc\\u30af\\u3092\\u5b9f\\u884c\\u3059\\u308b\\u30b7\\u30b9\\u30c6\\u30e0\\u3068\\u7570\\u306a\\u308b\\u5834\\u5408\\u306f\\u3001\\u30de\\u30a4\\u30af\\u30ed\\u30d9\\u30f3\\u30c1\\u30de\\u30fc\\u30af\\u306e\\u7d50\\u679c\\u306b\\u6ce8\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002 </li> <li>\\u30b3\\u30f3\\u30d1\\u30a4\\u30e9\\u306e\\u6700\\u9069\\u5316\\u306b\\u3088\\u3063\\u3066\\u30d9\\u30f3\\u30c1\\u30de\\u30fc\\u30af\\u306e\\u7d50\\u679c\\u304c\\u8aa4\\u9b54\\u5316\\u3055\\u308c\\u306a\\u3044\\u3088\\u3046\\u3001\\u30c6\\u30b9\\u30c8\\u5bfe\\u8c61\\u306e\\u95a2\\u6570\\u304c\\u526f\\u4f5c\\u7528\\u3092\\u5f15\\u304d\\u8d77\\u3053\\u3059\\u3088\\u3046\\u306b\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002 </li> <li>\\u30aa\\u30d6\\u30b6\\u30fc\\u30d0\\u30fc\\u52b9\\u679c\\u3092\\u9632\\u3050\\u306b\\u306f\\u3001CPU \\u306b\\u4f9d\\u5b58\\u3059\\u308b\\u95a2\\u6570\\u304c\\u4f7f\\u7528\\u3059\\u308b\\u30c7\\u30fc\\u30bf\\u3092\\u30d9\\u30f3\\u30c1\\u30de\\u30fc\\u30af\\u304c\\u518d\\u751f\\u6210\\u3059\\u308b\\u3088\\u3046\\u5f37\\u5236\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</li> </ul> <p>\\u30bb\\u30af\\u30b7\\u30e7\\u30f3\\u5168\\u6587\\u306f\\u3053\\u3061\\u3089\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#go-90\",\"title\":\"Go\\u8a00\\u8a9e\\u306e\\u30c6\\u30b9\\u30c8\\u6a5f\\u80fd\\u3092\\u3059\\u3079\\u3066\\u8a66\\u3057\\u3066\\u3044\\u306a\\u3044 (#90)\",\"text\":\"<ul> <li>\\u30b3\\u30fc\\u30c9\\u30ab\\u30d0\\u30ec\\u30c3\\u30b8 </li> </ul> <p>\\u30b3\\u30fc\\u30c9\\u306e\\u3069\\u306e\\u90e8\\u5206\\u306b\\u6ce8\\u610f\\u304c\\u5fc5\\u8981\\u304b\\u3092\\u3059\\u3050\\u306b\\u78ba\\u8a8d\\u3059\\u308b\\u305f\\u3081\\u306b\\u3001<code>-coverprofile</code> \\u30d5\\u30e9\\u30b0\\u3092\\u6307\\u5b9a\\u3057\\u3066\\u30b3\\u30fc\\u30c9\\u30ab\\u30d0\\u30ec\\u30c3\\u30b8\\u3092\\u4f7f\\u7528\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002 </p> <ul> <li>\\u5225\\u306e\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u304b\\u3089\\u306e\\u30c6\\u30b9\\u30c8 </li> </ul> <p>\\u5185\\u90e8\\u3067\\u306f\\u306a\\u304f\\u516c\\u958b\\u3055\\u308c\\u305f\\u52d5\\u4f5c\\u306b\\u7126\\u70b9\\u3092\\u5f53\\u3066\\u305f\\u30c6\\u30b9\\u30c8\\u306e\\u4f5c\\u6210\\u3092\\u5f37\\u5236\\u3059\\u308b\\u305f\\u3081\\u306b\\u3001\\u5358\\u4f53\\u30c6\\u30b9\\u30c8\\u306f\\u5225\\u3005\\u306e\\u30d1\\u30c3\\u30b1\\u30fc\\u30b8\\u306b\\u914d\\u7f6e\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p> <ul> <li>\\u30e6\\u30fc\\u30c6\\u30a3\\u30ea\\u30c6\\u30a3\\u95a2\\u6570 </li> </ul> <p>\\u5f93\\u6765\\u306e <code>if err != nil</code> \\u306e\\u4ee3\\u308f\\u308a\\u306b <code>*testing.T</code> \\u5909\\u6570\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u30a8\\u30e9\\u30fc\\u3092\\u51e6\\u7406\\u3059\\u308b\\u3068\\u3001\\u30b3\\u30fc\\u30c9\\u304c\\u77ed\\u304f\\u3001\\u8aad\\u307f\\u3084\\u3059\\u304f\\u306a\\u308a\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p> <ul> <li>setup \\u3068 teardown</li> </ul> <p>setup \\u304a\\u3088\\u3073 teardown \\u6a5f\\u80fd\\u3092\\u5229\\u7528\\u3057\\u3066\\u3001\\u7d71\\u5408\\u30c6\\u30b9\\u30c8\\u306e\\u5834\\u5408\\u306a\\u3069\\u3001\\u8907\\u96d1\\u306a\\u74b0\\u5883\\u3092\\u69cb\\u6210\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#community-mistake\",\"title\":\"\\u30d5\\u30a1\\u30b8\\u30f3\\u30b0\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3044\\u306a\\u3044\\uff08community mistake\\uff09\",\"text\":\"\\u8981\\u7d04 <p>\\u30d5\\u30a1\\u30b8\\u30f3\\u30b0\\u306f\\u3001\\u8907\\u96d1\\u306a\\u95a2\\u6570\\u3084\\u30e1\\u30bd\\u30c3\\u30c9\\u3078\\u306e\\u30e9\\u30f3\\u30c0\\u30e0\\u306a\\u3001\\u4e88\\u60f3\\u5916\\u306e\\u3001\\u307e\\u305f\\u306f\\u4e0d\\u6b63\\u306a\\u5165\\u529b\\u3092\\u691c\\u51fa\\u3057\\u3001\\u8106\\u5f31\\u6027\\u3001\\u30d0\\u30b0\\u3001\\u3055\\u3089\\u306b\\u306f\\u6f5c\\u5728\\u7684\\u306a\\u30af\\u30e9\\u30c3\\u30b7\\u30e5\\u3092\\u767a\\u898b\\u3059\\u308b\\u306e\\u306b\\u52b9\\u7387\\u7684\\u3067\\u3059\\u3002</p> <p>@jeromedoucet \\u3055\\u3093\\u306e\\u3054\\u5354\\u529b\\u306b\\u611f\\u8b1d\\u3044\\u305f\\u3057\\u307e\\u3059\\u3002</p>\"},{\"location\":\"ja/#_17\",\"title\":\"\\u6700\\u9069\\u5316\",\"text\":\"\"},{\"location\":\"ja/#cpu-91\",\"title\":\"CPU \\u30ad\\u30e3\\u30c3\\u30b7\\u30e5\\u3092\\u7406\\u89e3\\u3057\\u3066\\u3044\\u306a\\u3044 (#91)\",\"text\":\"<ul> <li>CPU \\u30a2\\u30fc\\u30ad\\u30c6\\u30af\\u30c1\\u30e3 </li> </ul> <p>L1 \\u30ad\\u30e3\\u30c3\\u30b7\\u30e5\\u306f\\u30e1\\u30a4\\u30f3\\u30e1\\u30e2\\u30ea\\u3088\\u308a\\u3082\\u7d04 50 \\uff5e 100 \\u500d\\u9ad8\\u901f\\u3067\\u3042\\u308b\\u305f\\u3081\\u3001CPU \\u30d0\\u30a6\\u30f3\\u30c9\\u306e\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u6700\\u9069\\u5316\\u3059\\u308b\\u306b\\u306f\\u3001CPU \\u30ad\\u30e3\\u30c3\\u30b7\\u30e5\\u306e\\u4f7f\\u7528\\u65b9\\u6cd5\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3053\\u3068\\u304c\\u91cd\\u8981\\u3067\\u3059\\u3002 </p> <ul> <li>\\u30ad\\u30e3\\u30c3\\u30b7\\u30e5\\u30e9\\u30a4\\u30f3 </li> </ul> <p>\\u30ad\\u30e3\\u30c3\\u30b7\\u30e5\\u30e9\\u30a4\\u30f3\\u306e\\u6982\\u5ff5\\u3092\\u610f\\u8b58\\u3059\\u308b\\u3053\\u3068\\u306f\\u3001\\u30c7\\u30fc\\u30bf\\u96c6\\u7d04\\u578b\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3067\\u30c7\\u30fc\\u30bf\\u3092\\u6574\\u7406\\u3059\\u308b\\u65b9\\u6cd5\\u3092\\u7406\\u89e3\\u3059\\u308b\\u306e\\u306b\\u91cd\\u8981\\u3067\\u3059\\u3002CPU \\u306f\\u30e1\\u30e2\\u30ea\\u3092\\u30ef\\u30fc\\u30c9\\u3054\\u3068\\u306b\\u30d5\\u30a7\\u30c3\\u30c1\\u3057\\u307e\\u305b\\u3093\\u3002\\u4ee3\\u308f\\u308a\\u306b\\u3001\\u901a\\u5e38\\u306f\\u30e1\\u30e2\\u30ea\\u30d6\\u30ed\\u30c3\\u30af\\u3092 64 \\u30d0\\u30a4\\u30c8\\u306e\\u30ad\\u30e3\\u30c3\\u30b7\\u30e5\\u30e9\\u30a4\\u30f3\\u306b\\u30b3\\u30d4\\u30fc\\u3057\\u307e\\u3059\\u3002\\u500b\\u3005\\u306e\\u30ad\\u30e3\\u30c3\\u30b7\\u30e5\\u30e9\\u30a4\\u30f3\\u3092\\u6700\\u5927\\u9650\\u306b\\u6d3b\\u7528\\u3059\\u308b\\u306b\\u306f\\u3001\\u7a7a\\u9593\\u7684\\u5c40\\u6240\\u6027\\u3092\\u5f37\\u5236\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p> <ul> <li>\\u69cb\\u9020\\u4f53\\u306e\\u30b9\\u30e9\\u30a4\\u30b9\\u3068\\u30b9\\u30e9\\u30a4\\u30b9\\u306e\\u69cb\\u9020\\u4f53</li> </ul> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p> <ul> <li>\\u4e88\\u6e2c\\u53ef\\u80fd\\u6027 </li> </ul> <p>CPU \\u306b\\u3068\\u3063\\u3066\\u4e88\\u6e2c\\u53ef\\u80fd\\u306a\\u30b3\\u30fc\\u30c9\\u306b\\u3059\\u308b\\u3053\\u3068\\u306f\\u3001\\u7279\\u5b9a\\u306e\\u95a2\\u6570\\u3092\\u6700\\u9069\\u5316\\u3059\\u308b\\u52b9\\u7387\\u7684\\u306a\\u65b9\\u6cd5\\u3067\\u3082\\u3042\\u308a\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001\\u30e6\\u30cb\\u30c3\\u30c8\\u307e\\u305f\\u306f\\u5b9a\\u6570\\u30b9\\u30c8\\u30e9\\u30a4\\u30c9\\u306f CPU \\u306b\\u3068\\u3063\\u3066\\u4e88\\u6e2c\\u53ef\\u80fd\\u3067\\u3059\\u304c\\u3001\\u975e\\u30e6\\u30cb\\u30c3\\u30c8\\u30b9\\u30c8\\u30e9\\u30a4\\u30c9\\uff08\\u9023\\u7d50\\u30ea\\u30b9\\u30c8\\u306a\\u3069\\uff09\\u306f\\u4e88\\u6e2c\\u3067\\u304d\\u307e\\u305b\\u3093\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p> <ul> <li>\\u30ad\\u30e3\\u30c3\\u30b7\\u30e5\\u914d\\u7f6e\\u30dd\\u30ea\\u30b7\\u30fc </li> </ul> <p>\\u30ad\\u30e3\\u30c3\\u30b7\\u30e5\\u304c\\u30d1\\u30fc\\u30c6\\u30a3\\u30b7\\u30e7\\u30f3\\u5316\\u3055\\u308c\\u3066\\u3044\\u308b\\u3053\\u3068\\u3092\\u8a8d\\u8b58\\u3059\\u308b\\u3053\\u3068\\u3067\\u3001\\u91cd\\u5927\\u306a\\u30b9\\u30c8\\u30e9\\u30a4\\u30c9\\u3092\\u56de\\u907f\\u3057\\u3001\\u30ad\\u30e3\\u30c3\\u30b7\\u30e5\\u306e\\u3054\\u304f\\u4e00\\u90e8\\u306e\\u307f\\u3092\\u4f7f\\u7528\\u3059\\u308b\\u3088\\u3046\\u306b\\u3059\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002</p>\"},{\"location\":\"ja/#92\",\"title\":\"\\u8aa4\\u3063\\u305f\\u5171\\u6709\\u3092\\u5f15\\u304d\\u8d77\\u3053\\u3059\\u4e26\\u884c\\u51e6\\u7406(#92)\",\"text\":\"\\u8981\\u7d04 <p>\\u4e0b\\u4f4d\\u30ec\\u30d9\\u30eb\\u306e CPU \\u30ad\\u30e3\\u30c3\\u30b7\\u30e5\\u304c\\u3059\\u3079\\u3066\\u306e\\u30b3\\u30a2\\u3067\\u5171\\u6709\\u3055\\u308c\\u308b\\u308f\\u3051\\u3067\\u306f\\u306a\\u3044\\u3053\\u3068\\u3092\\u77e5\\u3063\\u3066\\u304a\\u304f\\u3068\\u3001\\u4e26\\u884c\\u51e6\\u7406\\u306b\\u304a\\u3051\\u308b\\u306e\\u8aa4\\u3063\\u305f\\u5171\\u6709\\u306a\\u3069\\u3067\\u30d1\\u30d5\\u30a9\\u30fc\\u30de\\u30f3\\u30b9\\u3092\\u4f4e\\u4e0b\\u3055\\u305b\\u3066\\u3057\\u307e\\u3046\\u3053\\u3068\\u3092\\u56de\\u907f\\u3067\\u304d\\u307e\\u3059\\u3002\\u30e1\\u30e2\\u30ea\\u306e\\u5171\\u6709\\u306f\\u3042\\u308a\\u3048\\u306a\\u3044\\u306e\\u3067\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#93\",\"title\":\"\\u547d\\u4ee4\\u30ec\\u30d9\\u30eb\\u306e\\u4e26\\u5217\\u6027\\u3092\\u8003\\u616e\\u3057\\u306a\\u3044 (#93)\",\"text\":\"\\u8981\\u7d04 <p>\\u547d\\u4ee4\\u30ec\\u30d9\\u30eb\\u306e\\u4e26\\u5217\\u6027\\uff08ILP\\uff09\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u30b3\\u30fc\\u30c9\\u306e\\u7279\\u5b9a\\u306e\\u90e8\\u5206\\u3092\\u6700\\u9069\\u5316\\u3057\\u3001CPU \\u304c\\u3067\\u304d\\u308b\\u3060\\u3051\\u591a\\u304f\\u306e\\u547d\\u4ee4\\u3092\\u4e26\\u5217\\u5b9f\\u884c\\u3067\\u304d\\u308b\\u3088\\u3046\\u306b\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002\\u4e3b\\u306a\\u624b\\u9806\\u306e 1 \\u3064\\u306b\\u30c7\\u30fc\\u30bf\\u30cf\\u30b6\\u30fc\\u30c9\\u306e\\u7279\\u5b9a\\u304c\\u3042\\u308a\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#94\",\"title\":\"\\u30c7\\u30fc\\u30bf\\u306e\\u914d\\u7f6e\\u3092\\u610f\\u8b58\\u3057\\u3066\\u3044\\u306a\\u3044 (#94)\",\"text\":\"\\u8981\\u7d04 <p>Go\\u8a00\\u8a9e\\u3067\\u306f\\u3001\\u57fa\\u672c\\u578b\\u306f\\u5404\\u3005\\u306e\\u30b5\\u30a4\\u30ba\\u306b\\u5408\\u308f\\u305b\\u3066\\u914d\\u7f6e\\u3055\\u308c\\u308b\\u3053\\u3068\\u3092\\u899a\\u3048\\u3066\\u304a\\u304f\\u3053\\u3068\\u3067\\u3001\\u3042\\u308a\\u304c\\u3061\\u306a\\u9593\\u9055\\u3044\\u3092\\u907f\\u3051\\u308b\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002\\u305f\\u3068\\u3048\\u3070\\u3001\\u69cb\\u9020\\u4f53\\u306e\\u30d5\\u30a3\\u30fc\\u30eb\\u30c9\\u3092\\u30b5\\u30a4\\u30ba\\u3067\\u964d\\u9806\\u306b\\u518d\\u7de8\\u6210\\u3059\\u308b\\u3068\\u3001\\u69cb\\u9020\\u4f53\\u304c\\u3088\\u308a\\u30b3\\u30f3\\u30d1\\u30af\\u30c8\\u306b\\u306a\\u308b\\uff08\\u30e1\\u30e2\\u30ea\\u5272\\u308a\\u5f53\\u3066\\u304c\\u5c11\\u306a\\u304f\\u306a\\u308a\\u3001\\u7a7a\\u9593\\u7684\\u5c40\\u6240\\u6027\\u304c\\u5411\\u4e0a\\u3059\\u308b\\uff09\\u53ef\\u80fd\\u6027\\u304c\\u3042\\u308b\\u3053\\u3068\\u306b\\u7559\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#95\",\"title\":\"\\u30d2\\u30fc\\u30d7\\u3068\\u30b9\\u30bf\\u30c3\\u30af\\u306e\\u9055\\u3044\\u3092\\u7406\\u89e3\\u3057\\u3066\\u3044\\u306a\\u3044 (#95)\",\"text\":\"\\u8981\\u7d04 <p>\\u30d2\\u30fc\\u30d7\\u3068\\u30b9\\u30bf\\u30c3\\u30af\\u306e\\u57fa\\u672c\\u7684\\u306a\\u9055\\u3044\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3053\\u3068\\u3082\\u3001Go \\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u6700\\u9069\\u5316\\u3059\\u308b\\u969b\\u306b\\u306f\\u5927\\u5207\\u3067\\u3059\\u3002\\u30b9\\u30bf\\u30c3\\u30af\\u5272\\u308a\\u5f53\\u3066\\u306f\\u5bb9\\u6613\\u306a\\u306e\\u306b\\u5bfe\\u3057\\u3066\\u3001\\u30d2\\u30fc\\u30d7\\u5272\\u308a\\u5f53\\u3066\\u306f\\u9045\\u304f\\u3001\\u30e1\\u30e2\\u30ea\\u306e\\u30af\\u30ea\\u30fc\\u30f3\\u30a2\\u30c3\\u30d7\\u306b GC \\u3092\\u5229\\u7528\\u3057\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#api-syncpool-96\",\"title\":\"\\u5272\\u308a\\u5f53\\u3066\\u3092\\u6e1b\\u3089\\u3059\\u65b9\\u6cd5\\u304c\\u308f\\u304b\\u3063\\u3066\\u3044\\u306a\\u3044\\uff08 API \\u306e\\u5909\\u66f4\\u3001\\u30b3\\u30f3\\u30d1\\u30a4\\u30e9\\u306e\\u6700\\u9069\\u5316\\u3001\\u304a\\u3088\\u3073 <code>sync.Pool</code>\\uff09 (#96)\",\"text\":\"\\u8981\\u7d04 <p>\\u5272\\u308a\\u5f53\\u3066\\u3092\\u6e1b\\u3089\\u3059\\u3053\\u3068\\u3082\\u3001Go \\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u3092\\u6700\\u9069\\u5316\\u3059\\u308b\\u4e0a\\u3067\\u91cd\\u8981\\u3067\\u3059\\u3002\\u3053\\u308c\\u306f\\u3001\\u5171\\u6709\\u3092\\u9632\\u3050\\u305f\\u3081\\u306b API \\u3092\\u614e\\u91cd\\u306b\\u8a2d\\u8a08\\u3059\\u308b\\u3001\\u4e00\\u822c\\u7684\\u306a Go \\u30b3\\u30f3\\u30d1\\u30a4\\u30e9\\u306e\\u6700\\u9069\\u5316\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3001<code>sync.Pool</code> \\u3092\\u4f7f\\u7528\\u3059\\u308b\\u306a\\u3069\\u3001\\u3055\\u307e\\u3056\\u307e\\u306a\\u65b9\\u6cd5\\u3067\\u884c\\u3046\\u3053\\u3068\\u304c\\u3067\\u304d\\u307e\\u3059\\u3002</p> <p>\\u30bd\\u30fc\\u30b9\\u30b3\\u30fc\\u30c9 </p>\"},{\"location\":\"ja/#97\",\"title\":\"\\u30a4\\u30f3\\u30e9\\u30a4\\u30f3\\u5c55\\u958b\\u3092\\u3057\\u3066\\u3044\\u306a\\u3044 (#97)\",\"text\":\"\\u8981\\u7d04 <p>\\u30d5\\u30a1\\u30b9\\u30c8\\u30d1\\u30b9\\u306e\\u30a4\\u30f3\\u30e9\\u30a4\\u30f3\\u5316\\u624b\\u6cd5\\u3092\\u4f7f\\u7528\\u3057\\u3066\\u3001\\u95a2\\u6570\\u306e\\u547c\\u3073\\u51fa\\u3057\\u306b\\u304b\\u304b\\u308b\\u511f\\u5374\\u6642\\u9593\\u3092\\u52b9\\u7387\\u7684\\u306b\\u524a\\u6e1b\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p>\"},{\"location\":\"ja/#go-98\",\"title\":\"Go\\u8a00\\u8a9e\\u306e\\u8a3a\\u65ad\\u30c4\\u30fc\\u30eb\\u3092\\u5229\\u7528\\u3057\\u3066\\u3044\\u306a\\u3044 (#98)\",\"text\":\"\\u8981\\u7d04 <p>\\u30d7\\u30ed\\u30d5\\u30a1\\u30a4\\u30ea\\u30f3\\u30b0\\u3068\\u5b9f\\u884c\\u30c8\\u30ec\\u30fc\\u30b5\\u3092\\u5229\\u7528\\u3057\\u3066\\u3001\\u30a2\\u30d7\\u30ea\\u30b1\\u30fc\\u30b7\\u30e7\\u30f3\\u306e\\u30d1\\u30d5\\u30a9\\u30fc\\u30de\\u30f3\\u30b9\\u3068\\u6700\\u9069\\u5316\\u3059\\u3079\\u304d\\u90e8\\u5206\\u306b\\u3064\\u3044\\u3066\\u7406\\u89e3\\u3057\\u307e\\u3057\\u3087\\u3046\\u3002</p> <p>\\u30bb\\u30af\\u30b7\\u30e7\\u30f3\\u5168\\u6587\\u306f\\u3053\\u3061\\u3089\\u3002</p>\"},{\"location\":\"ja/#gc-99\",\"title\":\"GC \\u306e\\u4ed5\\u7d44\\u307f\\u3092\\u7406\\u89e3\\u3057\\u3066\\u3044\\u306a\\u3044 (#99)\",\"text\":\"\\u8981\\u7d04 <p>GC \\u306e\\u8abf\\u6574\\u65b9\\u6cd5\\u3092\\u7406\\u89e3\\u3059\\u308b\\u3068\\u3001\\u7a81\\u7136\\u306e\\u8ca0\\u8377\\u306e\\u5897\\u52a0\\u3092\\u3088\\u308a\\u52b9\\u7387\\u7684\\u306b\\u51e6\\u7406\\u3067\\u304d\\u308b\\u306a\\u3069\\u3001\\u3055\\u307e\\u3056\\u307e\\u306a\\u6069\\u6075\\u304c\\u5f97\\u3089\\u308c\\u307e\\u3059\\u3002</p>\"},{\"location\":\"ja/#docker-kubernetes-go-100\",\"title\":\"Docker \\u3068 Kubernetes \\u4e0a\\u3067Go\\u8a00\\u8a9e\\u3092\\u5b9f\\u884c\\u3059\\u308b\\u3053\\u3068\\u306e\\u5f71\\u97ff\\u3092\\u7406\\u89e3\\u3057\\u3066\\u3044\\u306a\\u3044 (#100)\",\"text\":\"\\u8981\\u7d04 <p>Docker \\u3068 Kubernetes \\u306b\\u30c7\\u30d7\\u30ed\\u30a4\\u3059\\u308b\\u969b\\u306e CPU \\u30b9\\u30ed\\u30c3\\u30c8\\u30ea\\u30f3\\u30b0\\u3092\\u56de\\u907f\\u3059\\u308b\\u306b\\u306f\\u3001Go\\u8a00\\u8a9e\\u304c CFS \\u5bfe\\u5fdc\\u3067\\u306f\\u306a\\u3044\\u3053\\u3068\\u306b\\u7559\\u610f\\u3057\\u3066\\u304f\\u3060\\u3055\\u3044\\u3002</p>\"},{\"location\":\"pt-br/\",\"title\":\"Brazilian Portuguese Version\",\"text\":\"\"},{\"location\":\"pt-br/#erros-comuns-de-go\",\"title\":\"Erros comuns de Go\",\"text\":\"The Coder Cafe <p>Se voc\\u00ea gostou do meu livro, talvez se interesse pelo meu novo projeto: The Coder Cafe, uma newsletter di\\u00e1ria para programadores.</p> <p>Feeling overwhelmed by the endless stream of tech content? At The Coder Cafe, we serve one essential concept for coders. Written by a senior software engineer at Google, it's perfectly brewed for your morning coffee, helping you grow your skills deeply.</p> <p></p><p></p> <p>Esta p\\u00e1gina \\u00e9 um resumo dos erros do 100 Go Mistakes and How to Avoid Them book. Enquanto isso, tamb\\u00e9m est\\u00e1 aberto \\u00e0 comunidade. Se voc\\u00ea acredita que um erro comum do Go deve ser adicionado, crie uma issue.</p> <p></p> Beta <p>Voc\\u00ea est\\u00e1 visualizando uma vers\\u00e3o beta enriquecida com muito mais conte\\u00fado. No entanto, esta vers\\u00e3o ainda n\\u00e3o est\\u00e1 completa e estou procurando volunt\\u00e1rios para me ajudar a resumir os erros restantes (GitHub issue #43).</p> <p>Progresso: </p>\"},{\"location\":\"pt-br/#codigo-e-organizacao-do-projeto\",\"title\":\"C\\u00f3digo e Organiza\\u00e7\\u00e3o do Projeto\",\"text\":\"\"},{\"location\":\"pt-br/#sombreamento-nao-intencional-de-variavel-1\",\"title\":\"Sombreamento n\\u00e3o intencional de vari\\u00e1vel (#1)\",\"text\":\"TL;DR <p>Evitar vari\\u00e1veis \\u200b\\u200bsombreadas pode ajudar a evitar erros, como fazer refer\\u00eancia \\u00e0 vari\\u00e1vel errada ou confundir os desenvolvedores.</p> <p>O sombreamento de vari\\u00e1vel ocorre quando um nome de vari\\u00e1vel \\u00e9 redeclarado em um bloco interno, mas essa pr\\u00e1tica est\\u00e1 sujeita a erros. A imposi\\u00e7\\u00e3o de uma regra para proibir vari\\u00e1veis \\u200b\\u200bobscuras depende do gosto pessoal. Por exemplo, \\u00e0s vezes pode ser conveniente reutilizar um nome de vari\\u00e1vel existente, como <code>err</code> no caso de erros. Por\\u00e9m, em geral, devemos ser cautelosos porque agora sabemos que podemos enfrentar um cen\\u00e1rio onde o c\\u00f3digo compila, mas a vari\\u00e1vel que recebe o valor n\\u00e3o \\u00e9 a esperada.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#codigo-aninhado-desnecessario-2\",\"title\":\"C\\u00f3digo aninhado desnecess\\u00e1rio (#2)\",\"text\":\"TL;DR <p>Evitar n\\u00edveis aninhados e manter o caminho feliz alinhado \\u00e0 esquerda facilita a constru\\u00e7\\u00e3o de um modelo de c\\u00f3digo mental.</p> <p>Em geral, quanto mais n\\u00edveis aninhados uma fun\\u00e7\\u00e3o exigir, mais complexa ser\\u00e1 sua leitura e compreens\\u00e3o. Vamos ver algumas aplica\\u00e7\\u00f5es diferentes desta regra para otimizar a legibilidade do nosso c\\u00f3digo:</p> <ul> <li>Quando um bloco <code>if</code> retorna, devemos omitir o <code>else</code> em todos os casos. Por exemplo, n\\u00e3o dever\\u00edamos escrever:</li> </ul> <pre><code>if foo() {\\n    // ...\\n    return true\\n} else {\\n    // ...\\n}\\n</code></pre> <p>Em vez disso, omitimos o bloco <code>else</code> assim:</p> <pre><code>if foo() {\\n    // ...\\n    return true\\n}\\n// ...\\n</code></pre> <ul> <li>Tamb\\u00e9m podemos seguir esta l\\u00f3gica com um caminho n\\u00e3o feliz:</li> </ul> <pre><code>if s != \\\"\\\" {\\n    // ...\\n} else {\\n    return errors.New(\\\"empty string\\\")\\n}\\n</code></pre> <p>Aqui, um <code>s</code> vazio representa o caminho n\\u00e3o feliz. Portanto, devemos inverter a condi\\u00e7\\u00e3o assim:</p> <pre><code>if s == \\\"\\\" {\\n    return errors.New(\\\"empty string\\\")\\n}\\n// ...\\n</code></pre> <p>Escrever c\\u00f3digo leg\\u00edvel \\u00e9 um desafio importante para todo desenvolvedor. Esfor\\u00e7ar-se para reduzir o n\\u00famero de blocos aninhados, alinhar o caminho feliz \\u00e0 esquerda e retornar o mais cedo poss\\u00edvel s\\u00e3o meios concretos para melhorar a legibilidade do nosso c\\u00f3digo.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#uso-indevido-de-funcoes-init-3\",\"title\":\"Uso indevido de fun\\u00e7\\u00f5es init (#3)\",\"text\":\"TL;DR <p>Ao inicializar vari\\u00e1veis, lembre-se de que as fun\\u00e7\\u00f5es init t\\u00eam tratamento de erros limitado e tornam o tratamento de estado e os testes mais complexos. Na maioria dos casos, as inicializa\\u00e7\\u00f5es devem ser tratadas como fun\\u00e7\\u00f5es espec\\u00edficas.</p> <p>Uma fun\\u00e7\\u00e3o init \\u00e9 uma fun\\u00e7\\u00e3o usada para inicializar o estado de um aplicativo. N\\u00e3o aceita argumentos e n\\u00e3o retorna nenhum resultado (uma fun\\u00e7\\u00e3o <code>func()</code>). Quando um pacote \\u00e9 inicializado, todas as declara\\u00e7\\u00f5es de constantes e vari\\u00e1veis \\u200b\\u200bdo pacote s\\u00e3o avaliadas. Ent\\u00e3o, as fun\\u00e7\\u00f5es init s\\u00e3o executadas.</p> <p>As fun\\u00e7\\u00f5es de inicializa\\u00e7\\u00e3o podem levar a alguns problemas:</p> <ul> <li>Elas podem limitar o gerenciamento de erros.</li> <li>Elas podem complicar a implementa\\u00e7\\u00e3o de testes (por exemplo, uma depend\\u00eancia externa deve ser configurada, o que pode n\\u00e3o ser necess\\u00e1rio para o escopo dos testes unit\\u00e1rios).</li> <li>Se a inicializa\\u00e7\\u00e3o exigir que definamos um estado, isso dever\\u00e1 ser feito por meio de vari\\u00e1veis \\u200b\\u200bglobais.</li> </ul> <p>Devemos ser cautelosos com as fun\\u00e7\\u00f5es init. No entanto, elas podem ser \\u00fateis em algumas situa\\u00e7\\u00f5es, como na defini\\u00e7\\u00e3o de configura\\u00e7\\u00e3o est\\u00e1tica. Caso contr\\u00e1rio, e na maioria dos casos, devemos tratar as inicializa\\u00e7\\u00f5es atrav\\u00e9s de fun\\u00e7\\u00f5es ad hoc.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#uso-excessivo-de-getters-e-setters-4\",\"title\":\"Uso excessivo de getters e setters (#4)\",\"text\":\"TL;DR <p>Forcing the use of getters and setters isn\\u2019t idiomatic in Go. Being pragmatic and finding the right balance between efficiency and blindly following certain idioms should be the way to go.</p> <p>O encapsulamento de dados refere-se a ocultar os valores ou o estado de um objeto. Getters e setters s\\u00e3o meios de habilitar o encapsulamento, fornecendo m\\u00e9todos exportados sobre campos de objetos n\\u00e3o exportados.</p> <p>No Go, n\\u00e3o h\\u00e1 suporte autom\\u00e1tico para getters e setters como vemos em algumas linguagens. Tamb\\u00e9m n\\u00e3o \\u00e9 considerado obrigat\\u00f3rio nem idiom\\u00e1tico o uso de getters e setters para acessar campos struct. N\\u00e3o devemos sobrecarregar nosso c\\u00f3digo com getters e setters em structs se eles n\\u00e3o trouxerem nenhum valor. Dever\\u00edamos ser pragm\\u00e1ticos e nos esfor\\u00e7ar para encontrar o equil\\u00edbrio certo entre efici\\u00eancia e seguir express\\u00f5es que \\u00e0s vezes s\\u00e3o consideradas indiscut\\u00edveis em outros paradigmas de programa\\u00e7\\u00e3o.</p> <p>Lembre-se de que Go \\u00e9 uma linguagem \\u00fanica projetada para muitas caracter\\u00edsticas, incluindo simplicidade. No entanto, se encontrarmos necessidade de getters e setters ou, como mencionado, prevermos uma necessidade futura e ao mesmo tempo garantirmos a compatibilidade futura, n\\u00e3o h\\u00e1 nada de errado em us\\u00e1-los.</p>\"},{\"location\":\"pt-br/#interface-poluidas-5\",\"title\":\"Interface poluidas (#5)\",\"text\":\"TL;DR <p>Abstra\\u00e7\\u00f5es devem ser descobertas, n\\u00e3o criadas. Para evitar complexidade desnecess\\u00e1ria, crie uma interface quando precisar dela e n\\u00e3o quando voc\\u00ea prev\\u00ear que ser\\u00e1 necess\\u00e1ria, ou se puder pelo menos provar que a abstra\\u00e7\\u00e3o \\u00e9 v\\u00e1lida.</p> <p>Leia a se\\u00e7\\u00e3o completa aqui.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#interface-do-lado-do-producer-6\",\"title\":\"Interface do lado do producer (#6)\",\"text\":\"TL;DR <p>Manter interfaces no lado do cliente evita abstra\\u00e7\\u00f5es desnecess\\u00e1rias.</p> <p>As interfaces s\\u00e3o satisfeitas implicitamente em Go, o que tende a ser um divisor de \\u00e1guas em compara\\u00e7\\u00e3o com linguagens com implementa\\u00e7\\u00e3o expl\\u00edcita. Na maioria dos casos, a abordagem a seguir \\u00e9 semelhante \\u00e0 que descrevemos na se\\u00e7\\u00e3o anterior: as abstra\\u00e7\\u00f5es devem ser descobertas, n\\u00e3o criadas. Isso significa que n\\u00e3o cabe ao producer for\\u00e7ar uma determinada abstra\\u00e7\\u00e3o para todos os clientes. Em vez disso, cabe ao cliente decidir se precisa de alguma forma de abstra\\u00e7\\u00e3o e ent\\u00e3o determinar o melhor n\\u00edvel de abstra\\u00e7\\u00e3o para suas necessidades.</p> <p>Uma interface deve residir no lado do consumidor na maioria dos casos. Contudo, em contextos espec\\u00edficos (por exemplo, quando sabemos \\u2013 e n\\u00e3o prevemos \\u2013 que uma abstra\\u00e7\\u00e3o ser\\u00e1 \\u00fatil para os consumidores), podemos querer t\\u00ea-la do lado do procuder. Se o fizermos, devemos nos esfor\\u00e7ar para mant\\u00ea-lo o m\\u00ednimo poss\\u00edvel, aumentando o seu potencial de reutiliza\\u00e7\\u00e3o e tornando-o mais facilmente combin\\u00e1vel.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#interfaces-de-retorno-7\",\"title\":\"Interfaces de retorno (#7)\",\"text\":\"TL;DR <p>Para evitar restri\\u00e7\\u00f5es em termos de flexibilidade, uma fun\\u00e7\\u00e3o n\\u00e3o deve retornar interfaces, mas implementa\\u00e7\\u00f5es concretas na maioria dos casos. Por outro lado, uma fun\\u00e7\\u00e3o deve aceitar interfaces sempre que poss\\u00edvel.</p> <p>Na maioria dos casos, n\\u00e3o devemos retornar interfaces, mas implementa\\u00e7\\u00f5es concretas. Caso contr\\u00e1rio, isso pode tornar nosso design mais complexo devido \\u00e0s depend\\u00eancias do pacote e pode restringir a flexibilidade porque todos os clientes teriam que contar com a mesma abstra\\u00e7\\u00e3o. Novamente, a conclus\\u00e3o \\u00e9 semelhante \\u00e0s se\\u00e7\\u00f5es anteriores: se sabemos (n\\u00e3o prevemos) que uma abstra\\u00e7\\u00e3o ser\\u00e1 \\u00fatil para os clientes, podemos considerar o retorno de uma interface. Caso contr\\u00e1rio, n\\u00e3o dever\\u00edamos for\\u00e7ar abstra\\u00e7\\u00f5es; eles devem ser descobertas pelos clientes. Se um cliente precisar abstrair uma implementa\\u00e7\\u00e3o por qualquer motivo, ele ainda poder\\u00e1 fazer isso do lado do cliente.</p>\"},{\"location\":\"pt-br/#any-nao-diz-nada-8\",\"title\":\"<code>any</code> n\\u00e3o diz nada (#8)\",\"text\":\"TL;DR <p>Use apenas <code>any</code> se precisar aceitar ou retornar qualquer tipo poss\\u00edvel, como <code>json.Marshal</code>. Caso contr\\u00e1rio, <code>any</code> n\\u00e3o fornece informa\\u00e7\\u00f5es significativas e pode levar a problemas de tempo de compila\\u00e7\\u00e3o, permitindo que um chamador chame m\\u00e9todos com qualquer tipo de dados.</p> <p>O tipo <code>any</code> pode ser \\u00fatil se houver uma necessidade genu\\u00edna de aceitar ou retornar qualquer tipo poss\\u00edvel (por exemplo, quando se trata de empacotamento ou formata\\u00e7\\u00e3o). Em geral, devemos evitar a todo custo generalizar demais o c\\u00f3digo que escrevemos. Talvez um pouco de c\\u00f3digo duplicado possa ocasionalmente ser melhor se melhorar outros aspectos, como a expressividade do c\\u00f3digo.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#ficar-confuso-sobre-quando-usar-genericos-9\",\"title\":\"Ficar confuso sobre quando usar gen\\u00e9ricos (#9)\",\"text\":\"TL;DR <p>Depender de par\\u00e2metros gen\\u00e9ricos e de tipo pode impedir a grava\\u00e7\\u00e3o de c\\u00f3digo clich\\u00ea (boilerplate) para fatorar elementos ou comportamentos. No entanto, n\\u00e3o use par\\u00e2metros de tipo prematuramente, mas somente quando voc\\u00ea perceber uma necessidade concreta deles. Caso contr\\u00e1rio, introduzem abstra\\u00e7\\u00f5es e complexidade desnecess\\u00e1rias.</p> <p>Leia a se\\u00e7\\u00e3o completa aqui.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-estar-ciente-dos-possiveis-problemas-com-a-incorporacao-de-tipos-10\",\"title\":\"N\\u00e3o estar ciente dos poss\\u00edveis problemas com a incorpora\\u00e7\\u00e3o de tipos (#10)\",\"text\":\"TL;DR <p>Usar a incorpora\\u00e7\\u00e3o de tipo (type embedding) tamb\\u00e9m pode ajudar a evitar c\\u00f3digo clich\\u00ea (boilerplate); no entanto, certifique-se de que isso n\\u00e3o leve a problemas de visibilidade onde alguns campos deveriam ter permanecido ocultos.</p> <p>Ao criar uma struct, Go oferece a op\\u00e7\\u00e3o de incorporar tipos. Mas isso \\u00e0s vezes pode levar a comportamentos inesperados se n\\u00e3o compreendermos todas as implica\\u00e7\\u00f5es da incorpora\\u00e7\\u00e3o de tipos. Ao longo desta se\\u00e7\\u00e3o, veremos como incorporar tipos, o que eles trazem e os poss\\u00edveis problemas.</p> <p>No Go, um campo struct \\u00e9 chamado de incorporado se for declarado sem nome. Por exemplo,</p> <pre><code>type Foo struct {\\n    Bar // Embedded field\\n}\\n\\ntype Bar struct {\\n    Baz int\\n}\\n</code></pre> <p>Na estrutura <code>Foo</code>, o tipo <code>Bar</code> \\u00e9 declarado sem nome associado; portanto, \\u00e9 um campo incorporado.</p> <p>Usamos incorpora\\u00e7\\u00e3o para promover os campos e m\\u00e9todos de um tipo incorporado. Como <code>Bar</code> cont\\u00e9m um campo <code>Baz</code>, esse campo \\u00e9 promovido para <code>Foo</code>. Portanto, <code>Baz</code> fica dispon\\u00edvel a partir de <code>Foo</code>.</p> <p>O que podemos dizer sobre a incorpora\\u00e7\\u00e3o de tipos? Primeiro, observemos que raramente \\u00e9 uma necessidade e significa que, qualquer que seja o caso de uso, provavelmente tamb\\u00e9m poderemos resolv\\u00ea-lo sem incorpora\\u00e7\\u00e3o de tipo. A incorpora\\u00e7\\u00e3o de tipos \\u00e9 usada principalmente por conveni\\u00eancia: na maioria dos casos, para promover comportamentos.</p> <p>Se decidirmos usar incorpora\\u00e7\\u00e3o de tipo, precisamos ter em mente duas restri\\u00e7\\u00f5es principais:</p> <ul> <li>N\\u00e3o deve ser usado apenas como um a\\u00e7\\u00facar sint\\u00e1tico para simplificar o acesso a um campo (como <code>Foo.Baz()</code> em vez de <code>Foo.Bar.Baz()</code>). Se esta for a \\u00fanica justificativa, n\\u00e3o vamos incorporar o tipo interno e usar um campo.</li> <li>N\\u00e3o deve promover dados (campos) ou um comportamento (m\\u00e9todos) que queremos ocultar do exterior: por exemplo, se permitir que os clientes acessem um comportamento de bloqueio que deve permanecer privado da struct.</li> </ul> <p>Usar a incorpora\\u00e7\\u00e3o de tipo de forma consciente, mantendo essas restri\\u00e7\\u00f5es em mente, pode ajudar a evitar c\\u00f3digo clich\\u00ea (boilerplate) com m\\u00e9todos de encaminhamento adicionais. No entanto, vamos garantir que n\\u00e3o o fazemos apenas por motivos cosm\\u00e9ticos e n\\u00e3o promovemos elementos que deveriam permanecer ocultos.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-usar-o-padrao-de-opcoes-funcionais-functional-options-pattern-11\",\"title\":\"N\\u00e3o usar o padr\\u00e3o de op\\u00e7\\u00f5es funcionais (functional options pattern) (#11)\",\"text\":\"TL;DR <p>Para lidar com op\\u00e7\\u00f5es de maneira conveniente e amig\\u00e1vel \\u00e0 API, use o padr\\u00e3o de op\\u00e7\\u00f5es funcionais.</p> <p>Embora existam diferentes implementa\\u00e7\\u00f5es com pequenas varia\\u00e7\\u00f5es, a ideia principal \\u00e9 a seguinte:</p> <ul> <li>Uma estrutura n\\u00e3o exportada cont\\u00e9m a configura\\u00e7\\u00e3o: op\\u00e7\\u00f5es.</li> <li>Cada op\\u00e7\\u00e3o \\u00e9 uma fun\\u00e7\\u00e3o que retorna o mesmo tipo: <code>type Option func(options *options) error</code>. Por exemplo, <code>WithPort</code> aceita um argumento <code>int</code>  que representa a porta e retorna um tipo <code>Option</code> que representa como atualizar a struct <code>options</code>.</li> </ul> <p></p> <pre><code>type options struct {\\n  port *int\\n}\\n\\ntype Option func(options *options) error\\n\\nfunc WithPort(port int) Option {\\n  return func(options *options) error {\\n    if port &lt; 0 {\\n    return errors.New(\\\"port should be positive\\\")\\n  }\\n  options.port = &amp;port\\n  return nil\\n  }\\n}\\n\\nfunc NewServer(addr string, opts ...Option) ( *http.Server, error) {\\n  var options options\\n  for _, opt := range opts {\\n    err := opt(&amp;options)\\n    if err != nil {\\n      return nil, err\\n    }\\n  }\\n\\n  // At this stage, the options struct is built and contains the config\\n  // Therefore, we can implement our logic related to port configuration\\n  var port int\\n  if options.port == nil {\\n    port = defaultHTTPPort\\n  } else {\\n      if *options.port == 0 {\\n      port = randomPort()\\n    } else {\\n      port = *options.port\\n    }\\n  }\\n\\n  // ...\\n}\\n</code></pre> <p>O padr\\u00e3o de op\\u00e7\\u00f5es funcionais fornece uma maneira pr\\u00e1tica e amig\\u00e1vel \\u00e0 API de lidar com op\\u00e7\\u00f5es. Embora o padr\\u00e3o do construtor possa ser uma op\\u00e7\\u00e3o v\\u00e1lida, ele tem algumas desvantagens menores (ter que passar uma estrutura de configura\\u00e7\\u00e3o que pode estar vazia ou uma maneira menos pr\\u00e1tica de lidar com o gerenciamento de erros) que tendem a tornar o padr\\u00e3o de op\\u00e7\\u00f5es funcionais a maneira idiom\\u00e1tica de lidar com esse tipo de problema no Go.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#desorganizacao-do-projeto-estrutura-do-projeto-e-organizacao-do-pacote-12\",\"title\":\"Desorganiza\\u00e7\\u00e3o do projeto (estrutura do projeto e organiza\\u00e7\\u00e3o do pacote) (#12)\",\"text\":\"<p>No que diz respeito \\u00e0 organiza\\u00e7\\u00e3o geral, existem diferentes escolas de pensamento. Por exemplo, devemos organizar a nossa aplica\\u00e7\\u00e3o por contexto ou por camada? Depende de nossas prefer\\u00eancias. Podemos preferir agrupar o c\\u00f3digo por contexto (como o contexto do cliente, o contexto do contrato, etc.), ou podemos preferir seguir os princ\\u00edpios da arquitetura hexagonal e agrupar por camada t\\u00e9cnica. Se a decis\\u00e3o que tomarmos se adequar ao nosso caso de uso, n\\u00e3o pode ser uma decis\\u00e3o errada, desde que permane\\u00e7amos consistentes com ela.</p> <p>Em rela\\u00e7\\u00e3o aos pacotes, existem v\\u00e1rias pr\\u00e1ticas recomendadas que devemos seguir. Primeiro, devemos evitar pacotes prematuros porque podem complicar demais um projeto. \\u00c0s vezes, \\u00e9 melhor usar uma organiza\\u00e7\\u00e3o simples e fazer nosso projeto evoluir quando entendemos o que ele cont\\u00e9m, em vez de nos for\\u00e7armos a fazer a estrutura perfeita desde o in\\u00edcio. A granularidade \\u00e9 outra coisa essencial a considerar. Devemos evitar dezenas de pacotes nano contendo apenas um ou dois arquivos. Se o fizermos, \\u00e9 porque provavelmente perdemos algumas conex\\u00f5es l\\u00f3gicas entre esses pacotes, tornando nosso projeto mais dif\\u00edcil de ser compreendido pelos leitores. Por outro lado, tamb\\u00e9m devemos evitar pacotes grandes que diluem o significado do nome de um pacote.</p> <p>A nomenclatura dos pacotes tamb\\u00e9m deve ser considerada com cuidado. Como todos sabemos (como desenvolvedores), nomear \\u00e9 dif\\u00edcil. Para ajudar os clientes a entender um projeto Go, devemos nomear nossos pacotes de acordo com o que eles fornecem, n\\u00e3o com o que cont\\u00eam. Al\\u00e9m disso, a nomenclatura deve ser significativa. Portanto, o nome de um pacote deve ser curto, conciso, expressivo e, por conven\\u00e7\\u00e3o, uma \\u00fanica palavra min\\u00fascula.</p> <p>Quanto ao que exportar, a regra \\u00e9 bastante simples. Devemos minimizar o que deve ser exportado tanto quanto poss\\u00edvel para reduzir o acoplamento entre pacotes e manter ocultos os elementos exportados desnecess\\u00e1rios. Se n\\u00e3o tivermos certeza se devemos ou n\\u00e3o exportar um elemento, devemos optar por n\\u00e3o export\\u00e1-lo. Mais tarde, se descobrirmos que precisamos export\\u00e1-lo, poderemos ajustar nosso c\\u00f3digo. Vamos tamb\\u00e9m ter em mente algumas exce\\u00e7\\u00f5es, como fazer com que os campos sejam exportados para que uma estrutura possa ser desempacotada com encoding/json.</p> <p>Organizar um projeto n\\u00e3o \\u00e9 simples, mas seguir essas regras deve ajudar a facilitar sua manuten\\u00e7\\u00e3o. No entanto, lembre-se de que a consist\\u00eancia tamb\\u00e9m \\u00e9 vital para facilitar a manuten\\u00e7\\u00e3o. Portanto, vamos nos certificar de manter as coisas o mais consistentes poss\\u00edvel dentro de uma base de c\\u00f3digo.</p> Note <p>Em 2023, a equipe Go publicou uma diretriz oficial para organizar/estruturar um projeto Go: go.dev/doc/modules/layout</p>\"},{\"location\":\"pt-br/#criando-pacotes-de-utilitarios-13\",\"title\":\"Criando pacotes de utilit\\u00e1rios (#13)\",\"text\":\"TL;DR <p>A nomenclatura \\u00e9 uma parte cr\\u00edtica do design do aplicativo. Criar pacotes como <code>common</code>, <code>util</code> e <code>shared</code> n\\u00e3o traz muito valor para o leitor. Refatore esses pacotes em nomes de pacotes significativos e espec\\u00edficos.</p> <p>Al\\u00e9m disso, tenha em mente que nomear um pacote com base no que ele fornece e n\\u00e3o no que ele cont\\u00e9m pode ser uma forma eficiente de aumentar sua expressividade.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#ignorando-colisoes-de-nomes-de-pacotes-14\",\"title\":\"Ignorando colis\\u00f5es de nomes de pacotes (#14)\",\"text\":\"TL;DR <p>Para evitar colis\\u00f5es de nomes entre vari\\u00e1veis \\u200b\\u200be pacotes, levando a confus\\u00e3o ou talvez at\\u00e9 bugs, use nomes exclusivos para cada um. Se isso n\\u00e3o for vi\\u00e1vel, use um alias de importa\\u00e7\\u00e3o para alterar o qualificador para diferenciar o nome do pacote do nome da vari\\u00e1vel ou pense em um nome melhor.</p> <p>As colis\\u00f5es de pacotes ocorrem quando um nome de vari\\u00e1vel colide com um nome de pacote existente, impedindo que o pacote seja reutilizado. Devemos evitar colis\\u00f5es de nomes de vari\\u00e1veis \\u200b\\u200bpara evitar ambiguidade. Se enfrentarmos uma colis\\u00e3o, devemos encontrar outro nome significativo ou usar um alias de importa\\u00e7\\u00e3o.</p>\"},{\"location\":\"pt-br/#documentacao-de-codigo-ausente-15\",\"title\":\"Documenta\\u00e7\\u00e3o de c\\u00f3digo ausente (#15)\",\"text\":\"TL;DR <p>Para ajudar clientes e mantenedores a entender a finalidade do seu c\\u00f3digo, documente os elementos exportados.</p> <p>A documenta\\u00e7\\u00e3o \\u00e9 um aspecto importante da programa\\u00e7\\u00e3o. Simplifica como os clientes podem consumir uma API, mas tamb\\u00e9m pode ajudar na manuten\\u00e7\\u00e3o de um projeto. No Go, devemos seguir algumas regras para tornar nosso c\\u00f3digo idiom\\u00e1tico:</p> <p>Primeiro, cada elemento exportado deve ser documentado. Seja uma estrutura, uma interface, uma fun\\u00e7\\u00e3o ou qualquer outra coisa, se for exportado deve ser documentado. A conven\\u00e7\\u00e3o \\u00e9 adicionar coment\\u00e1rios, come\\u00e7ando com o nome do elemento exportado.</p> <p>Por conven\\u00e7\\u00e3o, cada coment\\u00e1rio deve ser uma frase completa que termina com pontua\\u00e7\\u00e3o. Tenha tamb\\u00e9m em mente que quando documentamos uma fun\\u00e7\\u00e3o (ou um m\\u00e9todo), devemos destacar o que a fun\\u00e7\\u00e3o pretende fazer, n\\u00e3o como o faz; isso pertence ao n\\u00facleo de uma fun\\u00e7\\u00e3o e coment\\u00e1rios, n\\u00e3o \\u00e0 documenta\\u00e7\\u00e3o. Al\\u00e9m disso, o ideal \\u00e9 que a documenta\\u00e7\\u00e3o forne\\u00e7a informa\\u00e7\\u00f5es suficientes para que o consumidor n\\u00e3o precise olhar nosso c\\u00f3digo para entender como usar um elemento exportado.</p> <p>Quando se trata de documentar uma vari\\u00e1vel ou constante, podemos estar interessados \\u200b\\u200bem transmitir dois aspectos: sua finalidade e seu conte\\u00fado. O primeiro deve funcionar como documenta\\u00e7\\u00e3o de c\\u00f3digo para ser \\u00fatil para clientes externos. Este \\u00faltimo, por\\u00e9m, n\\u00e3o deveria ser necessariamente p\\u00fablico.</p> <p>Para ajudar clientes e mantenedores a entender o escopo de um pacote, devemos tamb\\u00e9m documentar cada pacote. A conven\\u00e7\\u00e3o \\u00e9 iniciar o coment\\u00e1rio com <code>// Package</code> seguido do nome do pacote. A primeira linha de um coment\\u00e1rio de pacote deve ser concisa. Isso porque ele aparecer\\u00e1 no pacote. Ent\\u00e3o, podemos fornecer todas as informa\\u00e7\\u00f5es que precisamos nas linhas seguintes.</p> <p>Documentar nosso c\\u00f3digo n\\u00e3o deve ser uma restri\\u00e7\\u00e3o. Devemos aproveitar a oportunidade para garantir que isso ajude os clientes e mantenedores a entender o prop\\u00f3sito do nosso c\\u00f3digo.</p>\"},{\"location\":\"pt-br/#nao-usando-linters-16\",\"title\":\"N\\u00e3o usando linters (#16)\",\"text\":\"TL;DR <p>Para melhorar a qualidade e consist\\u00eancia do c\\u00f3digo, use linters e formatadores.</p> <p>Um linter \\u00e9 uma ferramenta autom\\u00e1tica para analisar c\\u00f3digo e detectar erros. O escopo desta se\\u00e7\\u00e3o n\\u00e3o \\u00e9 fornecer uma lista exaustiva dos linters existentes; caso contr\\u00e1rio, ele ficar\\u00e1 obsoleto rapidamente. Mas devemos entender e lembrar por que os linters s\\u00e3o essenciais para a maioria dos projetos Go.</p> <p>No entanto, se voc\\u00ea n\\u00e3o \\u00e9 um usu\\u00e1rio regular de linters, aqui est\\u00e1 uma lista que voc\\u00ea pode usar diariamente:</p> <ul> <li>https://golang.org/cmd/vet\\u2014A standard Go analyzer</li> <li>https://github.com/kisielk/errcheck\\u2014An error checker</li> <li>https://github.com/fzipp/gocyclo\\u2014A cyclomatic complexity analyzer</li> <li>https://github.com/jgautheron/goconst\\u2014A repeated string constants analyzer</li> </ul> <p>Al\\u00e9m dos linters, tamb\\u00e9m devemos usar formatadores de c\\u00f3digo para corrigir o estilo do c\\u00f3digo. Aqui est\\u00e1 uma lista de alguns formatadores de c\\u00f3digo para voc\\u00ea experimentar:</p> <ul> <li>https://golang.org/cmd/gofmt\\u2014A standard Go code formatter</li> <li>https://godoc.org/golang.org/x/tools/cmd/goimports\\u2014A standard Go imports formatter</li> </ul> <p>Enquanto isso, devemos tamb\\u00e9m dar uma olhada em golangci-lint (https://github.com/golangci/golangci-lint). \\u00c9 uma ferramenta de linting que fornece uma fachada sobre muitos linters e formatadores \\u00fateis. Al\\u00e9m disso, permite executar os linters em paralelo para melhorar a velocidade de an\\u00e1lise, o que \\u00e9 bastante \\u00fatil.</p> <p>Linters e formatadores s\\u00e3o uma forma poderosa de melhorar a qualidade e consist\\u00eancia de nossa base de c\\u00f3digo. Vamos dedicar um tempo para entender qual deles devemos usar e garantir que automatizamos sua execu\\u00e7\\u00e3o (como um precommit hook de CI ou Git).</p>\"},{\"location\":\"pt-br/#tipos-de-dados\",\"title\":\"Tipos de dados\",\"text\":\"\"},{\"location\":\"pt-br/#criando-confusao-com-literais-octais-17\",\"title\":\"Criando confus\\u00e3o com literais octais (#17)\",\"text\":\"TL;DR <p>Ao ler o c\\u00f3digo existente, lembre-se de que literais inteiros come\\u00e7ando com <code>0</code> s\\u00e3o n\\u00fameros octais. Al\\u00e9m disso, para melhorar a legibilidade, torne os inteiros octais expl\\u00edcitos prefixando-os com <code>0o</code>.</p> <p>Os n\\u00fameros octais come\\u00e7am com 0 (por exemplo, <code>010</code> \\u00e9 igual a 8 na base 10). Para melhorar a legibilidade e evitar poss\\u00edveis erros para futuros leitores de c\\u00f3digo, devemos tornar os n\\u00fameros octais expl\\u00edcitos usando o prefixo <code>0o</code> (por exemplo, <code>0o10</code>).</p> <p>Devemos tamb\\u00e9m observar as outras representa\\u00e7\\u00f5es literais inteiras:</p> <ul> <li>Bin\\u00e1rio\\u2014Usa um prefixo <code>0b</code> ou <code>0B</code>(por exemplo, <code>0b100</code> \\u00e9 igual a 4 na base 10)</li> <li>Hexadecimal\\u2014Usa um prefixo <code>0x</code> ou <code>0X</code> (por exemplo, <code>0xF</code> \\u00e9 igual a 15 na base 10)</li> <li>Imagin\\u00e1rio\\u2014Usa um <code>i</code> sufixo (por exemplo, <code>3i</code>)</li> </ul> <p>Tamb\\u00e9m podemos usar um caractere de sublinhado (_) como separador para facilitar a leitura. Por exemplo, podemos escrever 1 bilh\\u00e3o desta forma: <code>1_000_000_000</code>. Tamb\\u00e9m podemos usar o caractere sublinhado com outras representa\\u00e7\\u00f5es (por exemplo, <code>0b00_00_01</code>).</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#negligenciando-estouros-de-numero-inteiro-18\",\"title\":\"Negligenciando estouros de n\\u00famero inteiro (#18)\",\"text\":\"TL;DR <p>Como os overflows e underflows de n\\u00fameros inteiros s\\u00e3o tratados silenciosamente no Go, voc\\u00ea pode implementar suas pr\\u00f3prias fun\\u00e7\\u00f5es para captur\\u00e1-los.</p> <p>No Go, um estouro de n\\u00famero inteiro que pode ser detectado em tempo de compila\\u00e7\\u00e3o gera um erro de compila\\u00e7\\u00e3o. Por exemplo,</p> <pre><code>var counter int32 = math.MaxInt32 + 1\\n</code></pre> <pre><code>constant 2147483648 overflows int32\\n</code></pre> <p>No entanto, em tempo de execu\\u00e7\\u00e3o, um overflow ou underflow de inteiro \\u00e9 silencioso; isso n\\u00e3o leva ao p\\u00e2nico do aplicativo. \\u00c9 essencial ter esse comportamento em mente, pois ele pode levar a bugs sorrateiros (por exemplo, um incremento de n\\u00famero inteiro ou adi\\u00e7\\u00e3o de n\\u00fameros inteiros positivos que leva a um resultado negativo).</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-entendendo-os-pontos-flutuantes-19\",\"title\":\"N\\u00e3o entendendo os pontos flutuantes (#19)\",\"text\":\"TL;DR <p>Fazer compara\\u00e7\\u00f5es de ponto flutuante dentro de um determinado delta pode garantir que seu c\\u00f3digo seja port\\u00e1til. Ao realizar adi\\u00e7\\u00e3o ou subtra\\u00e7\\u00e3o, agrupe as opera\\u00e7\\u00f5es com ordem de grandeza semelhante para favorecer a precis\\u00e3o. Al\\u00e9m disso, execute multiplica\\u00e7\\u00e3o e divis\\u00e3o antes da adi\\u00e7\\u00e3o e subtra\\u00e7\\u00e3o.</p> <p>Em Go, existem dois tipos de ponto flutuante (se omitirmos os n\\u00fameros imagin\\u00e1rios): float32 e float64. O conceito de ponto flutuante foi inventado para resolver o principal problema dos n\\u00fameros inteiros: sua incapacidade de representar valores fracion\\u00e1rios. Para evitar surpresas desagrad\\u00e1veis, precisamos saber que a aritm\\u00e9tica de ponto flutuante \\u00e9 uma aproxima\\u00e7\\u00e3o da aritm\\u00e9tica real.</p> <p>Para isso, veremos um exemplo de multiplica\\u00e7\\u00e3o:</p> <pre><code>var n float32 = 1.0001\\nfmt.Println(n * n)\\n</code></pre> <p>Podemos esperar que este c\\u00f3digo imprima o resultado de 1.0001 * 1.0001 = 1,00020001, certo? No entanto, execut\\u00e1-lo na maioria dos processadores x86 imprime 1.0002.</p> <p>Como os tipos <code>float32</code> e <code>float64</code> em Go s\\u00e3o aproxima\\u00e7\\u00f5es, temos que ter algumas regras em mente:</p> <ul> <li>Ao comparar dois n\\u00fameros de ponto flutuante, verifique se a diferen\\u00e7a est\\u00e1 dentro de um intervalo aceit\\u00e1vel.</li> <li>Ao realizar adi\\u00e7\\u00f5es ou subtra\\u00e7\\u00f5es, agrupe opera\\u00e7\\u00f5es com ordem de magnitude semelhante para melhor precis\\u00e3o.</li> <li>Para favorecer a precis\\u00e3o, se uma sequ\\u00eancia de opera\\u00e7\\u00f5es exigir adi\\u00e7\\u00e3o, subtra\\u00e7\\u00e3o, multiplica\\u00e7\\u00e3o ou divis\\u00e3o, execute primeiro as opera\\u00e7\\u00f5es de multiplica\\u00e7\\u00e3o e divis\\u00e3o.</li> </ul> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-entendendo-o-comprimento-e-a-capacidade-de-slice-20\",\"title\":\"N\\u00e3o entendendo o comprimento e a capacidade de slice (#20)\",\"text\":\"TL;DR <p>Compreender a diferen\\u00e7a entre comprimento e capacidade da slice deve fazer parte do conhecimento b\\u00e1sico de um desenvolvedor Go. O comprimento de slice \\u00e9 o n\\u00famero de elementos dispon\\u00edveis na slice, enquanto a capacidade de slice \\u00e9 o n\\u00famero de elementos na matriz de apoio.</p> <p>Leia a se\\u00e7\\u00e3o completa aqui.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#inicializacao-de-slice-ineficiente-21\",\"title\":\"Inicializa\\u00e7\\u00e3o de slice ineficiente (#21)\",\"text\":\"TL;DR <p>Ao criar uma fatia, inicialize-a com um determinado comprimento ou capacidade se o seu comprimento j\\u00e1 for conhecido. Isso reduz o n\\u00famero de aloca\\u00e7\\u00f5es e melhora o desempenho.</p> <p>Ao inicializar uma fatia usando <code>make</code>, podemos fornecer um comprimento e uma capacidade opcional. Esquecer de passar um valor apropriado para ambos os par\\u00e2metros quando faz sentido \\u00e9 um erro generalizado. Na verdade, isso pode levar a m\\u00faltiplas c\\u00f3pias e esfor\\u00e7o adicional para o GC limpar as matrizes de apoio tempor\\u00e1rias. Em termos de desempenho, n\\u00e3o h\\u00e1 uma boa raz\\u00e3o para n\\u00e3o ajudar o tempo de execu\\u00e7\\u00e3o do Go.</p> <p>Nossas op\\u00e7\\u00f5es s\\u00e3o alocar uma fatia com determinada capacidade ou comprimento. Destas duas solu\\u00e7\\u00f5es, vimos que a segunda tende a ser um pouco mais r\\u00e1pida. Mas usar uma determinada capacidade e anexar pode ser mais f\\u00e1cil de implementar e ler em alguns contextos.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#estar-confuso-sobre-slice-nula-vs-slice-vazia-22\",\"title\":\"Estar confuso sobre slice nula vs. slice vazia (#22)\",\"text\":\"TL;DR <p>To prevent common confusions such as when using the <code>encoding/json</code> or the <code>reflect</code> package, you need to understand the difference between nil and empty slices. Both are zero-length, zero-capacity slices, but only a nil slice doesn\\u2019t require allocation.</p> <p>No Go, h\\u00e1 uma distin\\u00e7\\u00e3o entre slices nulas e vazias. Uma slice nula \\u00e9 igual a <code>nil</code>, enquanto uma slice vazia tem comprimento zero. Uma slice nula est\\u00e1 vazia, mas uma slice vazia n\\u00e3o \\u00e9 necessariamente <code>nil</code>. Enquanto isso, uma slice nula n\\u00e3o requer nenhuma aloca\\u00e7\\u00e3o. Vimos ao longo desta se\\u00e7\\u00e3o como inicializar uma slice dependendo do contexto usando</p> <ul> <li><code>var s []string</code> se n\\u00e3o tivermos certeza sobre o comprimento final e a fatia pode estar vazia</li> <li><code>[]string(nil)</code> como a\\u00e7\\u00facar sint\\u00e1tico para criar uma fatia nula e vazia</li> <li><code>make([]string, length)</code> se o comprimento futuro for conhecido</li> </ul> <p>A \\u00faltima op\\u00e7\\u00e3o, <code>[]string{}</code> deve ser evitada se inicializarmos a fatia sem elementos. Finalmente, vamos verificar se as bibliotecas que usamos fazem distin\\u00e7\\u00f5es entre fatias nulas e vazias para evitar comportamentos inesperados.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-verificar-corretamente-se-um-slice-esta-vazio-23\",\"title\":\"N\\u00e3o verificar corretamente se um slice est\\u00e1 vazio (#23)\",\"text\":\"TL;DR <p>Para verificar se uma fatia n\\u00e3o cont\\u00e9m nenhum elemento, verifique seu comprimento. Esta verifica\\u00e7\\u00e3o funciona independentemente de o slice estar <code>nil</code> ou vazio. O mesmo vale para maps. Para projetar APIs inequ\\u00edvocas, voc\\u00ea n\\u00e3o deve distinguir entre slice nulos e vazios.</p> <p>Para determinar se um slice possui elementos, podemos faz\\u00ea-lo verificando se o slice \\u00e9 nulo ou se seu comprimento \\u00e9 igual a 0. Verificar o comprimento \\u00e9 a melhor op\\u00e7\\u00e3o a seguir, pois cobrir\\u00e1 ambos se o slice estiver vazio ou se o slice \\u00e9 nulo.</p> <p>Enquanto isso, ao projetar interfaces, devemos evitar distinguir slices nulos e vazios, o que leva a erros sutis de programa\\u00e7\\u00e3o. Ao retornar slices, n\\u00e3o deve haver diferen\\u00e7a sem\\u00e2ntica nem t\\u00e9cnica se retornarmos um slice nulo ou vazio. Ambos devem significar a mesma coisa para quem liga. Este princ\\u00edpio \\u00e9 o mesmo com maps. Para verificar se um map est\\u00e1 vazio, verifique seu comprimento, n\\u00e3o se \\u00e9 nulo.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-fazer-copias-de-slcies-corretamente-24\",\"title\":\"N\\u00e3o fazer c\\u00f3pias de slcies corretamente (#24)\",\"text\":\"TL;DR <p>Para copiar um slice para outro usando a fun\\u00e7\\u00e3o <code>copy</code>, lembre-se que o n\\u00famero de elementos copiados corresponde ao m\\u00ednimo entre os comprimentos dos dois slices.</p> <p>Copiar elementos de um slice para outro \\u00e9 uma opera\\u00e7\\u00e3o razoavelmente frequente. Ao utilizar a c\\u00f3pia, devemos lembrar que o n\\u00famero de elementos copiados para o destino corresponde ao m\\u00ednimo entre os comprimentos dos dois slices. Tenha tamb\\u00e9m em mente que existem outras alternativas para copiar um slice, por isso n\\u00e3o devemos nos surpreender se as encontrarmos em uma base de c\\u00f3digo.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#efeitos-colaterais-inesperados-usando-o-slice-append-25\",\"title\":\"Efeitos colaterais inesperados usando o slice append (#25)\",\"text\":\"TL;DR <p>Usar <code>copy</code> ou a express\\u00e3o de slice completa \\u00e9 uma forma de evitar que <code>append</code> crie conflitos se duas fun\\u00e7\\u00f5es diferentes usarem slices apoiados pela mesmo array. No entanto, apenas uma c\\u00f3pia de slice evita vazamentos de mem\\u00f3ria se voc\\u00ea quiser reduzir um slice grande.</p> <p>Ao usar o slicing, devemos lembrar que podemos enfrentar uma situa\\u00e7\\u00e3o que leva a efeitos colaterais n\\u00e3o intencionais. Se o slice resultante tiver um comprimento menor que sua capacidade, o acr\\u00e9scimo poder\\u00e1 alterar o slice original. Se quisermos restringir a gama de poss\\u00edveis efeitos colaterais, podemos usar uma c\\u00f3pia de slice ou a express\\u00e3o de slice completa, o que nos impede de fazer uma c\\u00f3pia.</p> Note <p><code>s[low:high:max]</code>(express\\u00e3o de slice completo): Esta instru\\u00e7\\u00e3o cria um slice semelhante \\u00e0quele criado com <code>s[low:high]</code>, exceto que a capacidade de slice resultante \\u00e9 igual a <code>max - low</code>.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#slices-e-vazamentos-de-memoria-26\",\"title\":\"Slices e vazamentos de mem\\u00f3ria (#26)\",\"text\":\"TL;DR <p>Trabalhando com um slice de ponteiros ou estruturas com campos de ponteiro, voc\\u00ea pode evitar vazamentos de mem\\u00f3ria marcando como nulos os elementos exclu\\u00eddos por uma opera\\u00e7\\u00e3o de fatiamento.</p>\"},{\"location\":\"pt-br/#vazamento-de-capacidade\",\"title\":\"Vazamento de capacidade\",\"text\":\"<p>Lembre-se de que fatiar um slice ou array grande pode levar a um potencial alto consumo de mem\\u00f3ria. O espa\\u00e7o restante n\\u00e3o ser\\u00e1 recuperado pelo GC e podemos manter um grande array de apoio, apesar de usarmos apenas alguns elementos. Usar uma c\\u00f3pia em slice \\u00e9 a solu\\u00e7\\u00e3o para evitar tal caso.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#slice-e-ponteiros\",\"title\":\"Slice e ponteiros\",\"text\":\"<p>Quando usamos a opera\\u00e7\\u00e3o de fatiamento com ponteiros ou estruturas com campos de ponteiro, precisamos saber que o GC n\\u00e3o recuperar\\u00e1 esses elementos. Nesse caso, as duas op\\u00e7\\u00f5es s\\u00e3o realizar uma c\\u00f3pia ou marcar explicitamente os elementos restantes ou seus campos como <code>nil</code>.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#inicializacao-ineficiente-do-mapa-27\",\"title\":\"Inicializa\\u00e7\\u00e3o ineficiente do mapa (#27)\",\"text\":\"TL;DR <p>Ao criar um mapa, inicialize-o com um determinado comprimento se o seu comprimento j\\u00e1 for conhecido. Isso reduz o n\\u00famero de aloca\\u00e7\\u00f5es e melhora o desempenho.</p> <p>Um mapa fornece uma cole\\u00e7\\u00e3o n\\u00e3o ordenada de pares chave-valor em que todas as chaves s\\u00e3o distintas. No Go, um mapa \\u00e9 baseado na estrutura de dados da tabela hash. Internamente, uma tabela hash \\u00e9 uma matriz de intervalos e cada intervalo \\u00e9 um ponteiro para uma matriz de pares de valores-chave.</p> <p>Se soubermos de antem\\u00e3o o n\\u00famero de elementos que um mapa conter\\u00e1, devemos cri\\u00e1-lo fornecendo um tamanho inicial. Fazer isso evita o crescimento potencial do mapa, o que \\u00e9 bastante pesado em termos de computa\\u00e7\\u00e3o porque requer a realoca\\u00e7\\u00e3o de espa\\u00e7o suficiente e o reequil\\u00edbrio de todos os elementos.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#mapas-e-vazamentos-de-memoria-28\",\"title\":\"Mapas e vazamentos de mem\\u00f3ria (#28)\",\"text\":\"TL;DR <p>Um mapa sempre pode crescer na mem\\u00f3ria, mas nunca diminui. Portanto, se isso causar alguns problemas de mem\\u00f3ria, voc\\u00ea pode tentar diferentes op\\u00e7\\u00f5es, como for\\u00e7ar Go a recriar o mapa ou usar ponteiros.</p> <p>Leia a se\\u00e7\\u00e3o completa aqui.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#comparando-valores-incorretamente-29\",\"title\":\"Comparando valores incorretamente (#29)\",\"text\":\"TL;DR <p>Para comparar tipos em Go, voc\\u00ea pode usar os operadores == e != se dois tipos forem compar\\u00e1veis: booleanos, numerais, strings, ponteiros, canais e estruturas s\\u00e3o compostos inteiramente de tipos compar\\u00e1veis. Caso contr\\u00e1rio, voc\\u00ea pode usar <code>reflect.DeepEquale</code> pagar o pre\\u00e7o da reflex\\u00e3o ou usar implementa\\u00e7\\u00f5es e bibliotecas personalizadas.</p> <p>\\u00c9 essencial entender como usar <code>==</code> e <code>!=</code> para fazer compara\\u00e7\\u00f5es de forma eficaz. Podemos usar esses operadores em operandos compar\\u00e1veis:</p> <ul> <li>Booleans\\u2014Compara se dois booleanos s\\u00e3o iguais.</li> <li>Numerics (int, float, and complex types)\\u2014Compare se dois n\\u00fameros s\\u00e3o iguais.</li> <li>Strings\\u2014Compare se duas strings s\\u00e3o iguais.</li> <li>Channels\\u2014Compare se dois canais foram criados pela mesma chamada a ser feita ou se ambos s\\u00e3o nulos.</li> <li>Interfaces\\u2014Compare se duas interfaces t\\u00eam tipos din\\u00e2micos id\\u00eanticos e valores din\\u00e2micos iguais ou se ambas s\\u00e3o nulas.</li> <li>Pointers\\u2014Compare se dois ponteiros apontam para o mesmo valor na mem\\u00f3ria ou se ambos s\\u00e3o nulos.</li> <li>Structs and arrays\\u2014Compare se s\\u00e3o compostas de tipos semelhantes.</li> </ul> Note <p>Tamb\\u00e9m podemos usar os operadores <code>?</code>, <code>&gt;=</code>, <code>&lt;</code> e <code>&gt;</code> com tipos num\\u00e9ricos para comparar valores e com strings para comparar sua ordem lexical.</p> <p>Se os operandos n\\u00e3o forem compar\\u00e1veis \\u200b\\u200b(por exemplo, slices e mapas), teremos que usar outras op\\u00e7\\u00f5es, como reflex\\u00e3o. A reflex\\u00e3o \\u00e9 uma forma de metaprograma\\u00e7\\u00e3o e se refere \\u00e0 capacidade de um aplicativo de introspectar e modificar sua estrutura e comportamento. Por exemplo, em Go, podemos usar <code>reflect.DeepEqual</code>. Esta fun\\u00e7\\u00e3o informa se dois elementos s\\u00e3o profundamente iguais percorrendo recursivamente dois valores. Os elementos que ele aceita s\\u00e3o tipos b\\u00e1sicos mais arrays, estruturas, slices, mapas, ponteiros, interfaces e fun\\u00e7\\u00f5es. No entanto, o principal problema \\u00e9 a penalidade de desempenho.</p> <p>Se o desempenho for crucial em tempo de execu\\u00e7\\u00e3o, implementar nosso m\\u00e9todo customizado pode ser a melhor solu\\u00e7\\u00e3o. Uma observa\\u00e7\\u00e3o adicional: devemos lembrar que a biblioteca padr\\u00e3o possui alguns m\\u00e9todos de compara\\u00e7\\u00e3o existentes. Por exemplo, podemos usar a fun\\u00e7\\u00e3o <code>bytes.Compare</code> otimizada para comparar duas slices de bytes. Antes de implementar um m\\u00e9todo customizado, precisamos ter certeza de n\\u00e3o reinventar a roda.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#estruturas-de-controle\",\"title\":\"Estruturas de Controle\",\"text\":\"\"},{\"location\":\"pt-br/#ignorando-que-os-elementos-sao-copiados-em-loops-de-range-30\",\"title\":\"Ignorando que os elementos s\\u00e3o copiados em loops de <code>range</code> (#30)\",\"text\":\"TL;DR <p>O elemento de valor em um loop de <code>range</code> \\u00e9 uma c\\u00f3pia. Portanto, para modificar uma struct, por exemplo, acesse-a atrav\\u00e9s de seu \\u00edndice ou atrav\\u00e9s de um loop <code>for</code> cl\\u00e1ssico (a menos que o elemento ou campo que voc\\u00ea deseja modificar seja um ponteiro).</p> <p>Um range loop permite iterar em diferentes estruturas de dados:</p> <ul> <li>String</li> <li>Array</li> <li>Pointer to an array</li> <li>Slice</li> <li>Map</li> <li>Receiving channel</li> </ul> <p>Comparado a um for <code>loop</code> cl\\u00e1ssico, um loop <code>range</code> \\u00e9 uma maneira conveniente de iterar todos os elementos de uma dessas estruturas de dados, gra\\u00e7as \\u00e0 sua sintaxe concisa.</p> <p>Ainda assim, devemos lembrar que o elemento de valor em um range loop \\u00e9 uma c\\u00f3pia. Portanto, se o valor for uma estrutura que precisamos sofrer muta\\u00e7\\u00e3o, atualizaremos apenas a c\\u00f3pia, n\\u00e3o o elemento em si, a menos que o valor ou campo que modificamos seja um ponteiro. As op\\u00e7\\u00f5es preferidas s\\u00e3o acessar o elemento atrav\\u00e9s do \\u00edndice usando um range loop ou um loop for cl\\u00e1ssico.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#ignorando-como-os-argumentos-sao-avaliados-em-range-loops-canais-e-arrays-31\",\"title\":\"Ignorando como os argumentos s\\u00e3o avaliados em range loops (canais e arrays) (#31)\",\"text\":\"TL;DR <p>Entender que a express\\u00e3o passada ao operador <code>range</code> \\u00e9 avaliada apenas uma vez antes do in\\u00edcio do loop pode ajudar a evitar erros comuns, como atribui\\u00e7\\u00e3o ineficiente em canal ou itera\\u00e7\\u00e3o de slice.</p> <p>O range loop avalia a express\\u00e3o fornecida apenas uma vez, antes do in\\u00edcio do loop, fazendo uma c\\u00f3pia (independentemente do tipo). Devemos lembrar deste comportamento para evitar erros comuns que podem, por exemplo, nos levar a acessar o elemento errado. Por exemplo:</p> <pre><code>a := [3]int{0, 1, 2}\\nfor i, v := range a {\\n    a[2] = 10\\n    if i == 2 {\\n        fmt.Println(v)\\n    }\\n}\\n</code></pre> <p>Este c\\u00f3digo atualiza o \\u00faltimo \\u00edndice para 10. No entanto, se executarmos este c\\u00f3digo, ele n\\u00e3o imprimir\\u00e1 10; imprime 2.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#ignorando-os-impactos-do-uso-de-elementos-ponteiros-em-range-loops-32\",\"title\":\"Ignorando os impactos do uso de elementos ponteiros em <code>range</code> loops (#32)\",\"text\":\"Warning <p>Este erro n\\u00e3o \\u00e9 mais relevante no Go 1.22 (detalhes).</p>\"},{\"location\":\"pt-br/#fazendo-suposicoes-erradas-durante-as-iteracoes-de-maps-ordenacao-e-insercao-do-mapa-durante-a-iteracao-33\",\"title\":\"Fazendo suposi\\u00e7\\u00f5es erradas durante as itera\\u00e7\\u00f5es de maps (ordena\\u00e7\\u00e3o e inser\\u00e7\\u00e3o do mapa durante a itera\\u00e7\\u00e3o) (#33)\",\"text\":\"TL;DR <p>Para garantir resultados previs\\u00edveis ao usar maps, lembre-se de que uma estrutura de dados de mapa:</p> <ul> <li>N\\u00e3o ordena os dados por chaves</li> <li>N\\u00e3o preserva o pedido de inser\\u00e7\\u00e3o</li> <li>N\\u00e3o tem uma ordem de itera\\u00e7\\u00e3o determin\\u00edstica</li> <li>N\\u00e3o garante que um elemento adicionado durante uma itera\\u00e7\\u00e3o ser\\u00e1 produzido durante esta itera\\u00e7\\u00e3o</li> </ul> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#ignorando-como-a-declaracao-break-funciona-34\",\"title\":\"Ignorando como a declara\\u00e7\\u00e3o <code>break</code> funciona (#34)\",\"text\":\"TL;DR <p>Usar <code>break</code> ou <code>continue</code> com um r\\u00f3tulo imp\\u00f5e a quebra de uma instru\\u00e7\\u00e3o espec\\u00edfica. Isso pode ser \\u00fatil com instru\\u00e7\\u00f5es <code>switch</code> ou <code>select</code> dentro de loops.</p> <p>Uma instru\\u00e7\\u00e3o break \\u00e9 comumente usada para encerrar a execu\\u00e7\\u00e3o de um loop. Quando loops s\\u00e3o usados \\u200b\\u200bem conjunto com switch ou select, os desenvolvedores frequentemente cometem o erro de quebrar a instru\\u00e7\\u00e3o errada. Por exemplo:</p> <pre><code>for i := 0; i &lt; 5; i++ {\\n    fmt.Printf(\\\"%d \\\", i)\\n\\n    switch i {\\n    default:\\n    case 2:\\n        break\\n    }\\n}\\n</code></pre> <p>A instru\\u00e7\\u00e3o break n\\u00e3o encerra o loop <code>for</code>: em vez disso, ela encerra a instru\\u00e7\\u00e3o <code>switch</code>. Portanto, em vez de iterar de 0 a 2, este c\\u00f3digo itera de 0 a 4: <code>0 1 2 3 4</code>.</p> <p>Uma regra essencial a ter em mente \\u00e9 que uma instru\\u00e7\\u00e3o <code>break</code> encerra a execu\\u00e7\\u00e3o da instru\\u00e7\\u00e3o <code>for</code>, <code>switch</code>, ou mais interna <code>select</code>. No exemplo anterior, ele encerra a instru\\u00e7\\u00e3o <code>switch</code>.</p> <p>Para quebrar o loop em vez da instru\\u00e7\\u00e3o <code>switch</code>, a maneira mais idiom\\u00e1tica \\u00e9 usar um r\\u00f3tulo:</p> <pre><code>loop:\\n    for i := 0; i &lt; 5; i++ {\\n        fmt.Printf(\\\"%d \\\", i)\\n\\n        switch i {\\n        default:\\n        case 2:\\n            break loop\\n        }\\n    }\\n</code></pre> <p>Aqui, associamos o <code>loop</code>r\\u00f3tulo ao <code>for</code> loop. Ent\\u00e3o, como fornecemos o <code>loop</code> r\\u00f3tulo para a instru\\u00e7\\u00e3o <code>break</code>, ela interrompe o loop, n\\u00e3o a op\\u00e7\\u00e3o. Portanto, esta nova vers\\u00e3o ser\\u00e1 impressa <code>0 1 2</code>, como esper\\u00e1vamos.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#usando-defer-dentro-de-um-loop-35\",\"title\":\"Usando <code>defer</code> dentro de um loop (#35)\",\"text\":\"TL;DR <p>Extrair a l\\u00f3gica do loop dentro de uma fun\\u00e7\\u00e3o leva \\u00e0 execu\\u00e7\\u00e3o de uma instru\\u00e7\\u00e3o <code>defer</code> no final de cada itera\\u00e7\\u00e3o.</p> <p>A instru\\u00e7\\u00e3o <code>defer</code> atrasa a execu\\u00e7\\u00e3o de uma chamada at\\u00e9 que a fun\\u00e7\\u00e3o circundante retorne. \\u00c9 usado principalmente para reduzir o c\\u00f3digo padr\\u00e3o. Por exemplo, se um recurso precisar ser fechado eventualmente, podemos usar <code>defer</code> para evitar a repeti\\u00e7\\u00e3o das chamadas de fechamento antes de cada <code>return</code>.</p> <p>Um erro comum com <code>defer</code> \\u00e9 esquecer que ele agenda uma chamada de fun\\u00e7\\u00e3o quando a fun\\u00e7\\u00e3o circundante retorna. Por exemplo:</p> <pre><code>func readFiles(ch &lt;-chan string) error {\\n    for path := range ch {\\n        file, err := os.Open(path)\\n        if err != nil {\\n            return err\\n        }\\n\\n        defer file.Close()\\n\\n        // Do something with file\\n    }\\n    return nil\\n}\\n</code></pre> <p>As chamadas <code>defer</code> n\\u00e3o s\\u00e3o executadas durante cada itera\\u00e7\\u00e3o do loop, mas quando a fun\\u00e7\\u00e3o <code>readFiles</code> retorna. Se <code>readFiles</code> n\\u00e3o retornar, os descritores de arquivos ficar\\u00e3o abertos para sempre, causando vazamentos.</p> <p>Uma op\\u00e7\\u00e3o comum para corrigir esse problema \\u00e9 criar uma fun\\u00e7\\u00e3o circundante ap\\u00f3s <code>defer</code>, chamada durante cada itera\\u00e7\\u00e3o:</p> <pre><code>func readFiles(ch &lt;-chan string) error {\\n    for path := range ch {\\n        if err := readFile(path); err != nil {\\n            return err\\n        }\\n    }\\n    return nil\\n}\\n\\nfunc readFile(path string) error {\\n    file, err := os.Open(path)\\n    if err != nil {\\n        return err\\n    }\\n\\n    defer file.Close()\\n\\n    // Do something with file\\n    return nil\\n}\\n</code></pre> <p>Outra solu\\u00e7\\u00e3o \\u00e9 tornar a fun\\u00e7\\u00e3o <code>readFile</code> um encerramento, mas intrinsecamente, esta permanece a mesma solu\\u00e7\\u00e3o: adicionar outra fun\\u00e7\\u00e3o circundante para executar as chamadas <code>defer</code> durante cada itera\\u00e7\\u00e3o.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#strings\",\"title\":\"Strings\",\"text\":\"\"},{\"location\":\"pt-br/#nao-entendendo-o-conceito-de-rune-36\",\"title\":\"N\\u00e3o entendendo o conceito de rune (#36)\",\"text\":\"TL;DR <p>Entender que uma runa corresponde ao conceito de um ponto de c\\u00f3digo Unicode e que pode ser composta de m\\u00faltiplos bytes deve fazer parte do conhecimento b\\u00e1sico do desenvolvedor Go para trabalhar com precis\\u00e3o com strings.</p> <p>Como as runas est\\u00e3o por toda parte no Go, \\u00e9 importante entender o seguinte:</p> <ul> <li>Um conjunto de caracteres \\u00e9 um conjunto de caracteres, enquanto uma codifica\\u00e7\\u00e3o descreve como traduzir um conjunto de caracteres em bin\\u00e1rio.</li> <li>No Go, uma string faz refer\\u00eancia a uma fatia imut\\u00e1vel de bytes arbitr\\u00e1rios.</li> <li>O c\\u00f3digo-fonte Go \\u00e9 codificado usando UTF-8. Portanto, todos os literais de string s\\u00e3o strings UTF-8. Mas como uma string pode conter bytes arbitr\\u00e1rios, se for obtida de outro lugar (n\\u00e3o do c\\u00f3digo-fonte), n\\u00e3o h\\u00e1 garantia de que seja baseada na codifica\\u00e7\\u00e3o UTF-8.</li> <li>A <code>rune</code> corresponde ao conceito de ponto de c\\u00f3digo Unicode, significando um item representado por um \\u00fanico valor.</li> <li>Usando UTF-8, um ponto de c\\u00f3digo Unicode pode ser codificado em 1 a 4 bytes.</li> <li>Usar <code>len()</code> na string em Go retorna o n\\u00famero de bytes, n\\u00e3o o n\\u00famero de runas.</li> </ul> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#iteracao-de-string-imprecisa-37\",\"title\":\"Itera\\u00e7\\u00e3o de string imprecisa (#37)\",\"text\":\"TL;DR <p>Iterar em uma string com o operador <code>range</code> itera nas runas com o \\u00edndice correspondente ao \\u00edndice inicial da sequ\\u00eancia de bytes da runa. Para acessar um \\u00edndice de runa espec\\u00edfico (como a terceira runa), converta a string em um arquivo <code>[]rune</code>.</p> <p>Iterar em uma string \\u00e9 uma opera\\u00e7\\u00e3o comum para desenvolvedores. Talvez queiramos realizar uma opera\\u00e7\\u00e3o para cada runa na string ou implementar uma fun\\u00e7\\u00e3o personalizada para procurar uma substring espec\\u00edfica. Em ambos os casos, temos que iterar nas diferentes runas de uma string. Mas \\u00e9 f\\u00e1cil ficar confuso sobre como funciona a itera\\u00e7\\u00e3o.</p> <p>For example, consider the following example:</p> <pre><code>s := \\\"h\\u00eallo\\\"\\nfor i := range s {\\n    fmt.Printf(\\\"position %d: %c\\\\n\\\", i, s[i])\\n}\\nfmt.Printf(\\\"len=%d\\\\n\\\", len(s))\\n</code></pre> <pre><code>position 0: h\\nposition 1: \\u00c3\\nposition 3: l\\nposition 4: l\\nposition 5: o\\nlen=6\\n</code></pre> <p>Vamos destacar tr\\u00eas pontos que podem ser confusos:</p> <ul> <li>A segunda runa \\u00e9 \\u00c3 na sa\\u00edda em vez de \\u00ea.</li> <li>Saltamos da posi\\u00e7\\u00e3o 1 para a posi\\u00e7\\u00e3o 3: o que h\\u00e1 na posi\\u00e7\\u00e3o 2?</li> <li>len retorna uma contagem de 6, enquanto s cont\\u00e9m apenas 5 runas.</li> </ul> <p>Vamos come\\u00e7ar com a \\u00faltima observa\\u00e7\\u00e3o. J\\u00e1 mencionamos que len retorna o n\\u00famero de bytes em uma string, n\\u00e3o o n\\u00famero de runas. Como atribu\\u00edmos uma string literal a <code>s</code>, <code>s</code> \\u00e9 uma string UTF-8. Enquanto isso, o caractere especial \\u201c\\u00ea\\u201d n\\u00e3o \\u00e9 codificado em um \\u00fanico byte; requer 2 bytes. Portanto, chamar <code>len(s)</code> retorna 6.</p> <p>Enquanto isso, no exemplo anterior, temos que entender que n\\u00e3o repetimos cada runa; em vez disso, iteramos sobre cada \\u00edndice inicial de uma runa:</p> <p></p> <p>Imprimir <code>s[i]</code> n\\u00e3o imprime a i-\\u00e9sima runa; imprime a representa\\u00e7\\u00e3o UTF-8 do byte em index <code>i</code>. Portanto, imprimimos \\\"h\\u00c3llo\\\" em vez de \\\"h\\u00eallo\\\".</p> <p>Se quisermos imprimir todas as diferentes runas, podemos usar o elemento value do operador <code>range</code>:</p> <pre><code>s := \\\"h\\u00eallo\\\"\\nfor i, r := range s {\\n    fmt.Printf(\\\"position %d: %c\\\\n\\\", i, r)\\n}\\n</code></pre> <p>Ou podemos converter a string em uma fatia de runas e iterar sobre ela:</p> <pre><code>s := \\\"h\\u00eallo\\\"\\nrunes := []rune(s)\\nfor i, r := range runes {\\n    fmt.Printf(\\\"position %d: %c\\\\n\\\", i, r)\\n}\\n</code></pre> <p>Observe que esta solu\\u00e7\\u00e3o introduz uma sobrecarga de tempo de execu\\u00e7\\u00e3o em compara\\u00e7\\u00e3o com a anterior. Na verdade, converter uma string em uma fatia de runas requer a aloca\\u00e7\\u00e3o de uma fatia adicional e a convers\\u00e3o dos bytes em runas: uma complexidade de tempo O(n) com n o n\\u00famero de bytes na string. Portanto, se quisermos iterar todas as runas, devemos usar a primeira solu\\u00e7\\u00e3o.</p> <p>Por\\u00e9m, se quisermos acessar a i-\\u00e9sima runa de uma string com a primeira op\\u00e7\\u00e3o, n\\u00e3o teremos acesso ao \\u00edndice da runa; em vez disso, conhecemos o \\u00edndice inicial de uma runa na sequ\\u00eancia de bytes.</p> <pre><code>s := \\\"h\\u00eallo\\\"\\nr := []rune(s)[4]\\nfmt.Printf(\\\"%c\\\\n\\\", r) // o\\n</code></pre> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#uso-indevido-de-funcoes-de-trim-38\",\"title\":\"Uso indevido de fun\\u00e7\\u00f5es de trim (#38)\",\"text\":\"TL;DR <p><code>strings.TrimRight</code>/<code>strings.TrimLeft</code> remove todas as runas finais/iniciais contidas em um determinado conjunto, enquanto <code>strings.TrimSuffix</code>/<code>strings.TrimPrefix</code> retorna uma string sem um sufixo/prefixo fornecido.</p> <p>Por exemplo:</p> <pre><code>fmt.Println(strings.TrimRight(\\\"123oxo\\\", \\\"xo\\\"))\\n</code></pre> <p>O exemplo imprime 123:</p> <p></p> <p>Por outro lado, <code>strings.TrimLeft</code> remove todas as runas principais contidas em um conjunto.</p> <p>Por outro lado, <code>strings.TrimSuffix</code>/<code>strings.TrimPrefix</code> retorna uma string sem o sufixo/prefixo final fornecido.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#concatenacao-de-strings-subotimizada-39\",\"title\":\"Concatena\\u00e7\\u00e3o de strings subotimizada (#39)\",\"text\":\"TL;DR <p>A concatena\\u00e7\\u00e3o de uma lista de strings deve ser feita com <code>strings.Builder</code> para evitar a aloca\\u00e7\\u00e3o de uma nova string durante cada itera\\u00e7\\u00e3o.</p> <p>Vamos considerar uma fun\\u00e7\\u00e3o <code>concat</code> que concatena todos os elementos string de uma fatia usando o operador <code>+=</code>:</p> <pre><code>func concat(values []string) string {\\n    s := \\\"\\\"\\n    for _, value := range values {\\n        s += value\\n    }\\n    return s\\n}\\n</code></pre> <p>Durante cada itera\\u00e7\\u00e3o, o operador <code>+=</code> concatena com <code>s</code> a sequ\\u00eancia de valores. \\u00c0 primeira vista, esta fun\\u00e7\\u00e3o pode n\\u00e3o parecer errada. Mas com esta implementa\\u00e7\\u00e3o, esquecemos uma das principais caracter\\u00edsticas de uma string: a sua imutabilidade. Portanto, cada itera\\u00e7\\u00e3o n\\u00e3o \\u00e9 atualizada <code>s</code>; ele realoca uma nova string na mem\\u00f3ria, o que impacta significativamente o desempenho desta fun\\u00e7\\u00e3o.</p> <p>Felizmente, existe uma solu\\u00e7\\u00e3o para lidar com esse problema, usando <code>strings.Builder</code>:</p> <pre><code>func concat(values []string) string {\\n    sb := strings.Builder{}\\n    for _, value := range values {\\n        _, _ = sb.WriteString(value)\\n    }\\n    return sb.String()\\n}\\n</code></pre> <p>Durante cada itera\\u00e7\\u00e3o, constru\\u00edmos a string resultante chamando o m\\u00e9todo <code>WriteString</code> que anexa o conte\\u00fado do valor ao seu buffer interno, minimizando assim a c\\u00f3pia da mem\\u00f3ria.</p> Note <p><code>WriteString</code> retorna um erro como segunda sa\\u00edda, mas n\\u00f3s o ignoramos propositalmente. Na verdade, este m\\u00e9todo nunca retornar\\u00e1 um erro diferente de zero. Ent\\u00e3o, qual \\u00e9 o prop\\u00f3sito deste m\\u00e9todo retornar um erro como parte de sua assinatura? <code>strings.Builder</code> implementa a <code>io.StringWriter</code> interface, que cont\\u00e9m um \\u00fanico m\\u00e9todo: <code>WriteString(s string) (n int, err error)</code>. Portanto, para estar em conformidade com esta interface, <code>WriteString</code> deve retornar um erro.</p> <p>Internamente, <code>strings.Builder</code> cont\\u00e9m uma fatia de bytes. Cada chamada para <code>WriteString</code> resulta em uma chamada para anexar nesta fatia. Existem dois impactos. Primeiro, esta estrutura n\\u00e3o deve ser usada simultaneamente, pois as chamadas <code>append</code> levariam a condi\\u00e7\\u00f5es de corrida. O segundo impacto \\u00e9 algo que vimos no mistake #21, \\\"Inicializa\\u00e7\\u00e3o de slice ineficiente\\\": se o comprimento futuro de uma slice j\\u00e1 for conhecido, devemos pr\\u00e9-aloc\\u00e1-la. Para isso, <code>strings.Builder</code> exp\\u00f5e um m\\u00e9todo <code>Grow(n int)</code> para garantir espa\\u00e7o para outros <code>n</code> bytes:</p> <pre><code>func concat(values []string) string {\\n    total := 0\\n    for i := 0; i &lt; len(values); i++ {\\n        total += len(values[i])\\n    }\\n\\n    sb := strings.Builder{}\\n    sb.Grow(total) (2)\\n    for _, value := range values {\\n        _, _ = sb.WriteString(value)\\n    }\\n    return sb.String()\\n}\\n</code></pre> <p>Vamos executar um benchmark para comparar as tr\\u00eas vers\\u00f5es (v1 usando <code>+=</code>; v2 usando <code>strings.Builder{}</code> sem pr\\u00e9-aloca\\u00e7\\u00e3o; e v3 usando <code>strings.Builder{}</code> com pr\\u00e9-aloca\\u00e7\\u00e3o). A slice de entrada cont\\u00e9m 1.000 strings e cada string cont\\u00e9m 1.000 bytes:</p> <pre><code>BenchmarkConcatV1-4             16      72291485 ns/op\\nBenchmarkConcatV2-4           1188        878962 ns/op\\nBenchmarkConcatV3-4           5922        190340 ns/op\\n</code></pre> <p>Como podemos ver, a vers\\u00e3o mais recente \\u00e9 de longe a mais eficiente: 99% mais r\\u00e1pida que a v1 e 78% mais r\\u00e1pida que a v2.</p> <p><code>strings.Builder</code> \\u00e9 a solu\\u00e7\\u00e3o recomendada para concatenar uma lista de strings. Normalmente, esta solu\\u00e7\\u00e3o deve ser usada dentro de um loop. Na verdade, se precisarmos apenas concatenar algumas strings (como um nome e um sobrenome), o uso <code>strings.Builder</code> n\\u00e3o \\u00e9 recomendado, pois isso tornar\\u00e1 o c\\u00f3digo um pouco menos leg\\u00edvel do que usar o operador <code>+=</code> or <code>fmt.Sprintf</code>.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#conversoes-de-string-inuteis-40\",\"title\":\"Convers\\u00f5es de string in\\u00fateis (#40)\",\"text\":\"TL;DR <p>Lembrar que o pacote <code>bytes</code> oferece as mesmas opera\\u00e7\\u00f5es que o pacote <code>strings</code> pode ajudar a evitar convers\\u00f5es extras de bytes/string.</p> <p>Ao optar por trabalhar com uma string ou um <code>[]byte</code>, a maioria dos programadores tende a preferir strings por conveni\\u00eancia. Mas a maior parte da E/S \\u00e9 realmente feita com <code>[]byte</code>. Por exemplo, <code>io.Reader</code>, <code>io.Writer</code> e <code>io.ReadAll</code> trabalham com <code>[]byte</code>, n\\u00e3o com strings.</p> <p>Quando nos perguntamos se devemos trabalhar com strings ou <code>[]byte</code>, lembremos que trabalhar com <code>[]byte</code>n\\u00e3o \\u00e9 necessariamente menos conveniente. Na verdade, todas as fun\\u00e7\\u00f5es exportadas do pacote strings tamb\\u00e9m possuem alternativas no pacote <code>bytes</code>: <code>Split</code>, <code>Count</code>, <code>Contains</code>, <code>Index</code> e assim por diante. Portanto, estejamos fazendo I/O ou n\\u00e3o, devemos primeiro verificar se poder\\u00edamos implementar um fluxo de trabalho completo usando bytes em vez de strings e evitar o pre\\u00e7o de convers\\u00f5es adicionais.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#vazamentos-de-substring-e-memoria-41\",\"title\":\"Vazamentos de substring e mem\\u00f3ria (#41)\",\"text\":\"TL;DR <p>Usar c\\u00f3pias em vez de substrings pode evitar vazamentos de mem\\u00f3ria, pois a string retornada por uma opera\\u00e7\\u00e3o de substring ser\\u00e1 apoiada pela mesma matriz de bytes.</p> <p>In mistake #26, \\u201cSlices and memory leaks,\\u201d we saw how slicing a slice or array may lead to memory leak situations. This principle also applies to string and substring operations.</p> <p>We need to keep two things in mind while using the substring operation in Go. First, the interval provided is based on the number of bytes, not the number of runes. Second, a substring operation may lead to a memory leak as the resulting substring will share the same backing array as the initial string. The solutions to prevent this case from happening are to perform a string copy manually or to use <code>strings.Clone</code> from Go 1.18.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#functions-and-methods\",\"title\":\"Functions and Methods\",\"text\":\"\"},{\"location\":\"pt-br/#nao-saber-que-tipo-de-receptor-usar-42\",\"title\":\"N\\u00e3o saber que tipo de receptor usar (#42)\",\"text\":\"TL;DR <p>A decis\\u00e3o de usar um valor ou um receptor de ponteiro deve ser tomada com base em fatores como o tipo, se deve sofrer muta\\u00e7\\u00e3o, se cont\\u00e9m um campo que n\\u00e3o pode ser copiado e o tamanho do objeto. Em caso de d\\u00favida, use um receptor de ponteiro.</p> <p>Choosing between value and pointer receivers isn\\u2019t always straightforward. Let\\u2019s discuss some of the conditions to help us choose.</p> <p>A receiver must be a pointer</p> <ul> <li>If the method needs to mutate the receiver. This rule is also valid if the receiver is a slice and a method needs to append elements:</li> </ul> <pre><code>type slice []int\\n\\nfunc (s *slice) add(element int) {\\n    *s = append(*s, element)\\n}\\n</code></pre> <ul> <li>If the method receiver contains a field that cannot be copied: for example, a type part of the sync package (see #74, \\u201cCopying a sync type\\u201d).</li> </ul> <p>A receiver should be a pointer</p> <ul> <li>If the receiver is a large object. Using a pointer can make the call more efficient, as doing so prevents making an extensive copy. When in doubt about how large is large, benchmarking can be the solution; it\\u2019s pretty much impossible to state a specific size, because it depends on many factors.</li> </ul> <p>A receiver must be a value</p> <ul> <li>If we have to enforce a receiver\\u2019s immutability.</li> <li>If the receiver is a map, function, or channel. Otherwise, a compilation error   occurs.</li> </ul> <p>A receiver should be a value</p> <ul> <li>If the receiver is a slice that doesn\\u2019t have to be mutated.</li> <li>If the receiver is a small array or struct that is naturally a value type without mutable fields, such as <code>time.Time</code>.</li> <li>If the receiver is a basic type such as <code>int</code>, <code>float64</code>, or <code>string</code>.</li> </ul> <p>Of course, it\\u2019s impossible to be exhaustive, as there will always be edge cases, but this section\\u2019s goal was to provide guidance to cover most cases. By default, we can choose to go with a value receiver unless there\\u2019s a good reason not to do so. In doubt, we should use a pointer receiver.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nunca-usando-parametros-de-resultado-nomeados-43\",\"title\":\"Nunca usando par\\u00e2metros de resultado nomeados (#43)\",\"text\":\"TL;DR <p>Usar par\\u00e2metros de resultado nomeados pode ser uma maneira eficiente de melhorar a legibilidade de uma fun\\u00e7\\u00e3o/m\\u00e9todo, especialmente se v\\u00e1rios par\\u00e2metros de resultado tiverem o mesmo tipo. Em alguns casos, esta abordagem tamb\\u00e9m pode ser conveniente porque os par\\u00e2metros de resultado nomeados s\\u00e3o inicializados com seu valor zero. Mas tenha cuidado com os poss\\u00edveis efeitos colaterais.</p> <p>When we return parameters in a function or a method, we can attach names to these parameters and use them as regular variables. When a result parameter is named, it\\u2019s initialized to its zero value when the function/method begins. With named result parameters, we can also call a naked return statement (without arguments). In that case, the current values of the result parameters are used as the returned values.</p> <p>Here\\u2019s an example that uses a named result parameter <code>b</code>:</p> <pre><code>func f(a int) (b int) {\\n    b = a\\n    return\\n}\\n</code></pre> <p>In this example, we attach a name to the result parameter: <code>b</code>. When we call return without arguments, it returns the current value of <code>b</code>.</p> <p>In some cases, named result parameters can also increase readability: for example, if two parameters have the same type. In other cases, they can also be used for convenience. Therefore, we should use named result parameters sparingly when there\\u2019s a clear benefit.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#efeitos-colaterais-nao-intencionais-com-parametros-de-resultado-nomeados-44\",\"title\":\"Efeitos colaterais n\\u00e3o intencionais com par\\u00e2metros de resultado nomeados (#44)\",\"text\":\"TL;DR <p>Consulte #43.</p> <p>We mentioned why named result parameters can be useful in some situations. But as these result parameters are initialized to their zero value, using them can sometimes lead to subtle bugs if we\\u2019re not careful enough. For example, can you spot what\\u2019s wrong with this code?</p> <pre><code>func (l loc) getCoordinates(ctx context.Context, address string) (\\n    lat, lng float32, err error) {\\n    isValid := l.validateAddress(address) (1)\\n    if !isValid {\\n        return 0, 0, errors.New(\\\"invalid address\\\")\\n    }\\n\\n    if ctx.Err() != nil { (2)\\n        return 0, 0, err\\n    }\\n\\n    // Get and return coordinates\\n}\\n</code></pre> <p>The error might not be obvious at first glance. Here, the error returned in the <code>if ctx.Err() != nil</code> scope is <code>err</code>. But we haven\\u2019t assigned any value to the <code>err</code> variable. It\\u2019s still assigned to the zero value of an <code>error</code> type: <code>nil</code>. Hence, this code will always return a nil error.</p> <p>When using named result parameters, we must recall that each parameter is initialized to its zero value. As we have seen in this section, this can lead to subtle bugs that aren\\u2019t always straightforward to spot while reading code. Therefore, let\\u2019s remain cautious when using named result parameters, to avoid potential side effects.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#retornando-um-receptor-nulo-45\",\"title\":\"Retornando um receptor nulo (#45)\",\"text\":\"TL;DR <p>Ao retornar uma interface, tenha cuidado para n\\u00e3o retornar um ponteiro nulo, mas um valor nulo expl\\u00edcito. Caso contr\\u00e1rio, poder\\u00e3o ocorrer consequ\\u00eancias n\\u00e3o intencionais e o chamador receber\\u00e1 um valor diferente de zero.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#usando-um-nome-de-arquivo-como-entrada-de-funcao-46\",\"title\":\"Usando um nome de arquivo como entrada de fun\\u00e7\\u00e3o (#46)\",\"text\":\"TL;DR <p>Projetar fun\\u00e7\\u00f5es para receber tipos <code>io.Reader</code> em vez de nomes de arquivos melhora a capacidade de reutiliza\\u00e7\\u00e3o de uma fun\\u00e7\\u00e3o e facilita o teste.</p> <p>Accepting a filename as a function input to read from a file should, in most cases, be considered a code smell (except in specific functions such as <code>os.Open</code>). Indeed, it makes unit tests more complex because we may have to create multiple files. It also reduces the reusability of a function (although not all functions are meant to be reused). Using the <code>io.Reader</code> interface abstracts the data source. Regardless of whether the input is a file, a string, an HTTP request, or a gRPC request, the implementation can be reused and easily tested.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#ignorando-como-argumentos-defer-e-receptores-sao-avaliados-avaliacao-de-argumentos-ponteiros-e-receptores-de-valor-47\",\"title\":\"Ignorando como argumentos <code>defer</code> e receptores s\\u00e3o avaliados (avalia\\u00e7\\u00e3o de argumentos, ponteiros e receptores de valor) (#47)\",\"text\":\"TL;DR <p>Passar um ponteiro para uma fun\\u00e7\\u00e3o <code>defer</code> e agrupar uma chamada dentro de um closure s\\u00e3o duas solu\\u00e7\\u00f5es poss\\u00edveis para superar a avalia\\u00e7\\u00e3o imediata de argumentos e receptores.</p> <p>In a <code>defer</code> function the arguments are evaluated right away, not once the surrounding function returns. For example, in this code, we always call <code>notify</code> and <code>incrementCounter</code> with the same status: an empty string.</p> <pre><code>const (\\n    StatusSuccess  = \\\"success\\\"\\n    StatusErrorFoo = \\\"error_foo\\\"\\n    StatusErrorBar = \\\"error_bar\\\"\\n)\\n\\nfunc f() error {\\n    var status string\\n    defer notify(status)\\n    defer incrementCounter(status)\\n\\n    if err := foo(); err != nil {\\n        status = StatusErrorFoo\\n        return err\\n    }\\n\\n    if err := bar(); err != nil {\\n        status = StatusErrorBar\\n        return err\\n    }\\n\\n    status = StatusSuccess &lt;5&gt;\\n    return nil\\n}\\n</code></pre> <p>Indeed, we call <code>notify(status)</code> and <code>incrementCounter(status)</code> as <code>defer</code> functions. Therefore, Go will delay these calls to be executed once <code>f</code> returns with the current value of status at the stage we used defer, hence passing an empty string.</p> <p>Two leading options if we want to keep using <code>defer</code>.</p> <p>The first solution is to pass a string pointer:</p> <pre><code>func f() error {\\n    var status string\\n    defer notify(&amp;status) \\n    defer incrementCounter(&amp;status)\\n\\n    // The rest of the function unchanged\\n}\\n</code></pre> <p>Using <code>defer</code> evaluates the arguments right away: here, the address of status. Yes, status itself is modified throughout the function, but its address remains constant, regardless of the assignments. Hence, if <code>notify</code> or <code>incrementCounter</code> uses the value referenced by the string pointer, it will work as expected. But this solution requires changing the signature of the two functions, which may not always be possible.</p> <p>There\\u2019s another solution: calling a closure (an anonymous function value that references variables from outside its body) as a <code>defer</code> statement:</p> <pre><code>func f() error {\\n    var status string\\n    defer func() {\\n        notify(status)\\n        incrementCounter(status)\\n    }()\\n\\n    // The rest of the function unchanged\\n}\\n</code></pre> <p>Here, we wrap the calls to both <code>notify</code> and <code>incrementCounter</code> within a closure. This closure references the status variable from outside its body. Therefore, <code>status</code> is evaluated once the closure is executed, not when we call <code>defer</code>. This solution also works and doesn\\u2019t require <code>notify</code> and <code>incrementCounter</code> to change their signature.</p> <p>Let's also note this behavior applies with method receiver: the receiver is evaluated immediately.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#error-management\",\"title\":\"Error Management\",\"text\":\"\"},{\"location\":\"pt-br/#panico-48\",\"title\":\"P\\u00e2nico (#48)\",\"text\":\"TL;DR <p>Usar <code>panic</code> \\u00e9 uma op\\u00e7\\u00e3o para lidar com erros no Go. No entanto, s\\u00f3 deve ser usado com modera\\u00e7\\u00e3o em condi\\u00e7\\u00f5es irrecuper\\u00e1veis: por exemplo, para sinalizar um erro do programador ou quando voc\\u00ea n\\u00e3o consegue carregar uma depend\\u00eancia obrigat\\u00f3ria.</p> <p>In Go, panic is a built-in function that stops the ordinary flow:</p> <pre><code>func main() {\\n    fmt.Println(\\\"a\\\")\\n    panic(\\\"foo\\\")\\n    fmt.Println(\\\"b\\\")\\n}\\n</code></pre> <p>This code prints a and then stops before printing b:</p> <pre><code>a\\npanic: foo\\n\\ngoroutine 1 [running]:\\nmain.main()\\n        main.go:7 +0xb3\\n</code></pre> <p>Panicking in Go should be used sparingly. There are two prominent cases, one to signal a programmer error (e.g., <code>sql.Register</code> that panics if the driver is <code>nil</code> or has already been register) and another where our application fails to create a mandatory dependency. Hence, exceptional conditions that lead us to stop the application. In most other cases, error management should be done with a function that returns a proper error type as the last return argument.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#ignorando-quando-embrulhar-um-erro-49\",\"title\":\"Ignorando quando embrulhar um erro (#49)\",\"text\":\"TL;DR <p>Embrulhar um erro permite marcar um erro e/ou fornecer contexto adicional. No entanto, o agrupamento de erros cria um acoplamento potencial, pois disponibiliza o erro de origem para o chamador. Se voc\\u00ea quiser evitar isso, n\\u00e3o use a agrupamento autom\\u00e1tico de erros.</p> <p>Since Go 1.13, the %w directive allows us to wrap errors conveniently. Error wrapping is about wrapping or packing an error inside a wrapper container that also makes the source error available. In general, the two main use cases for error wrapping are the following:</p> <ul> <li>Adding additional context to an error</li> <li>Marking an error as a specific error</li> </ul> <p>When handling an error, we can decide to wrap it. Wrapping is about adding additional context to an error and/or marking an error as a specific type. If we need to mark an error, we should create a custom error type. However, if we just want to add extra context, we should use fmt.Errorf with the %w directive as it doesn\\u2019t require creating a new error type. Yet, error wrapping creates potential coupling as it makes the source error available for the caller. If we want to prevent it, we shouldn\\u2019t use error wrapping but error transformation, for example, using fmt.Errorf with the %v directive.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#comparando-um-tipo-de-erro-de-forma-imprecisa-50\",\"title\":\"Comparando um tipo de erro de forma imprecisa (#50)\",\"text\":\"TL;DR <p>Se voc\\u00ea usar o agrupamento de erros do Go 1.13 com a diretiva <code>%w</code> e <code>fmt.Errorf</code>, a compara\\u00e7\\u00e3o de um erro com um tipo dever\\u00e1 ser feita usando <code>errors.As</code>. Caso contr\\u00e1rio, se o erro retornado que voc\\u00ea deseja verificar for embrulhado, as verifica\\u00e7\\u00f5es falhar\\u00e3o.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#comparando-um-valor-de-erro-incorretamente-51\",\"title\":\"Comparando um valor de erro incorretamente (#51)\",\"text\":\"TL;DR <p>Se voc\\u00ea usar o agrupamento de erros do Go 1.13 com a diretiva <code>%w</code> e <code>fmt.Errorf</code>, a compara\\u00e7\\u00e3o de um erro ou de um valor dever\\u00e1 ser feita usando <code>errors.As</code>. Caso contr\\u00e1rio, se o erro retornado que voc\\u00ea deseja verificar for embrulhado, as verifica\\u00e7\\u00f5es falhar\\u00e3o.</p> <p>A sentinel error is an error defined as a global variable:</p> <pre><code>import \\\"errors\\\"\\n\\nvar ErrFoo = errors.New(\\\"foo\\\")\\n</code></pre> <p>In general, the convention is to start with <code>Err</code> followed by the error type: here, <code>ErrFoo</code>. A sentinel error conveys an expected error, an error that clients will expect to check. As general guidelines:</p> <ul> <li>Expected errors should be designed as error values (sentinel errors): <code>var ErrFoo = errors.New(\\\"foo\\\")</code>.</li> <li>Unexpected errors should be designed as error types: <code>type BarError struct { ... }</code>, with <code>BarError</code> implementing the <code>error</code> interface.</li> </ul> <p>If we use error wrapping in our application with the <code>%w</code> directive and <code>fmt.Errorf</code>, checking an error against a specific value should be done using <code>errors.Is</code> instead of <code>==</code>. Thus, even if the sentinel error is wrapped, <code>errors.Is</code> can recursively unwrap it and compare each error in the chain against the provided value.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#lidando-com-um-erro-duas-vezes-52\",\"title\":\"Lidando com um erro duas vezes (#52)\",\"text\":\"TL;DR <p>Na maioria das situa\\u00e7\\u00f5es, um erro deve ser tratado apenas uma vez. Registrar um erro \\u00e9 tratar um erro. Portanto, voc\\u00ea deve escolher entre registrar ou retornar um erro. Em muitos casos, o embrulho autom\\u00e1tico de erros \\u00e9 a solu\\u00e7\\u00e3o, pois permite fornecer contexto adicional a um erro e retornar o erro de origem.</p> <p>Handling an error multiple times is a mistake made frequently by developers, not specifically in Go. This can cause situations where the same error is logged multiple times make debugging harder.</p> <p>Let's remind us that handling an error should be done only once. Logging an error is handling an error. Hence, we should either log or return an error. By doing this, we simplify our code and gain better insights into the error situation. Using error wrapping is the most convenient approach as it allows us to propagate the source error and add context to an error.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-tratando-de-um-erro-53\",\"title\":\"N\\u00e3o tratando de um erro (#53)\",\"text\":\"TL;DR <p>Ignorar um erro, seja durante uma chamada de fun\\u00e7\\u00e3o ou em uma fun\\u00e7\\u00e3o <code>defer</code>, deve ser feito explicitamente usando o identificador em branco. Caso contr\\u00e1rio, os futuros leitores poder\\u00e3o ficar confusos sobre se foi intencional ou um erro.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-tratando-erros-de-defer-54\",\"title\":\"N\\u00e3o tratando erros de <code>defer</code> (#54)\",\"text\":\"TL;DR <p>Em muitos casos, voc\\u00ea n\\u00e3o deve ignorar um erro retornado por uma fun\\u00e7\\u00e3o <code>defer</code>. Manipule-o diretamente ou propague-o para o chamador, dependendo do contexto. Se voc\\u00ea quiser ignor\\u00e1-lo, use o identificador em branco.</p> <p>Consider the following code:</p> <pre><code>func f() {\\n  // ...\\n  notify() // Error handling is omitted\\n}\\n\\nfunc notify() error {\\n  // ...\\n}\\n</code></pre> <p>From a maintainability perspective, the code can lead to some issues. Let\\u2019s consider a new reader looking at it. This reader notices that notify returns an error but that the error isn\\u2019t handled by the parent function. How can they guess whether or not handling the error was intentional? How can they know whether the previous developer forgot to handle it or did it purposely?</p> <p>For these reasons, when we want to ignore an error, there's only one way to do it, using the blank identifier (<code>_</code>):</p> <pre><code>_ = notify\\n</code></pre> <p>In terms of compilation and run time, this approach doesn\\u2019t change anything compared to the first piece of code. But this new version makes explicit that we aren\\u2019t interested in the error. Also, we can add a comment that indicates the rationale for why an error is ignored:</p> <pre><code>// At-most once delivery.\\n// Hence, it's accepted to miss some of them in case of errors.\\n_ = notify()\\n</code></pre> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#concurrency-foundations\",\"title\":\"Concurrency: Foundations\",\"text\":\"\"},{\"location\":\"pt-br/#misturando-simultaneidade-e-paralelismo-55\",\"title\":\"Misturando simultaneidade e paralelismo (#55)\",\"text\":\"TL;DR <p>Compreender as diferen\\u00e7as fundamentais entre simultaneidade e paralelismo \\u00e9 a base do conhecimento do desenvolvedor Go. A simultaneidade tem a ver com estrutura, enquanto o paralelismo tem a ver com execu\\u00e7\\u00e3o.</p> <p>Concurrency and parallelism are not the same:</p> <ul> <li>Concurrency is about structure. We can change a sequential implementation into a concurrent one by introducing different steps that separate concurrent goroutines can tackle.</li> <li>Meanwhile, parallelism is about execution. We can use parallism at the steps level by adding more parallel goroutines.</li> </ul> <p>In summary, concurrency provides a structure to solve a problem with parts that may be parallelized. Therefore, concurrency enables parallelism.</p>\"},{\"location\":\"pt-br/#pensar-que-a-simultaneidade-e-sempre-mais-rapida-56\",\"title\":\"Pensar que a simultaneidade \\u00e9 sempre mais r\\u00e1pida (#56)\",\"text\":\"TL;DR <p>Para ser um desenvolvedor proficiente, voc\\u00ea deve reconhecer que a simultaneidade nem sempre \\u00e9 mais r\\u00e1pida. As solu\\u00e7\\u00f5es que envolvem a paraleliza\\u00e7\\u00e3o de cargas de trabalho m\\u00ednimas podem n\\u00e3o ser necessariamente mais r\\u00e1pidas do que uma implementa\\u00e7\\u00e3o sequencial. A avalia\\u00e7\\u00e3o comparativa de solu\\u00e7\\u00f5es sequenciais versus solu\\u00e7\\u00f5es simult\\u00e2neas deve ser a forma de validar suposi\\u00e7\\u00f5es.</p> <p>Read the full section here.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#ficar-confuso-sobre-quando-usar-canais-ou-mutexes-57\",\"title\":\"Ficar confuso sobre quando usar canais ou mutexes (#57)\",\"text\":\"TL;DR <p>Estar ciente das intera\\u00e7\\u00f5es goroutine tamb\\u00e9m pode ser \\u00fatil ao decidir entre canais e mutexes. Em geral, goroutines paralelas requerem sincroniza\\u00e7\\u00e3o e, portanto, mutexes. Por outro lado, goroutines simult\\u00e2neas geralmente requerem coordena\\u00e7\\u00e3o e orquestra\\u00e7\\u00e3o e, portanto, canais.</p> <p>Given a concurrency problem, it may not always be clear whether we can implement a solution using channels or mutexes. Because Go promotes sharing memory by communication, one mistake could be to always force the use of channels, regardless of the use case. However, we should see the two options as complementary. </p> <p>When should we use channels or mutexes? We will use the example in the next figure as a backbone. Our example has three different goroutines with specific relationships:</p> <ul> <li>G1 and G2 are parallel goroutines. They may be two goroutines executing the same function that keeps receiving messages from a channel, or perhaps two goroutines executing the same HTTP handler at the same time.</li> <li>On the other hand, G1 and G3 are concurrent goroutines, as are G2 and G3. All the goroutines are part of an overall concurrent structure, but G1 and G2 perform the first step, whereas G3 does the next step.</li> </ul> <p>In general, parallel goroutines have to synchronize: for example, when they need to access or mutate a shared resource such as a slice. Synchronization is enforced with mutexes but not with any channel types (not with buffered channels). Hence, in general, synchronization between parallel goroutines should be achieved via mutexes.</p> <p>Conversely, in general, concurrent goroutines have to coordinate and orchestrate. For example, if G3 needs to aggregate results from both G1 and G2, G1 and G2 need to signal to G3 that a new intermediate result is available. This coordination falls under the scope of communication\\u2014therefore, channels.</p> <p>Regarding concurrent goroutines, there\\u2019s also the case where we want to transfer the ownership of a resource from one step (G1 and G2) to another (G3); for example, if G1 and G2 are enriching a shared resource and at some point, we consider this job as complete. Here, we should use channels to signal that a specific resource is ready and handle the ownership transfer.</p> <p>Mutexes and channels have different semantics. Whenever we want to share a state or access a shared resource, mutexes ensure exclusive access to this resource. Conversely, channels are a mechanic for signaling with or without data (<code>chan struct{}</code> or not). Coordination or ownership transfer should be achieved via channels. It\\u2019s important to know whether goroutines are parallel or concurrent because, in general, we need mutexes for parallel goroutines and channels for concurrent ones.</p>\"},{\"location\":\"pt-br/#nao-entender-os-problemas-de-corrida-corridas-de-dados-vs-condicoes-de-corrida-e-o-modelo-de-memoria-go-58\",\"title\":\"N\\u00e3o entender os problemas de corrida (corridas de dados vs. condi\\u00e7\\u00f5es de corrida e o modelo de mem\\u00f3ria Go) (#58)\",\"text\":\"TL;DR <p>Ser proficiente em simultaneidade tamb\\u00e9m significa compreender que corridas de dados e condi\\u00e7\\u00f5es de corrida s\\u00e3o conceitos diferentes. As corridas de dados ocorrem quando v\\u00e1rias goroutines acessam simultaneamente o mesmo local de mem\\u00f3ria e pelo menos uma delas est\\u00e1 gravando. Enquanto isso, estar livre de disputa de dados n\\u00e3o significa necessariamente execu\\u00e7\\u00e3o determin\\u00edstica. Quando um comportamento depende da sequ\\u00eancia ou do tempo de eventos que n\\u00e3o podem ser controlados, esta \\u00e9 uma condi\\u00e7\\u00e3o de corrida.</p> <p>Race problems can be among the hardest and most insidious bugs a programmer can face. As Go developers, we must understand crucial aspects such as data races and race conditions, their possible impacts, and how to avoid them.</p>\"},{\"location\":\"pt-br/#data-race\",\"title\":\"Data Race\",\"text\":\"<p>A data race occurs when two or more goroutines simultaneously access the same memory location and at least one is writing. In this case, the result can be hazardous. Even worse, in some situations, the memory location may end up holding a value containing a meaningless combination of bits.</p> <p>We can prevent a data race from happening using different techniques. For example: </p> <ul> <li>Using the <code>sync/atomic</code> package</li> <li>In synchronizing the two goroutines with an ad hoc data structure like a mutex</li> <li>Using channels to make the two goroutines communicating to ensure that a variable is updated by only one goroutine at a time</li> </ul>\"},{\"location\":\"pt-br/#race-condition\",\"title\":\"Race Condition\",\"text\":\"<p>Depending on the operation we want to perform, does a data-race-free application necessarily mean a deterministic result? Not necessarily.</p> <p>A race condition occurs when the behavior depends on the sequence or the timing of events that can\\u2019t be controlled. Here, the timing of events is the goroutines\\u2019 execution order.</p> <p>In summary, when we work in concurrent applications, it\\u2019s essential to understand that a data race is different from a race condition. A data race occurs when multiple goroutines simultaneously access the same memory location and at least one of them is writing. A data race means unexpected behavior. However, a data-race-free application doesn\\u2019t necessarily mean deterministic results. An application can be free of data races but still have behavior that depends on uncontrolled events (such as goroutine execution, how fast a message is published to a channel, or how long a call to a database lasts); this is a race condition. Understanding both concepts is crucial to becoming proficient in designing concurrent applications.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-compreender-os-impactos-de-simultaneidade-de-um-tipo-de-carga-de-trabalho-59\",\"title\":\"N\\u00e3o compreender os impactos de simultaneidade de um tipo de carga de trabalho (#59)\",\"text\":\"TL;DR <p>Ao criar um determinado n\\u00famero de goroutines, considere o tipo de carga de trabalho. Criar goroutines vinculadas \\u00e0 CPU significa limitar esse n\\u00famero pr\\u00f3ximo \\u00e0 vari\\u00e1vel GOMAXPROCS (baseado por padr\\u00e3o no n\\u00famero de n\\u00facleos de CPU no host). A cria\\u00e7\\u00e3o de goroutines vinculadas a E/S depende de outros fatores, como o sistema externo.</p> <p>In programming, the execution time of a workload is limited by one of the following:</p> <ul> <li>The speed of the CPU\\u2014For example, running a merge sort algorithm. The workload is called CPU-bound.</li> <li>The speed of I/O\\u2014For example, making a REST call or a database query. The workload is called I/O-bound.</li> <li>The amount of available memory\\u2014The workload is called memory-bound.</li> </ul> Note <p>The last is the rarest nowadays, given that memory has become very cheap in recent decades. Hence, this section focuses on the two first workload types: CPU- and I/O-bound.</p> <p>If the workload executed by the workers is I/O-bound, the value mainly depends on the external system. Conversely, if the workload is CPU-bound, the optimal number of goroutines is close to the number of available CPU cores (a best practice can be to use <code>runtime.GOMAXPROCS</code>). Knowing the workload type (I/O or CPU) is crucial when designing concurrent applications.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#incompreensao-dos-contextos-go-60\",\"title\":\"Incompreens\\u00e3o dos contextos Go (#60)\",\"text\":\"TL;DR <p>Os contextos Go tamb\\u00e9m s\\u00e3o um dos pilares da simultaneidade em Go. Um contexto permite que voc\\u00ea carregue um prazo, um sinal de cancelamento e/ou uma lista de valores-chave.</p> <p>https://pkg.go.dev/context</p> <p>A Context carries a deadline, a cancellation signal, and other values across API boundaries.</p>\"},{\"location\":\"pt-br/#deadline\",\"title\":\"Deadline\",\"text\":\"<p>A deadline refers to a specific point in time determined with one of the following:</p> <ul> <li>A <code>time.Duration</code> from now (for example, in 250 ms)</li> <li>A <code>time.Time</code> (for example, 2023-02-07 00:00:00 UTC)</li> </ul> <p>The semantics of a deadline convey that an ongoing activity should be stopped if this deadline is met. An activity is, for example, an I/O request or a goroutine waiting to receive a message from a channel.</p>\"},{\"location\":\"pt-br/#cancellation-signals\",\"title\":\"Cancellation signals\",\"text\":\"<p>Another use case for Go contexts is to carry a cancellation signal. Let\\u2019s imagine that we want to create an application that calls <code>CreateFileWatcher(ctx context.Context, filename string)</code> within another goroutine. This function creates a specific file watcher that keeps reading from a file and catches updates. When the provided context expires or is canceled, this function handles it to close the file descriptor.</p>\"},{\"location\":\"pt-br/#context-values\",\"title\":\"Context values\",\"text\":\"<p>The last use case for Go contexts is to carry a key-value list. What\\u2019s the point of having a context carrying a key-value list? Because Go contexts are generic and mainstream, there are infinite use cases.</p> <p>For example, if we use tracing, we may want different subfunctions to share the same correlation ID. Some developers may consider this ID too invasive to be part of the function signature. In this regard, we could also decide to include it as part of the provided context.</p>\"},{\"location\":\"pt-br/#catching-a-context-cancellation\",\"title\":\"Catching a context cancellation\",\"text\":\"<p>The <code>context.Context</code> type exports a <code>Done</code> method that returns a receive-only notification channel: <code>&lt;-chan struct{}</code>. This channel is closed when the work associated with the context should be canceled. For example,</p> <ul> <li>The Done channel related to a context created with <code>context.WithCancel</code> is closed when the cancel function is called.</li> <li>The Done channel related to a context created with <code>context.WithDeadline</code> is closed when the deadline has expired.</li> </ul> <p>One thing to note is that the internal channel should be closed when a context is canceled or has met a deadline, instead of when it receives a specific value, because the closure of a channel is the only channel action that all the consumer goroutines will receive. This way, all the consumers will be notified once a context is canceled or a deadline is reached.</p> <p>In summary, to be a proficient Go developer, we have to understand what a context is and how to use it. In general, a function that users wait for should take a context, as doing so allows upstream callers to decide when calling this function should be aborted. </p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#concurrency-practice\",\"title\":\"Concurrency: Practice\",\"text\":\"\"},{\"location\":\"pt-br/#propagando-um-contexto-improprio-61\",\"title\":\"Propagando um contexto impr\\u00f3prio (#61)\",\"text\":\"TL;DR <p>Compreender as condi\\u00e7\\u00f5es em que um contexto pode ser cancelado deve ser importante ao propag\\u00e1-lo: por exemplo, um manipulador HTTP cancelando o contexto quando a resposta for enviada.</p> <p>In many situations, it is recommended to propagate Go contexts. However, context propagation can sometimes lead to subtle bugs, preventing subfunctions from being correctly executed.</p> <p>Let\\u2019s consider the following example. We expose an HTTP handler that performs some tasks and returns a response. But just before returning the response, we also want to send it to a Kafka topic. We don\\u2019t want to penalize the HTTP consumer latency-wise, so we want the publish action to be handled asynchronously within a new goroutine. We assume that we have at our disposal a <code>publish</code> function that accepts a context so the action of publishing a message can be interrupted if the context is canceled, for example. Here is a possible implementation:</p> <pre><code>func handler(w http.ResponseWriter, r *http.Request) {\\n    response, err := doSomeTask(r.Context(), r)\\n    if err != nil {\\n        http.Error(w, err.Error(), http.StatusInternalServerError)\\n    return\\n    }\\n    go func() {\\n        err := publish(r.Context(), response)\\n        // Do something with err\\n    }()\\n    writeResponse(response)\\n}\\n</code></pre> <p>What\\u2019s wrong with this piece of code? We have to know that the context attached to an HTTP request can cancel in different conditions:</p> <ul> <li>When the client\\u2019s connection closes</li> <li>In the case of an HTTP/2 request, when the request is canceled</li> <li>When the response has been written back to the client</li> </ul> <p>In the first two cases, we probably handle things correctly. For example, if we get a response from doSomeTask but the client has closed the connection, it\\u2019s probably OK to call publish with a context already canceled so the message isn\\u2019t published. But what about the last case?</p> <p>When the response has been written to the client, the context associated with the request will be canceled. Therefore, we are facing a race condition:</p> <ul> <li>If the response is written after the Kafka publication, we both return a response and publish a message successfully</li> <li>However, if the response is written before or during the Kafka publication, the message shouldn\\u2019t be published.</li> </ul> <p>In the latter case, calling publish will return an error because we returned the HTTP response quickly.</p> Note <p>From Go 1.21, there is a way to create a new context without cancel. <code>context.WithoutCancel</code> returns a copy of parent that is not canceled when parent is canceled.</p> <p>In summary, propagating a context should be done cautiously.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#iniciando-uma-goroutine-sem-saber-quando-interrompe-la-62\",\"title\":\"Iniciando uma goroutine sem saber quando interromp\\u00ea-la (#62)\",\"text\":\"TL;DR <p>Evitar vazamentos significa estar ciente de que sempre que uma goroutine for iniciada, voc\\u00ea deve ter um plano para interromp\\u00ea-la eventualmente.</p> <p>Goroutines are easy and cheap to start\\u2014so easy and cheap that we may not necessarily have a plan for when to stop a new goroutine, which can lead to leaks. Not knowing when to stop a goroutine is a design issue and a common concurrency mistake in Go.</p> <p>Let\\u2019s discuss a concrete example. We will design an application that needs to watch some external configuration (for example, using a database connection). Here\\u2019s a first implementation:</p> <pre><code>func main() {\\n    newWatcher()\\n    // Run the application\\n}\\n\\ntype watcher struct { /* Some resources */ }\\n\\nfunc newWatcher() {\\n    w := watcher{}\\n    go w.watch() // Creates a goroutine that watches some external configuration\\n}\\n</code></pre> <p>The problem with this code is that when the main goroutine exits (perhaps because of an OS signal or because it has a finite workload), the application is stopped. Hence, the resources created by watcher aren\\u2019t closed gracefully. How can we prevent this from happening?</p> <p>One option could be to pass to newWatcher a context that will be canceled when main returns:</p> <pre><code>func main() {\\n    ctx, cancel := context.WithCancel(context.Background())\\n    defer cancel()\\n    newWatcher(ctx)\\n    // Run the application\\n}\\n\\nfunc newWatcher(ctx context.Context) {\\n    w := watcher{}\\n    go w.watch(ctx)\\n}\\n</code></pre> <p>We propagate the context created to the watch method. When the context is canceled, the watcher struct should close its resources. However, can we guarantee that watch will have time to do so? Absolutely not\\u2014and that\\u2019s a design flaw.</p> <p>The problem is that we used signaling to convey that a goroutine had to be stopped. We didn\\u2019t block the parent goroutine until the resources had been closed.  Let\\u2019s make sure we do:</p> <pre><code>func main() {\\n    w := newWatcher()\\n    defer w.close()\\n    // Run the application\\n}\\n\\nfunc newWatcher() watcher {\\n    w := watcher{}\\n    go w.watch()\\n    return w\\n}\\n\\nfunc (w watcher) close() {\\n    // Close the resources\\n}\\n</code></pre> <p>Instead of signaling <code>watcher</code> that it\\u2019s time to close its resources, we now call this <code>close</code> method, using <code>defer</code> to guarantee that the resources are closed before the application exits.</p> <p>In summary, let\\u2019s be mindful that a goroutine is a resource like any other that must eventually be closed to free memory or other resources. Starting a goroutine without knowing when to stop it is a design issue. Whenever a goroutine is started, we should have a clear plan about when it will stop. Last but not least, if a goroutine creates resources and its lifetime is bound to the lifetime of the application, it\\u2019s probably safer to wait for this goroutine to complete before exiting the application. This way, we can ensure that the resources can be freed.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-ter-cuidado-com-goroutines-e-variaveis-de-loop-63\",\"title\":\"N\\u00e3o ter cuidado com goroutines e vari\\u00e1veis \\u200b\\u200bde loop (#63)\",\"text\":\"Warning <p>Este erro n\\u00e3o \\u00e9 mais relevante no Go 1.22 (detalhes).</p>\"},{\"location\":\"pt-br/#esperando-um-comportamento-deterministico-usando-selecao-e-canais-64\",\"title\":\"Esperando um comportamento determin\\u00edstico usando sele\\u00e7\\u00e3o e canais (#64)\",\"text\":\"TL;DR <p>Compreender que com <code>select</code> v\\u00e1rios canais escolhe o caso aleatoriamente se m\\u00faltiplas op\\u00e7\\u00f5es forem poss\\u00edveis evita fazer suposi\\u00e7\\u00f5es erradas que podem levar a erros sutis de simultaneidade.</p> <p>One common mistake made by Go developers while working with channels is to make wrong assumptions about how select behaves with multiple channels.</p> <p>For example, let's consider the following case (<code>disconnectCh</code> is a unbuffered channel):</p> <pre><code>go func() {\\n  for i := 0; i &lt; 10; i++ {\\n      messageCh &lt;- i\\n    }\\n    disconnectCh &lt;- struct{}{}\\n}()\\n\\nfor {\\n    select {\\n    case v := &lt;-messageCh:\\n        fmt.Println(v)\\n    case &lt;-disconnectCh:\\n        fmt.Println(\\\"disconnection, return\\\")\\n        return\\n    }\\n}\\n</code></pre> <p>If we run this example multiple times, the result will be random:</p> <pre><code>0\\n1\\n2\\ndisconnection, return\\n\\n0\\ndisconnection, return\\n</code></pre> <p>Instead of consuming the 10 messages, we only received a few of them. What\\u2019s the reason? It lies in the specification of the select statement with multiple channels (https:// go.dev/ref/spec):</p> <p>Quote</p> <p>If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection.</p> <p>Unlike a switch statement, where the first case with a match wins, the select statement selects randomly if multiple options are possible.</p> <p>This behavior might look odd at first, but there\\u2019s a good reason for it: to prevent possible starvation. Suppose the first possible communication chosen is based on the source order. In that case, we may fall into a situation where, for example, we only receive from one channel because of a fast sender. To prevent this, the language designers decided to use a random selection.</p> <p>When using <code>select</code> with multiple channels, we must remember that if multiple options are possible, the first case in the source order does not automatically win. Instead, Go selects randomly, so there\\u2019s no guarantee about which option will be chosen. To overcome this behavior, in the case of a single producer goroutine, we can use either unbuffered channels or a single channel.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-usar-canais-de-notificacao-65\",\"title\":\"N\\u00e3o usar canais de notifica\\u00e7\\u00e3o (#65)\",\"text\":\"TL;DR <p>Envie notifica\\u00e7\\u00f5es usando um tipo <code>chan struct{}</code>.</p> <p>Channels are a mechanism for communicating across goroutines via signaling. A signal can be either with or without data.</p> <p>Let\\u2019s look at a concrete example. We will create a channel that will notify us whenever a certain disconnection occurs. One idea is to handle it as a <code>chan bool</code>:</p> <pre><code>disconnectCh := make(chan bool)\\n</code></pre> <p>Now, let\\u2019s say we interact with an API that provides us with such a channel. Because it\\u2019s a channel of Booleans, we can receive either <code>true</code> or <code>false</code> messages. It\\u2019s probably clear what <code>true</code> conveys. But what does <code>false</code> mean? Does it mean we haven\\u2019t been disconnected? And in this case, how frequently will we receive such a signal? Does it mean we have reconnected? Should we even expect to receive <code>false</code>? Perhaps we should only expect to receive <code>true</code> messages.</p> <p>If that\\u2019s the case, meaning we don\\u2019t need a specific value to convey some information, we need a channel without data. The idiomatic way to handle it is a channel of empty structs: <code>chan struct{}</code>.</p>\"},{\"location\":\"pt-br/#nao-usar-canais-nulos-66\",\"title\":\"N\\u00e3o usar canais nulos (#66)\",\"text\":\"TL;DR <p>O uso de canais nulos deve fazer parte do seu conjunto de ferramentas de simultaneidade porque permite remover casos de instru\\u00e7\\u00f5es <code>select</code>, por exemplo.</p> <p>What should this code do?</p> <pre><code>var ch chan int\\n&lt;-ch\\n</code></pre> <p><code>ch</code> is a <code>chan int</code> type. The zero value of a channel being nil, <code>ch</code> is <code>nil</code>. The goroutine won\\u2019t panic; however, it will block forever.</p> <p>The principle is the same if we send a message to a nil channel. This goroutine blocks forever:</p> <pre><code>var ch chan int\\nch &lt;- 0\\n</code></pre> <p>Then what\\u2019s the purpose of Go allowing messages to be received from or sent to a nil channel? For example, we can use nil channels to implement an idiomatic way to merge two channels:</p> <pre><code>func merge(ch1, ch2 &lt;-chan int) &lt;-chan int {\\n    ch := make(chan int, 1)\\n\\n    go func() {\\n        for ch1 != nil || ch2 != nil { // Continue if at least one channel isn\\u2019t nil\\n            select {\\n            case v, open := &lt;-ch1:\\n                if !open {\\n                    ch1 = nil // Assign ch1 to a nil channel once closed\\n                    break\\n                }\\n                ch &lt;- v\\n            case v, open := &lt;-ch2:\\n                if !open {\\n                    ch2 = nil // Assigns ch2 to a nil channel once closed\\n                    break\\n                }\\n                ch &lt;- v\\n            }\\n        }\\n        close(ch)\\n    }()\\n\\n    return ch\\n}\\n</code></pre> <p>This elegant solution relies on nil channels to somehow remove one case from the <code>select</code> statement.</p> <p>Let\\u2019s keep this idea in mind: nil channels are useful in some conditions and should be part of the Go developer\\u2019s toolset when dealing with concurrent code.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#ficar-intrigado-com-o-tamanho-do-canal-67\",\"title\":\"Ficar intrigado com o tamanho do canal (#67)\",\"text\":\"TL;DR <p>Decida cuidadosamente o tipo de canal correto a ser usado, considerando o problema. Somente canais sem buffer oferecem fortes garantias de sincroniza\\u00e7\\u00e3o. Para canais em buffer, voc\\u00ea deve ter um bom motivo para especificar um tamanho de canal diferente de um.</p> <p>An unbuffered channel is a channel without any capacity. It can be created by either omitting the size or providing a 0 size:</p> <pre><code>ch1 := make(chan int)\\nch2 := make(chan int, 0)\\n</code></pre> <p>With an unbuffered channel (sometimes called a synchronous channel), the sender will block until the receiver receives data from the channel.</p> <p>Conversely, a buffered channel has a capacity, and it must be created with a size greater than or equal to 1:</p> <pre><code>ch3 := make(chan int, 1)\\n</code></pre> <p>With a buffered channel, a sender can send messages while the channel isn\\u2019t full. Once the channel is full, it will block until a receiver goroutine receives a message:</p> <pre><code>ch3 := make(chan int, 1)\\nch3 &lt;-1 // Non-blocking\\nch3 &lt;-2 // Blocking\\n</code></pre> <p>The first send isn\\u2019t blocking, whereas the second one is, as the channel is full at this stage.</p> <p>What's the main difference between unbuffered and buffered channels:</p> <ul> <li>An unbuffered channel enables synchronization. We have the guarantee that two goroutines will be in a known state: one receiving and another sending a message.</li> <li>A buffered channel doesn\\u2019t provide any strong synchronization. Indeed, a producer goroutine can send a message and then continue its execution if the channel isn\\u2019t full. The only guarantee is that a goroutine won\\u2019t receive a message before it is sent. But this is only a guarantee because of causality (you don\\u2019t drink your coffee before you prepare it).</li> </ul> <p>If we need a buffered channel, what size should we provide?</p> <p>The default value we should use for buffered channels is its minimum: 1. So, we may approach the problem from this standpoint: is there any good reason not to use a value of 1? Here\\u2019s a list of possible cases where we should use another size:</p> <ul> <li>While using a worker pooling-like pattern, meaning spinning a fixed number of goroutines that need to send data to a shared channel. In that case, we can tie the channel size to the number of goroutines created.</li> <li>When using channels for rate-limiting problems. For example, if we need to enforce resource utilization by bounding the number of requests, we should set up the channel size according to the limit.</li> </ul> <p>If we are outside of these cases, using a different channel size should be done cautiously. Let\\u2019s bear in mind that deciding about an accurate queue size isn\\u2019t an easy problem:</p> <p>Martin Thompson</p> <p>Queues are typically always close to full or close to empty due to the differences in pace between consumers and producers. They very rarely operate in a balanced middle ground where the rate of production and consumption is evenly matched.</p>\"},{\"location\":\"pt-br/#esquecendo-os-possiveis-efeitos-colaterais-da-formatacao-de-strings-68\",\"title\":\"Esquecendo os poss\\u00edveis efeitos colaterais da formata\\u00e7\\u00e3o de strings (#68)\",\"text\":\"TL;DR <p>Estar ciente de que a formata\\u00e7\\u00e3o de strings pode levar \\u00e0 chamada de fun\\u00e7\\u00f5es existentes significa estar atento a poss\\u00edveis impasses e outras disputas de dados.</p> <p>It\\u2019s pretty easy to forget the potential side effects of string formatting while working in a concurrent application.</p>\"},{\"location\":\"pt-br/#etcd-data-race\",\"title\":\"etcd data race\",\"text\":\"<p>github.com/etcd-io/etcd/pull/7816 shows an example of an issue where a map's key was formatted based on a mutable values from a context.</p>\"},{\"location\":\"pt-br/#deadlock\",\"title\":\"Deadlock\",\"text\":\"<p>Can you see what the problem is in this code with a <code>Customer</code> struct exposing an <code>UpdateAge</code> method and implementing the <code>fmt.Stringer</code> interface?</p> <pre><code>type Customer struct {\\n    mutex sync.RWMutex // Uses a sync.RWMutex to protect concurrent accesses\\n    id    string\\n    age   int\\n}\\n\\nfunc (c *Customer) UpdateAge(age int) error {\\n    c.mutex.Lock() // Locks and defers unlock as we update Customer\\n    defer c.mutex.Unlock()\\n\\n    if age &lt; 0 { // Returns an error if age is negative\\n        return fmt.Errorf(\\\"age should be positive for customer %v\\\", c)\\n    }\\n\\n    c.age = age\\n    return nil\\n}\\n\\nfunc (c *Customer) String() string {\\n    c.mutex.RLock() // Locks and defers unlock as we read Customer\\n    defer c.mutex.RUnlock()\\n    return fmt.Sprintf(\\\"id %s, age %d\\\", c.id, c.age)\\n}\\n</code></pre> <p>The problem here may not be straightforward. If the provided age is negative, we return an error. Because the error is formatted, using the <code>%s</code> directive on the receiver, it will call the <code>String</code> method to format <code>Customer</code>. But because <code>UpdateAge</code> already acquires the mutex lock, the <code>String</code> method won\\u2019t be able to acquire it. Hence, this leads to a deadlock situation. If all goroutines are also asleep, it leads to a panic.</p> <p>One possible solution is to restrict the scope of the mutex lock:</p> <pre><code>func (c *Customer) UpdateAge(age int) error {\\n    if age &lt; 0 {\\n        return fmt.Errorf(\\\"age should be positive for customer %v\\\", c)\\n    }\\n\\n    c.mutex.Lock() &lt;1&gt;\\n    defer c.mutex.Unlock()\\n\\n    c.age = age\\n    return nil\\n}\\n</code></pre> <p>Yet, such an approach isn't always possible. In these conditions, we have to be extremely careful with string formatting.</p> <p>Another approach is to access the <code>id</code> field directly:</p> <pre><code>func (c *Customer) UpdateAge(age int) error {\\n    c.mutex.Lock()\\n    defer c.mutex.Unlock()\\n\\n    if age &lt; 0 {\\n        return fmt.Errorf(\\\"age should be positive for customer id %s\\\", c.id)\\n    }\\n\\n    c.age = age\\n    return nil\\n}\\n</code></pre> <p>In concurrent applications, we should remain cautious about the possible side effects of string formatting.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#criando-corridas-de-dados-com-acrescimo-69\",\"title\":\"Criando corridas de dados com acr\\u00e9scimo (#69)\",\"text\":\"TL;DR <p>As chamadas <code>append</code> nem sempre s\\u00e3o isentas de disputa de dados; portanto, n\\u00e3o deve ser usado simultaneamente em uma slice compartilhada.</p> <p>Should adding an element to a slice using <code>append</code> is data-race-free? Spoiler: it depends.</p> <p>Do you believe this example has a data race? </p> <pre><code>s := make([]int, 1)\\n\\ngo func() { // In a new goroutine, appends a new element on s\\n    s1 := append(s, 1)\\n    fmt.Println(s1)\\n}()\\n\\ngo func() { // Same\\n    s2 := append(s, 1)\\n    fmt.Println(s2)\\n}()\\n</code></pre> <p>The answer is no.</p> <p>In this example, we create a slice with <code>make([]int, 1)</code>. The code creates a one-length, one-capacity slice. Thus, because the slice is full, using append in each goroutine returns a slice backed by a new array. It doesn\\u2019t mutate the existing array; hence, it doesn\\u2019t lead to a data race.</p> <p>Now, let\\u2019s run the same example with a slight change in how we initialize <code>s</code>. Instead of creating a slice with a length of 1, we create it with a length of 0 but a capacity of 1. How about this new example? Does it contain a data race?</p> <pre><code>s := make([]int, 0, 1)\\n\\ngo func() { \\n    s1 := append(s, 1)\\n    fmt.Println(s1)\\n}()\\n\\ngo func() {\\n    s2 := append(s, 1)\\n    fmt.Println(s2)\\n}()\\n</code></pre> <p>The answer is yes. We create a slice with <code>make([]int, 0, 1)</code>. Therefore, the array isn\\u2019t full. Both goroutines attempt to update the same index of the backing array (index 1), which is a data race.</p> <p>How can we prevent the data race if we want both goroutines to work on a slice containing the initial elements of <code>s</code> plus an extra element? One solution is to create a copy of <code>s</code>.</p> <p>We should remember that using append on a shared slice in concurrent applications can lead to a data race. Hence, it should be avoided.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#usando-mutexes-imprecisamente-com-slices-e-maps-70\",\"title\":\"Usando mutexes imprecisamente com slices e maps (#70)\",\"text\":\"TL;DR <p>Lembrar que slices e maps s\\u00e3o ponteiros pode evitar corridas comuns de dados.</p> <p>Let's implement a <code>Cache</code> struct used to handle caching for customer balances. This struct will contain a map of balances per customer ID and a mutex to protect concurrent accesses:</p> <pre><code>type Cache struct {\\n    mu       sync.RWMutex\\n    balances map[string]float64\\n}\\n</code></pre> <p>Next, we add an <code>AddBalance</code> method that mutates the <code>balances</code> map. The mutation is done in a critical section (within a mutex lock and a mutex unlock):</p> <pre><code>func (c *Cache) AddBalance(id string, balance float64) {\\n    c.mu.Lock()\\n    c.balances[id] = balance\\n    c.mu.Unlock()\\n}\\n</code></pre> <p>Meanwhile, we have to implement a method to calculate the average balance for all the customers. One idea is to handle a minimal critical section this way:</p> <pre><code>func (c *Cache) AverageBalance() float64 {\\n    c.mu.RLock()\\n    balances := c.balances // Creates a copy of the balances map\\n    c.mu.RUnlock()\\n\\n    sum := 0.\\n    for _, balance := range balances { // Iterates over the copy, outside of the critical section\\n        sum += balance\\n    }\\n    return sum / float64(len(balances))\\n}\\n</code></pre> <p>What's the problem with this code?</p> <p>If we run a test using the <code>-race</code> flag with two concurrent goroutines, one calling <code>AddBalance</code> (hence mutating balances) and another calling <code>AverageBalance</code>, a data race occurs. What\\u2019s the problem here?</p> <p>Internally, a map is a <code>runtime.hmap</code> struct containing mostly metadata (for example, a counter) and a pointer referencing data buckets. So, <code>balances := c.balances</code> doesn\\u2019t copy the actual data. Therefore, the two goroutines perform operations on the same data set, and one mutates it. Hence, it's a data race.</p> <p>One possible solution is to protect the whole <code>AverageBalance</code> function:</p> <pre><code>func (c *Cache) AverageBalance() float64 {\\n    c.mu.RLock()\\n    defer c.mu.RUnlock() // Unlocks when the function returns\\n\\n    sum := 0.\\n    for _, balance := range c.balances {\\n        sum += balance\\n    }\\n    return sum / float64(len(c.balances))\\n}\\n</code></pre> <p>Another option, if the iteration operation isn\\u2019t lightweight, is to work on an actual copy of the data and protect only the copy:</p> <pre><code>func (c *Cache) AverageBalance() float64 {\\n    c.mu.RLock()\\n    m := make(map[string]float64, len(c.balances)) // Copies the map\\n    for k, v := range c.balances {\\n        m[k] = v\\n    }\\n    c.mu.RUnlock()\\n\\n    sum := 0.\\n    for _, balance := range m {\\n        sum += balance\\n    }\\n    return sum / float64(len(m))\\n}\\n</code></pre> <p>Once we have made a deep copy, we release the mutex. The iterations are done on the copy outside of the critical section.</p> <p>In summary, we have to be careful with the boundaries of a mutex lock. In this section, we have seen why assigning an existing map (or an existing slice) to a map isn\\u2019t enough to protect against data races. The new variable, whether a map or a slice, is backed by the same data set. There are two leading solutions to prevent this: protect the whole function, or work on a copy of the actual data. In all cases, let\\u2019s be cautious when designing critical sections and make sure the boundaries are accurately defined.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#uso-indevido-syncwaitgroup-71\",\"title\":\"Uso indevido <code>sync.WaitGroup</code> (#71)\",\"text\":\"TL;DR <p>Para usar com precis\\u00e3o <code>sync.WaitGroup</code>, chame o m\\u00e9todo <code>Add</code> antes de ativar goroutines.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#esquecendo-synccond-72\",\"title\":\"Esquecendo <code>sync.Cond</code> (#72)\",\"text\":\"TL;DR <p>Voc\\u00ea pode enviar notifica\\u00e7\\u00f5es repetidas para v\\u00e1rios goroutines com <code>sync.Cond</code>.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-usando-errgroup-73\",\"title\":\"N\\u00e3o usando <code>errgroup</code> (#73)\",\"text\":\"TL;DR <p>Voc\\u00ea pode sincronizar um grupo de goroutines e lidar com erros e contextos com o pacote <code>errgroup</code>.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#copiando-um-tipo-sync-74\",\"title\":\"Copiando um tipo <code>sync</code> (#74)\",\"text\":\"TL;DR <p>Tipos <code>sync</code> n\\u00e3o devem ser copiados.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#standard-library\",\"title\":\"Standard Library\",\"text\":\"\"},{\"location\":\"pt-br/#fornecendo-uma-duracao-de-tempo-errada-75\",\"title\":\"Fornecendo uma dura\\u00e7\\u00e3o de tempo errada (#75)\",\"text\":\"TL;DR <p>Seja cauteloso com fun\\u00e7\\u00f5es que aceitam um arquivo <code>time.Duration</code>. Mesmo que a passagem de um n\\u00famero inteiro seja permitida, tente usar a API time para evitar qualquer poss\\u00edvel confus\\u00e3o.</p> <p>Many common functions in the standard library accept a <code>time.Duration</code>, which is an alias for the <code>int64</code> type. However, one <code>time.Duration</code> unit represents one nanosecond, instead of one millisecond, as commonly seen in other programming languages. As a result, passing numeric types instead of using the <code>time.Duration</code> API can lead to unexpected behavior.</p> <p>A developer with experience in other languages might assume that the following code creates a new <code>time.Ticker</code> that delivers ticks every second, given the value <code>1000</code>:</p> <pre><code>ticker := time.NewTicker(1000)\\nfor {\\n    select {\\n    case &lt;-ticker.C:\\n        // Do something\\n    }\\n}\\n</code></pre> <p>However, because 1,000 <code>time.Duration</code> units = 1,000 nanoseconds, ticks are delivered every 1,000 nanoseconds = 1 microsecond, not every second as assumed.</p> <p>We should always use the <code>time.Duration</code> API to avoid confusion and unexpected behavior: </p><pre><code>ticker = time.NewTicker(time.Microsecond)\\n// Or\\nticker = time.NewTicker(1000 * time.Nanosecond)\\n</code></pre><p></p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#timeafter-e-vazamentos-de-memoria-76\",\"title\":\"<code>time.After</code> e vazamentos de mem\\u00f3ria (#76)\",\"text\":\"TL;DR <p>Evitar chamadas para fun\\u00e7\\u00f5es <code>time.After</code> repetidas (como loops ou manipuladores HTTP) pode evitar pico de consumo de mem\\u00f3ria. Os recursos criados por <code>time.After</code> s\\u00e3o liberados somente quando o cron\\u00f4metro expira.</p> <p>Developers often use <code>time.After</code> in loops or HTTP handlers repeatedly to implement the timing function. But it can lead to unintended peak memory consumption due to the delayed release of resources, just like the following code:</p> <pre><code>func consumer(ch &lt;-chan Event) {\\n    for {\\n        select {\\n        case event := &lt;-ch:\\n            handle(event)\\n        case &lt;-time.After(time.Hour):\\n            log.Println(\\\"warning: no messages received\\\")\\n        }\\n    }\\n}\\n</code></pre> <p>The source code of the function time.After is as follows:</p> <pre><code>func After(d Duration) &lt;-chan Time {\\n    return NewTimer(d).C\\n}\\n</code></pre> <p>As we see, it returns receive-only channel.</p> <p>When <code>time.After</code> is used in a loop or repeated context, a new channel is created in each iteration. If these channels are not properly closed or if their associated timers are not stopped, they can accumulate and consume memory. The resources associated with each timer and channel are only released when the timer expires or the channel is closed.</p> <p>To avoid this happening, We can use context's timeout setting instead of <code>time.After</code>, like below:</p> <pre><code>func consumer(ch &lt;-chan Event) {\\n    for {\\n        ctx, cancel := context.WithTimeout(context.Background(), time.Hour)\\n        select {\\n        case event := &lt;-ch:\\n            cancel()\\n            handle(event)\\n        case &lt;-ctx.Done():\\n            log.Println(\\\"warning: no messages received\\\")\\n        }\\n    }\\n}\\n</code></pre> <p>We can also use <code>time.NewTimer</code> like so:</p> <pre><code>func consumer(ch &lt;-chan Event) {\\n    timerDuration := 1 * time.Hour\\n    timer := time.NewTimer(timerDuration)\\n\\n    for {\\n        timer.Reset(timerDuration)\\n        select {\\n        case event := &lt;-ch:\\n            handle(event)\\n        case &lt;-timer.C:\\n            log.Println(\\\"warning: no messages received\\\")\\n        }\\n    }\\n}\\n</code></pre> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#lidando-com-erros-comuns-json-77\",\"title\":\"Lidando com erros comuns JSON (#77)\",\"text\":\"<ul> <li>Comportamento inesperado devido \\u00e0 incorpora\\u00e7\\u00e3o de tipo</li> </ul> <p>Tenha cuidado ao usar campos incorporados em estruturas Go. Fazer isso pode levar a bugs sorrateiros, como um campo time.Time incorporado que implementa a interface <code>json.Marshaler</code>, substituindo assim o comportamento de empacotamento padr\\u00e3o.</p> <p> C\\u00f3digo fonte</p> <ul> <li>JSON e o rel\\u00f3gio monot\\u00f4nico</li> </ul> <p>Ao comparar duas estruturas <code>time.Time</code>, lembre-se de que <code>time.Time</code> cont\\u00e9m um rel\\u00f3gio de parede e um rel\\u00f3gio monot\\u00f4nico, e a compara\\u00e7\\u00e3o usando o operador == \\u00e9 feita em ambos os rel\\u00f3gios.</p> <p> C\\u00f3digo fonte</p> <ul> <li>Map de <code>any</code></li> </ul> <p>Para evitar suposi\\u00e7\\u00f5es erradas ao fornecer um map ao desempacotar (unmarshaling) dados JSON, lembre-se de que os valores num\\u00e9ricos s\\u00e3o convertidos para <code>float64</code> por padr\\u00e3o.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#erros-comuns-de-sql-78\",\"title\":\"Erros comuns de SQL (#78)\",\"text\":\"<ul> <li>Esquecer <code>sql.Open</code> n\\u00e3o necessariamente estabelece conex\\u00f5es com um banco de dados</li> </ul> <p>Esquecer <code>sql.Open</code> n\\u00e3o necessariamente estabelece conex\\u00f5es com um banco de dados   Chame o m\\u00e9todo <code>Ping</code> ou <code>PingContext</code> se precisar testar sua configura\\u00e7\\u00e3o e garantir que um banco de dados esteja acess\\u00edvel.</p> <p> C\\u00f3digo fonte</p> <ul> <li>Esquecendo o pool de conex\\u00f5es</li> </ul> <p>Configure os par\\u00e2metros de conex\\u00e3o do banco de dados para aplicativos de n\\u00edvel de produ\\u00e7\\u00e3o.</p> <ul> <li>N\\u00e3o usar declara\\u00e7\\u00f5es preparadas</li> </ul> <p>O uso de instru\\u00e7\\u00f5es preparadas em SQL torna as consultas mais eficientes e seguras.</p> <p> C\\u00f3digo fonte</p> <ul> <li>Tratamento incorreto de valores nulos</li> </ul> <p>Lide com colunas anul\\u00e1veis \\u200b\\u200bem tabelas usando ponteiros ou tipos <code>sql.NullXXX</code>.</p> <p> C\\u00f3digo fonte</p> <ul> <li>N\\u00e3o tratando de erros de itera\\u00e7\\u00e3o de linhas</li> </ul> <p>Chame o m\\u00e9todo <code>Err</code> de <code>sql.Rows</code> itera\\u00e7\\u00f5es posteriores \\u00e0 linha para garantir que voc\\u00ea n\\u00e3o perdeu nenhum erro ao preparar a pr\\u00f3xima linha.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-fechando-recursos-transitorios-body-http-sqlrows-e-osfile-79\",\"title\":\"N\\u00e3o fechando recursos transit\\u00f3rios (body HTTP, <code>sql.Rows</code> e <code>os.File</code>) (#79)\",\"text\":\"TL;DR <p>Eventualmente feche todas as estruturas implementadas <code>io.Closer</code> para evitar poss\\u00edveis vazamentos.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#esquecendo-a-instrucao-return-apos-responder-a-uma-solicitacao-http-80\",\"title\":\"Esquecendo a instru\\u00e7\\u00e3o return ap\\u00f3s responder a uma solicita\\u00e7\\u00e3o HTTP (#80)\",\"text\":\"TL;DR <p>Para evitar comportamentos inesperados nas implementa\\u00e7\\u00f5es do manipulador HTTP, certifique-se de n\\u00e3o perder a instru\\u00e7\\u00e3o <code>return</code> se quiser que um manipulador pare ap\\u00f3s <code>http.Error</code>.</p> <p>Consider the following HTTP handler that handles an error from <code>foo</code> using <code>http.Error</code>:</p> <pre><code>func handler(w http.ResponseWriter, req *http.Request) {\\n    err := foo(req)\\n    if err != nil {\\n        http.Error(w, \\\"foo\\\", http.StatusInternalServerError)\\n    }\\n\\n    _, _ = w.Write([]byte(\\\"all good\\\"))\\n    w.WriteHeader(http.StatusCreated)\\n}\\n</code></pre> <p>If we run this code and <code>err != nil</code>, the HTTP response would be:</p> <pre><code>foo\\nall good\\n</code></pre> <p>The response contains both the error and success messages, and also the first HTTP status code, 500. There would also be a warning log indicating that we attempted to write the status code multiple times:</p> <pre><code>2023/10/10 16:45:33 http: superfluous response.WriteHeader call from main.handler (main.go:20)\\n</code></pre> <p>The mistake in this code is that <code>http.Error</code> does not stop the handler's execution, which means the success message and status code get written in addition to the error. Beyond an incorrect response, failing to return after writing an error can lead to the unwanted execution of code and unexpected side-effects. The following code adds the <code>return</code> statement following the <code>http.Error</code> and exhibits the desired behavior when ran:</p> <pre><code>func handler(w http.ResponseWriter, req *http.Request) {\\n    err := foo(req)\\n    if err != nil {\\n        http.Error(w, \\\"foo\\\", http.StatusInternalServerError)\\n        return // Adds the return statement\\n    }\\n\\n    _, _ = w.Write([]byte(\\\"all good\\\"))\\n    w.WriteHeader(http.StatusCreated)\\n}\\n</code></pre> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#usando-o-cliente-e-servidor-http-padrao-81\",\"title\":\"Usando o cliente e servidor HTTP padr\\u00e3o (#81)\",\"text\":\"TL;DR <p>Para aplicativos de n\\u00edvel de produ\\u00e7\\u00e3o, n\\u00e3o use as implementa\\u00e7\\u00f5es de cliente e servidor HTTP padr\\u00e3o. Essas implementa\\u00e7\\u00f5es n\\u00e3o possuem tempos limite e comportamentos que deveriam ser obrigat\\u00f3rios na produ\\u00e7\\u00e3o.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#teste\",\"title\":\"Teste\",\"text\":\"\"},{\"location\":\"pt-br/#nao-categorizar-testes-tags-de-construcao-variaveis-de-ambiente-e-modo-abreviado-82\",\"title\":\"N\\u00e3o categorizar testes (tags de constru\\u00e7\\u00e3o, vari\\u00e1veis \\u200b\\u200bde ambiente e modo abreviado) (#82)\",\"text\":\"TL;DR <p>Categorizar testes usando sinalizadores de constru\\u00e7\\u00e3o, vari\\u00e1veis \\u200b\\u200bde ambiente ou modo curto torna o processo de teste mais eficiente. Voc\\u00ea pode criar categorias de teste usando sinalizadores de constru\\u00e7\\u00e3o ou vari\\u00e1veis \\u200b\\u200bde ambiente (por exemplo, testes de unidade versus testes de integra\\u00e7\\u00e3o) e diferenciar testes curtos de testes de longa dura\\u00e7\\u00e3o para decidir quais tipos de testes executar.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-habilitando-a-bandeira-de-corrida-83\",\"title\":\"N\\u00e3o habilitando a bandeira de corrida (#83)\",\"text\":\"TL;DR <p>A ativa\\u00e7\\u00e3o do sinalizador <code>-race</code> \\u00e9 altamente recomendada ao escrever aplicativos simult\\u00e2neos. Isso permite que voc\\u00ea detecte poss\\u00edveis corridas de dados que podem levar a bugs de software.</p> <p>In Go, the race detector isn\\u2019t a static analysis tool used during compilation; instead, it\\u2019s a tool to find data races that occur at runtime. To enable it, we have to enable the -race flag while compiling or running a test. For example:</p> <pre><code>go test -race ./...\\n</code></pre> <p>Once the race detector is enabled, the compiler instruments the code to detect data races. Instrumentation refers to a compiler adding extra instructions: here, tracking all memory accesses and recording when and how they occur.</p> <p>Enabling the race detector adds an overhead in terms of memory and execution time; hence, it's generally recommended to enable it only during local testing or continuous integration, not production.</p> <p>If a race is detected, Go raises a warning. For example:</p> <pre><code>package main\\n\\nimport (\\n    \\\"fmt\\\"\\n)\\n\\nfunc main() {\\n    i := 0\\n    go func() { i++ }()\\n    fmt.Println(i)\\n}\\n</code></pre> <p>Runnig this code with the <code>-race</code> logs the following warning:</p> <pre><code>==================\\nWARNING: DATA RACE\\nWrite at 0x00c000026078 by goroutine 7: # (1)\\n  main.main.func1()\\n      /tmp/app/main.go:9 +0x4e\\n\\nPrevious read at 0x00c000026078 by main goroutine: # (2)\\n  main.main()\\n      /tmp/app/main.go:10 +0x88\\n\\nGoroutine 7 (running) created at: # (3)\\n  main.main()\\n      /tmp/app/main.go:9 +0x7a\\n==================\\n</code></pre> <ol> <li>Indicates that goroutine 7 was writing</li> <li>Indicates that the main goroutine was reading</li> <li>Indicates when the goroutine 7 was created</li> </ol> <p>Let\\u2019s make sure we are comfortable reading these messages. Go always logs the following:</p> <ul> <li>The concurrent goroutines that are incriminated: here, the main goroutine and goroutine 7.</li> <li>Where accesses occur in the code: in this case, lines 9 and 10.</li> <li>When these goroutines were created: goroutine 7 was created in main().</li> </ul> <p>In addition, if a specific file contains tests that lead to data races, we can exclude it  from race detection using the <code>!race</code> build tag:</p> <pre><code>//go:build !race\\n\\npackage main\\n\\nimport (\\n    \\\"testing\\\"\\n)\\n\\nfunc TestFoo(t *testing.T) {\\n    // ...\\n}\\n</code></pre>\"},{\"location\":\"pt-br/#nao-usar-modos-de-execucao-de-teste-paralelo-e-aleatorio-84\",\"title\":\"N\\u00e3o usar modos de execu\\u00e7\\u00e3o de teste (paralelo e aleat\\u00f3rio) (#84)\",\"text\":\"TL;DR <p>Usar o sinalizador <code>-parallel</code> \\u00e9 uma forma eficiente de acelerar testes, especialmente os de longa dura\\u00e7\\u00e3o. Use o sinalizador <code>-shuffle</code> para ajudar a garantir que um conjunto de testes n\\u00e3o se baseie em suposi\\u00e7\\u00f5es erradas que possam ocultar bugs.</p>\"},{\"location\":\"pt-br/#nao-usar-testes-baseados-em-tabela-85\",\"title\":\"N\\u00e3o usar testes baseados em tabela (#85)\",\"text\":\"TL;DR <p>Os testes baseados em tabelas s\\u00e3o uma maneira eficiente de agrupar um conjunto de testes semelhantes para evitar a duplica\\u00e7\\u00e3o de c\\u00f3digo e facilitar o manuseio de atualiza\\u00e7\\u00f5es futuras.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#dormindo-em-testes-unitarios-86\",\"title\":\"Dormindo em testes unit\\u00e1rios (#86)\",\"text\":\"TL;DR <p>Evite interrup\\u00e7\\u00f5es usando a sincroniza\\u00e7\\u00e3o para tornar o teste menos inst\\u00e1vel e mais robusto. Se a sincroniza\\u00e7\\u00e3o n\\u00e3o for poss\\u00edvel, considere uma abordagem de nova tentativa.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-lidar-com-a-api-de-tempo-de-forma-eficiente-87\",\"title\":\"N\\u00e3o lidar com a API de tempo de forma eficiente (#87)\",\"text\":\"TL;DR <p>Entender como lidar com fun\\u00e7\\u00f5es usando a API time \\u00e9 outra maneira de tornar um teste menos complicado. Voc\\u00ea pode usar t\\u00e9cnicas padr\\u00e3o, como lidar com o tempo como parte de uma depend\\u00eancia oculta ou solicitar que os clientes o forne\\u00e7am.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-usar-pacotes-de-utilitarios-de-teste-httptest-e-iotest-88\",\"title\":\"N\\u00e3o usar pacotes de utilit\\u00e1rios de teste ( <code>httptest</code> e <code>iotest</code>) (#88)\",\"text\":\"<ul> <li>O pacote <code>httptest</code> \\u00e9 \\u00fatil para lidar com aplicativos HTTP. Ele fornece um conjunto de utilit\\u00e1rios para testar clientes e servidores.</li> </ul> <p> C\\u00f3digo fonte</p> <ul> <li>O pacote <code>iotest</code> ajuda a escrever io.Reader e testar se um aplicativo \\u00e9 tolerante a erros.</li> </ul> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#escrevendo-benchmarks-imprecisos-89\",\"title\":\"Escrevendo benchmarks imprecisos (#89)\",\"text\":\"TL;DR <p>Regarding benchmarks:</p> <ul> <li>Use m\\u00e9todos de tempo para preservar a precis\\u00e3o de um benchmark.</li> <li>Aumentar o tempo de teste ou usar ferramentas como o benchstat pode ser \\u00fatil ao lidar com micro-benchmarks.</li> <li>Tenha cuidado com os resultados de um micro-benchmark se o sistema que executa o aplicativo for diferente daquele que executa o micro-benchmark.</li> <li>Certifique-se de que a fun\\u00e7\\u00e3o em teste cause um efeito colateral, para evitar que as otimiza\\u00e7\\u00f5es do compilador enganem voc\\u00ea sobre os resultados do benchmark.</li> <li>Para evitar o efeito observador, force um benchmark a recriar os dados usados \\u200b\\u200bpor uma fun\\u00e7\\u00e3o vinculada \\u00e0 CPU.</li> </ul> <p>Leia a se\\u00e7\\u00e3o completa aqui.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-explorando-todos-os-recursos-de-teste-do-go-90\",\"title\":\"N\\u00e3o explorando todos os recursos de teste do Go (#90)\",\"text\":\"<ul> <li>Cobertura de c\\u00f3digo</li> </ul> <p>Use a cobertura de c\\u00f3digo com o sinalizador <code>-coverprofile</code> para ver rapidamente qual parte do c\\u00f3digo precisa de mais aten\\u00e7\\u00e3o.</p> <ul> <li>Testando de um pacote diferente</li> </ul> <p>Coloque os testes unit\\u00e1rios em um pacote diferente para impor testes de escrita que se concentrem em um comportamento exposto, n\\u00e3o em internos.</p> <p> C\\u00f3digo fonte</p> <ul> <li>Fun\\u00e7\\u00f5es utilit\\u00e1rias</li> </ul> <p>O tratamento de erros usando a vari\\u00e1vel <code>*testing.T</code> em vez do cl\\u00e1ssico <code>if err != nil</code> torna o c\\u00f3digo mais curto e f\\u00e1cil de ler.</p> <p> C\\u00f3digo fonte</p> <ul> <li>Configura\\u00e7\\u00e3o e desmontagem</li> </ul> <p>Voc\\u00ea pode usar fun\\u00e7\\u00f5es de setup e teardown para configurar um ambiente complexo, como no caso de testes de integra\\u00e7\\u00e3o.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-usar-fuzzing-erro-da-comunidade\",\"title\":\"N\\u00e3o usar fuzzing (erro da comunidade)\",\"text\":\"TL;DR <p>Fuzzing \\u00e9 uma estrat\\u00e9gia eficiente para detectar entradas aleat\\u00f3rias, inesperadas ou malformadas em fun\\u00e7\\u00f5es e m\\u00e9todos complexos, a fim de descobrir vulnerabilidades, bugs ou at\\u00e9 mesmo travamentos potenciais.</p> <p>Credits: @jeromedoucet</p>\"},{\"location\":\"pt-br/#otimizacoes\",\"title\":\"Otimiza\\u00e7\\u00f5es\",\"text\":\"\"},{\"location\":\"pt-br/#nao-entendendo-os-caches-da-cpu-91\",\"title\":\"N\\u00e3o entendendo os caches da CPU (#91)\",\"text\":\"<ul> <li>Arquitetura da CPU</li> </ul> <p>Compreender como usar caches de CPU \\u00e9 importante para otimizar aplicativos vinculados \\u00e0 CPU porque o cache L1 \\u00e9 cerca de 50 a 100 vezes mais r\\u00e1pido que a mem\\u00f3ria principal.</p> <ul> <li>Linha de cache</li> </ul> <p>Estar consciente do conceito de linha de cache \\u00e9 fundamental para entender como organizar dados em aplicativos com uso intensivo de dados. Uma CPU n\\u00e3o busca mem\\u00f3ria palavra por palavra; em vez disso, geralmente copia um bloco de mem\\u00f3ria para uma linha de cache de 64 bytes. Para aproveitar ao m\\u00e1ximo cada linha de cache individual, imponha a localidade espacial.</p> <p> C\\u00f3digo fonte</p> <ul> <li>Slice de estruturas vs. estrutura de slices</li> </ul> <p> C\\u00f3digo fonte</p> <ul> <li>Previsibilidade</li> </ul> <p>Tornar o c\\u00f3digo previs\\u00edvel para a CPU tamb\\u00e9m pode ser uma forma eficiente de otimizar certas fun\\u00e7\\u00f5es. Por exemplo, uma passada unit\\u00e1ria ou constante \\u00e9 previs\\u00edvel para a CPU, mas uma passada n\\u00e3o unit\\u00e1ria (por exemplo, uma lista vinculada) n\\u00e3o \\u00e9 previs\\u00edvel.</p> <p> C\\u00f3digo fonte</p> <ul> <li>Pol\\u00edtica de posicionamento de cache</li> </ul> <p>Para evitar um avan\\u00e7o cr\\u00edtico e, portanto, utilizar apenas uma pequena parte do cache, esteja ciente de que os caches s\\u00e3o particionados.</p>\"},{\"location\":\"pt-br/#escrevendo-codigo-simultaneo-que-leva-a-compartilhamento-falso-92\",\"title\":\"Escrevendo c\\u00f3digo simult\\u00e2neo que leva a compartilhamento falso (#92)\",\"text\":\"TL;DR <p>Saber que n\\u00edveis mais baixos de caches de CPU n\\u00e3o s\\u00e3o compartilhados entre todos os n\\u00facleos ajuda a evitar padr\\u00f5es que degradam o desempenho, como compartilhamento falso ao escrever c\\u00f3digo de simultaneidade. Compartilhar mem\\u00f3ria \\u00e9 uma ilus\\u00e3o.</p> <p>Leia a se\\u00e7\\u00e3o completa aqui.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-levando-em-consideracao-o-paralelismo-no-nivel-de-instrucao-93\",\"title\":\"N\\u00e3o levando em considera\\u00e7\\u00e3o o paralelismo no n\\u00edvel de instru\\u00e7\\u00e3o (#93)\",\"text\":\"TL;DR <p>Use o ILP para otimizar partes espec\\u00edficas do seu c\\u00f3digo para permitir que uma CPU execute tantas instru\\u00e7\\u00f5es paralelas quanto poss\\u00edvel. Identificar perigos nos dados \\u00e9 uma das etapas principais.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-estar-ciente-do-alinhamento-dos-dados-94\",\"title\":\"N\\u00e3o estar ciente do alinhamento dos dados (#94)\",\"text\":\"TL;DR <p>Voc\\u00ea pode evitar erros comuns lembrando que no Go os tipos b\\u00e1sicos s\\u00e3o alinhados com seu pr\\u00f3prio tamanho. Por exemplo, tenha em mente que reorganizar os campos de uma estrutura por tamanho em ordem decrescente pode levar a estruturas mais compactas (menos aloca\\u00e7\\u00e3o de mem\\u00f3ria e potencialmente uma melhor localidade espacial).</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-entendendo-stack-vs-heap-95\",\"title\":\"N\\u00e3o entendendo stack vs. heap (#95)\",\"text\":\"TL;DR <p>Compreender as diferen\\u00e7as fundamentais entre heap e pilha tamb\\u00e9m deve fazer parte do seu conhecimento b\\u00e1sico ao otimizar um aplicativo Go. As aloca\\u00e7\\u00f5es de pilha s\\u00e3o quase gratuitas, enquanto as aloca\\u00e7\\u00f5es de heap s\\u00e3o mais lentas e dependem do GC para limpar a mem\\u00f3ria.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-saber-como-reduzir-alocacoes-mudanca-de-api-otimizacoes-de-compilador-e-syncpool-96\",\"title\":\"N\\u00e3o saber como reduzir aloca\\u00e7\\u00f5es (mudan\\u00e7a de API, otimiza\\u00e7\\u00f5es de compilador e <code>sync.Pool</code>) (#96)\",\"text\":\"TL;DR <p>A redu\\u00e7\\u00e3o das aloca\\u00e7\\u00f5es tamb\\u00e9m \\u00e9 um aspecto essencial da otimiza\\u00e7\\u00e3o de um aplicativo Go. Isso pode ser feito de diferentes maneiras, como projetar a API cuidadosamente para evitar compartilhamento, compreender as otimiza\\u00e7\\u00f5es comuns do compilador Go e usar <code>sync.Pool</code>.</p> <p> C\\u00f3digo fonte</p>\"},{\"location\":\"pt-br/#nao-dependendo-do-inlining-97\",\"title\":\"N\\u00e3o dependendo do inlining (#97)\",\"text\":\"TL;DR <p>Use a t\\u00e9cnica de inlining de caminho r\\u00e1pido para reduzir com efici\\u00eancia o tempo amortizado para chamar uma fun\\u00e7\\u00e3o.</p>\"},{\"location\":\"pt-br/#nao-usar-ferramentas-de-diagnostico-go-98\",\"title\":\"N\\u00e3o usar ferramentas de diagn\\u00f3stico Go (#98)\",\"text\":\"TL;DR <p>Confie na cria\\u00e7\\u00e3o de perfil e no rastreador de execu\\u00e7\\u00e3o para entender o desempenho de um aplicativo e as partes a serem otimizadas.</p> <p>Leia a se\\u00e7\\u00e3o completa aqui.</p>\"},{\"location\":\"pt-br/#nao-entendendo-como-funciona-o-gc-99\",\"title\":\"N\\u00e3o entendendo como funciona o GC (#99)\",\"text\":\"TL;DR <p>Compreender como ajustar o GC pode levar a v\\u00e1rios benef\\u00edcios, como lidar com aumentos repentinos de carga com mais efici\\u00eancia.</p>\"},{\"location\":\"pt-br/#nao-entendendo-os-impactos-da-execucao-do-go-no-docker-e-kubernetes-100\",\"title\":\"N\\u00e3o entendendo os impactos da execu\\u00e7\\u00e3o do Go no Docker e Kubernetes (#100)\",\"text\":\"TL;DR <p>Para ajudar a evitar a limita\\u00e7\\u00e3o da CPU quando implantado no Docker e no Kubernetes, lembre-se de que Go n\\u00e3o reconhece CFS.</p> <p>By default, GOMAXPROCS is set to the number of OS-apparent logical CPU cores.</p> <p>When running some Go code inside Docker and Kubernetes, we must know that Go isn't CFS-aware (github.com/golang/go/issues/33803). Therefore, GOMAXPROCS isn't automatically set to the value of <code>spec.containers.resources.limits.cpu</code> (see Kubernetes Resource Management for Pods and Containers); instead, it's set to the number of logical cores on the host machine. The main implication is that it can lead to an increased tail latency in some specific situations.</p> <p>One solution is to rely on uber-go/automaxprocs that automatically set <code>GOMAXPROCS</code> to match the Linux container CPU quota.</p>\"},{\"location\":\"pt-br/#community\",\"title\":\"Community\",\"text\":\"<p>Thanks to all the contributors:</p> <p> </p>\"},{\"location\":\"zh/\",\"title\":\"Chinese (Simplified) Version\",\"text\":\"\"},{\"location\":\"zh/#100-go\",\"title\":\"100 \\u4e2a Go \\u5e38\\u89c1\\u9519\\u8bef\\u53ca\\u5982\\u4f55\\u907f\\u514d\",\"text\":\"The Coder Cafe <p>\\u5982\\u679c\\u60a8\\u559c\\u6b22\\u6211\\u7684\\u4e66\\uff0c\\u60a8\\u53ef\\u80fd\\u4f1a\\u5bf9\\u6211\\u7684\\u6700\\u65b0\\u9879\\u76ee\\u611f\\u5174\\u8da3\\uff1aThe Coder Cafe\\uff0c\\u8fd9\\u662f\\u4e00\\u4e2a\\u4e3a\\u7a0b\\u5e8f\\u5458\\u63d0\\u4f9b\\u7684\\u6bcf\\u65e5\\u7b80\\u62a5\\u3002</p> <p>Feeling overwhelmed by the endless stream of tech content? At The Coder Cafe, we serve one essential concept for coders. Written by a senior software engineer at Google, it's perfectly brewed for your morning coffee, helping you grow your skills deeply.</p> <p></p><p></p> <p></p>\"},{\"location\":\"zh/#_1\",\"title\":\"\\u4ee3\\u7801\\u53ca\\u5de5\\u7a0b\\u7ec4\\u7ec7\",\"text\":\"\"},{\"location\":\"zh/#1\",\"title\":\"\\u610f\\u5916\\u7684\\u53d8\\u91cf\\u9690\\u85cf (#1)\",\"text\":\"<p>\\u907f\\u514d\\u53d8\\u91cf\\u9690\\u85cf\\uff08\\u5916\\u90e8\\u4f5c\\u7528\\u57df\\u53d8\\u91cf\\u88ab\\u5185\\u90e8\\u4f5c\\u7528\\u57df\\u540c\\u540d\\u53d8\\u91cf\\u9690\\u85cf\\uff09\\uff0c\\u6709\\u52a9\\u4e8e\\u907f\\u514d\\u53d8\\u91cf\\u5f15\\u7528\\u9519\\u8bef\\uff0c\\u6709\\u52a9\\u4e8e\\u4ed6\\u4eba\\u9605\\u8bfb\\u7406\\u89e3\\u3002</p>\"},{\"location\":\"zh/#2\",\"title\":\"\\u4e0d\\u5fc5\\u8981\\u7684\\u4ee3\\u7801\\u5d4c\\u5957 (#2)\",\"text\":\"<p>\\u907f\\u514d\\u4e0d\\u5fc5\\u8981\\u7684\\u3001\\u8fc7\\u591a\\u7684\\u5d4c\\u5957\\u5c42\\u6b21\\uff0c\\u5e76\\u4e14\\u8ba9\\u6b63\\u5e38\\u4ee3\\u7801\\u8def\\u5f84\\u5c3d\\u91cf\\u5de6\\u5bf9\\u9f50\\uff08\\u800c\\u4e0d\\u662f\\u653e\\u5728\\u5206\\u652f\\u8def\\u5f84\\u4e2d\\uff09\\uff0c\\u6709\\u52a9\\u4e8e\\u6784\\u5efa\\u53ef\\u8bfb\\u6027\\u66f4\\u597d\\u7684\\u4ee3\\u7801\\u3002</p>\"},{\"location\":\"zh/#init-3\",\"title\":\"\\u8bef\\u7528 init \\u51fd\\u6570 (#3)\",\"text\":\"<p>\\u521d\\u59cb\\u5316\\u53d8\\u91cf\\u65f6\\uff0c\\u8bf7\\u8bb0\\u4f4f init \\u51fd\\u6570\\u5177\\u6709\\u6709\\u9650\\u7684\\u9519\\u8bef\\u5904\\u7406\\u80fd\\u529b\\uff0c\\u5e76\\u4e14\\u4f1a\\u4f7f\\u72b6\\u6001\\u5904\\u7406\\u548c\\u6d4b\\u8bd5\\u53d8\\u5f97\\u66f4\\u52a0\\u590d\\u6742\\u3002\\u5728\\u5927\\u591a\\u6570\\u60c5\\u51b5\\u4e0b\\uff0c\\u521d\\u59cb\\u5316\\u5e94\\u8be5\\u4f5c\\u4e3a\\u7279\\u5b9a\\u51fd\\u6570\\u6765\\u5904\\u7406\\u3002</p>\"},{\"location\":\"zh/#getterssetters-4\",\"title\":\"\\u6ee5\\u7528 getters/setters (#4)\",\"text\":\"<p>\\u5728 Go \\u8bed\\u8a00\\u4e2d\\uff0c\\u5f3a\\u5236\\u4f7f\\u7528 getter \\u548c setter \\u65b9\\u6cd5\\u5e76\\u4e0d\\u7b26\\u5408 Go \\u60ef\\u4f8b\\u3002\\u5728\\u5b9e\\u8df5\\u4e2d\\uff0c\\u5e94\\u8be5\\u627e\\u5230\\u6548\\u7387\\u548c\\u76f2\\u76ee\\u9075\\u5faa\\u67d0\\u4e9b\\u60ef\\u7528\\u6cd5\\u4e4b\\u95f4\\u7684\\u5e73\\u8861\\u70b9\\u3002</p>\"},{\"location\":\"zh/#5\",\"title\":\"\\u63a5\\u53e3\\u6c61\\u67d3 (#5)\",\"text\":\"<p>\\u62bd\\u8c61\\u5e94\\u8be5\\u88ab\\u53d1\\u73b0\\uff0c\\u800c\\u4e0d\\u662f\\u88ab\\u521b\\u9020\\u3002\\u4e3a\\u4e86\\u907f\\u514d\\u4e0d\\u5fc5\\u8981\\u7684\\u590d\\u6742\\u6027\\uff0c\\u9700\\u8981\\u65f6\\u624d\\u521b\\u5efa\\u63a5\\u53e3\\uff0c\\u800c\\u4e0d\\u662f\\u9884\\u89c1\\u5230\\u9700\\u8981\\u5b83\\uff0c\\u6216\\u8005\\u81f3\\u5c11\\u53ef\\u4ee5\\u8bc1\\u660e\\u8fd9\\u79cd\\u62bd\\u8c61\\u662f\\u6709\\u4ef7\\u503c\\u7684\\u3002</p>\"},{\"location\":\"zh/#6\",\"title\":\"\\u5c06\\u63a5\\u53e3\\u5b9a\\u4e49\\u5728\\u5b9e\\u73b0\\u65b9\\u4e00\\u4fa7 (#6)\",\"text\":\"<p>\\u5c06\\u63a5\\u53e3\\u4fdd\\u7559\\u5728\\u5f15\\u7528\\u65b9\\u4e00\\u4fa7\\uff08\\u800c\\u4e0d\\u662f\\u5b9e\\u73b0\\u65b9\\u4e00\\u4fa7\\uff09\\u53ef\\u4ee5\\u907f\\u514d\\u4e0d\\u5fc5\\u8981\\u7684\\u62bd\\u8c61\\u3002</p>\"},{\"location\":\"zh/#7\",\"title\":\"\\u5c06\\u63a5\\u53e3\\u4f5c\\u4e3a\\u8fd4\\u56de\\u503c (#7)\",\"text\":\"<p>\\u4e3a\\u4e86\\u907f\\u514d\\u5728\\u7075\\u6d3b\\u6027\\u65b9\\u9762\\u53d7\\u5230\\u9650\\u5236\\uff0c\\u5927\\u591a\\u6570\\u60c5\\u51b5\\u4e0b\\u51fd\\u6570\\u4e0d\\u5e94\\u8be5\\u8fd4\\u56de\\u63a5\\u53e3\\uff0c\\u800c\\u5e94\\u8be5\\u8fd4\\u56de\\u5177\\u4f53\\u7684\\u5b9e\\u73b0\\u3002\\u76f8\\u53cd\\uff0c\\u51fd\\u6570\\u5e94\\u8be5\\u5c3d\\u53ef\\u80fd\\u5730\\u4f7f\\u7528\\u63a5\\u53e3\\u4f5c\\u4e3a\\u53c2\\u6570\\u3002</p>\"},{\"location\":\"zh/#any-8\",\"title\":\"<code>any</code> \\u6ca1\\u4f20\\u9012\\u4efb\\u4f55\\u4fe1\\u606f (#8)\",\"text\":\"<p>\\u53ea\\u6709\\u5728\\u9700\\u8981\\u63a5\\u53d7\\u6216\\u8fd4\\u56de\\u4efb\\u610f\\u7c7b\\u578b\\u65f6\\uff0c\\u624d\\u4f7f\\u7528 <code>any</code>\\uff0c\\u4f8b\\u5982 <code>json.Marshal</code>\\u3002\\u5176\\u4ed6\\u60c5\\u51b5\\u4e0b\\uff0c\\u56e0\\u4e3a <code>any</code> \\u4e0d\\u63d0\\u4f9b\\u6709\\u610f\\u4e49\\u7684\\u4fe1\\u606f\\uff0c\\u53ef\\u80fd\\u4f1a\\u5bfc\\u81f4\\u7f16\\u8bd1\\u65f6\\u95ee\\u9898\\uff0c\\u5982\\u5141\\u8bb8\\u8c03\\u7528\\u8005\\u8c03\\u7528\\u65b9\\u6cd5\\u5904\\u7406\\u4efb\\u610f\\u7c7b\\u578b\\u6570\\u636e\\u3002</p>\"},{\"location\":\"zh/#9\",\"title\":\"\\u56f0\\u60d1\\u4f55\\u65f6\\u8be5\\u7528\\u8303\\u578b (#9)\",\"text\":\"<p>\\u4f7f\\u7528\\u6cdb\\u578b\\uff0c\\u53ef\\u4ee5\\u901a\\u8fc7\\u7c7b\\u578b\\u53c2\\u6570\\u5206\\u79bb\\u5177\\u4f53\\u7684\\u6570\\u636e\\u7c7b\\u578b\\u548c\\u884c\\u4e3a\\uff0c\\u907f\\u514d\\u5199\\u5f88\\u591a\\u91cd\\u590d\\u5ea6\\u5f88\\u9ad8\\u7684\\u4ee3\\u7801\\u3002\\u7136\\u800c\\uff0c\\u4e0d\\u8981\\u8fc7\\u65e9\\u5730\\u4f7f\\u7528\\u6cdb\\u578b\\u3001\\u7c7b\\u578b\\u53c2\\u6570\\uff0c\\u53ea\\u6709\\u5728\\u4f60\\u770b\\u5230\\u771f\\u6b63\\u9700\\u8981\\u65f6\\u624d\\u4f7f\\u7528\\u3002\\u5426\\u5219\\uff0c\\u5b83\\u4eec\\u4f1a\\u5f15\\u5165\\u4e0d\\u5fc5\\u8981\\u7684\\u62bd\\u8c61\\u548c\\u590d\\u6742\\u6027\\u3002</p>\"},{\"location\":\"zh/#10\",\"title\":\"\\u672a\\u610f\\u8bc6\\u5230\\u7c7b\\u578b\\u5d4c\\u5957\\u7684\\u53ef\\u80fd\\u95ee\\u9898 (#10)\",\"text\":\"<p>\\u4f7f\\u7528\\u7c7b\\u578b\\u5d4c\\u5957\\u4e5f\\u53ef\\u4ee5\\u907f\\u514d\\u5199\\u4e00\\u4e9b\\u91cd\\u590d\\u4ee3\\u7801\\uff0c\\u7136\\u800c\\uff0c\\u5728\\u4f7f\\u7528\\u65f6\\u9700\\u8981\\u786e\\u4fdd\\u4e0d\\u4f1a\\u5bfc\\u81f4\\u4e0d\\u5408\\u7406\\u7684\\u53ef\\u89c1\\u6027\\u95ee\\u9898\\uff0c\\u6bd4\\u5982\\u6709\\u4e9b\\u5b57\\u6bb5\\u5e94\\u8be5\\u5bf9\\u5916\\u9690\\u85cf\\u4e0d\\u5e94\\u8be5\\u88ab\\u66b4\\u9732\\u3002</p>\"},{\"location\":\"zh/#function-option-11\",\"title\":\"\\u4e0d\\u4f7f\\u7528 function option \\u6a21\\u5f0f (#11)\",\"text\":\"<p>\\u4e3a\\u4e86\\u8bbe\\u8ba1\\u5e76\\u63d0\\u4f9b\\u66f4\\u53cb\\u597d\\u7684 API\\uff08\\u53ef\\u9009\\u53c2\\u6570\\uff09\\uff0c\\u4e3a\\u4e86\\u66f4\\u597d\\u5730\\u5904\\u7406\\u9009\\u9879\\uff0c\\u5e94\\u8be5\\u4f7f\\u7528 function option \\u6a21\\u5f0f\\u3002</p>\"},{\"location\":\"zh/#12\",\"title\":\"\\u5de5\\u7a0b\\u7ec4\\u7ec7\\u4e0d\\u5408\\u7406 (\\u5de5\\u7a0b\\u7ed3\\u6784\\u548c\\u5305\\u7684\\u7ec4\\u7ec7) (#12)\",\"text\":\"<p>\\u9075\\u5faa\\u50cf project-layout \\u7684\\u5efa\\u8bae\\u6765\\u7ec4\\u7ec7 Go \\u5de5\\u7a0b\\u662f\\u4e00\\u4e2a\\u4e0d\\u9519\\u7684\\u65b9\\u6cd5\\uff0c\\u5c24\\u5176\\u662f\\u4f60\\u6b63\\u5728\\u5bfb\\u627e\\u4e00\\u4e9b\\u7c7b\\u4f3c\\u7684\\u7ecf\\u9a8c\\u3001\\u60ef\\u4f8b\\u6765\\u7ec4\\u7ec7\\u4e00\\u4e2a\\u65b0\\u7684 Go \\u5de5\\u7a0b\\u7684\\u65f6\\u5019\\u3002</p>\"},{\"location\":\"zh/#13\",\"title\":\"\\u521b\\u5efa\\u5de5\\u5177\\u5305 (#13)\",\"text\":\"<p>\\u547d\\u540d\\u662f\\u8f6f\\u4ef6\\u8bbe\\u8ba1\\u5f00\\u53d1\\u4e2d\\u975e\\u5e38\\u91cd\\u8981\\u7684\\u4e00\\u4e2a\\u90e8\\u5206\\uff0c\\u521b\\u5efa\\u4e00\\u4e9b\\u540d\\u5982 <code>common</code>\\u3001<code>util</code>\\u3001<code>shared</code> \\u4e4b\\u7c7b\\u7684\\u5305\\u540d\\u5e76\\u4e0d\\u4f1a\\u7ed9\\u8bfb\\u8005\\u5e26\\u6765\\u592a\\u5927\\u4ef7\\u503c\\uff0c\\u5e94\\u8be5\\u5c06\\u8fd9\\u4e9b\\u5305\\u540d\\u91cd\\u6784\\u4e3a\\u66f4\\u6e05\\u6670\\u3001\\u66f4\\u5177\\u4f53\\u7684\\u5305\\u540d\\u3002</p>\"},{\"location\":\"zh/#14\",\"title\":\"\\u5ffd\\u7565\\u4e86\\u5305\\u540d\\u51b2\\u7a81 (#14)\",\"text\":\"<p>\\u4e3a\\u4e86\\u907f\\u514d\\u53d8\\u91cf\\u540d\\u548c\\u5305\\u540d\\u4e4b\\u95f4\\u7684\\u51b2\\u7a81\\uff0c\\u5bfc\\u81f4\\u6df7\\u6dc6\\u6216\\u751a\\u81f3\\u9519\\u8bef\\uff0c\\u5e94\\u4e3a\\u6bcf\\u4e2a\\u53d8\\u91cf\\u548c\\u5305\\u4f7f\\u7528\\u552f\\u4e00\\u7684\\u540d\\u79f0\\u3002\\u5982\\u679c\\u8fd9\\u4e0d\\u53ef\\u884c\\uff0c\\u53ef\\u4ee5\\u8003\\u8651\\u4f7f\\u7528\\u5bfc\\u5165\\u522b\\u540d <code>import importAlias 'importPath'</code> \\u4ee5\\u533a\\u5206\\u5305\\u540d\\u548c\\u53d8\\u91cf\\u540d\\uff0c\\u6216\\u8005\\u8003\\u8651\\u4e00\\u4e2a\\u66f4\\u597d\\u7684\\u53d8\\u91cf\\u540d\\u3002</p>\"},{\"location\":\"zh/#15\",\"title\":\"\\u4ee3\\u7801\\u7f3a\\u5c11\\u6587\\u6863 (#15)\",\"text\":\"<p>\\u4e3a\\u4e86\\u8ba9\\u4f7f\\u7528\\u65b9\\u3001\\u7ef4\\u62a4\\u4eba\\u5458\\u80fd\\u66f4\\u6e05\\u6670\\u5730\\u4e86\\u89e3\\u4f60\\u7684\\u4ee3\\u7801\\u7684\\u610f\\u56fe\\uff0c\\u5bfc\\u51fa\\u7684\\u5143\\u7d20\\uff08\\u51fd\\u6570\\u3001\\u7c7b\\u578b\\u3001\\u5b57\\u6bb5\\uff09\\u9700\\u8981\\u6dfb\\u52a0\\u6ce8\\u91ca\\u3002</p>\"},{\"location\":\"zh/#linters-16\",\"title\":\"\\u4e0d\\u4f7f\\u7528 linters \\u68c0\\u67e5 (#16)\",\"text\":\"<p>\\u4e3a\\u4e86\\u6539\\u5584\\u4ee3\\u7801\\u8d28\\u91cf\\u3001\\u6574\\u4f53\\u4ee3\\u7801\\u7684\\u4e00\\u81f4\\u6027\\uff0c\\u5e94\\u8be5\\u4f7f\\u7528 linters \\u548c formatters\\u3002</p>\"},{\"location\":\"zh/#_2\",\"title\":\"\\u6570\\u636e\\u7c7b\\u578b\",\"text\":\"\"},{\"location\":\"zh/#17\",\"title\":\"\\u516b\\u8fdb\\u5236\\u5b57\\u9762\\u91cf\\u5f15\\u53d1\\u7684\\u56f0\\u60d1 (#17)\",\"text\":\"<p>\\u5728\\u9605\\u8bfb\\u73b0\\u6709\\u4ee3\\u7801\\u65f6\\uff0c\\u8bf7\\u8bb0\\u4f4f\\u4ee5 0 \\u5f00\\u5934\\u7684\\u6574\\u6570\\u5b57\\u9762\\u91cf\\u662f\\u516b\\u8fdb\\u5236\\u6570\\u3002\\u6b64\\u5916\\uff0c\\u4e3a\\u4e86\\u63d0\\u9ad8\\u53ef\\u8bfb\\u6027\\uff0c\\u53ef\\u4ee5\\u901a\\u8fc7\\u5728\\u524d\\u9762\\u52a0\\u4e0a 0o \\u6765\\u663e\\u5f0f\\u5730\\u8868\\u793a\\u516b\\u8fdb\\u5236\\u6574\\u6570\\u3002</p>\"},{\"location\":\"zh/#18\",\"title\":\"\\u672a\\u6ce8\\u610f\\u53ef\\u80fd\\u7684\\u6574\\u6570\\u6ea2\\u51fa (#18)\",\"text\":\"<p>\\u5728 Go \\u4e2d\\u6574\\u6570\\u4e0a\\u6ea2\\u51fa\\u548c\\u4e0b\\u6ea2\\u662f\\u9759\\u9ed8\\u5904\\u7406\\u7684\\uff0c\\u6240\\u4ee5\\u4f60\\u53ef\\u4ee5\\u5b9e\\u73b0\\u81ea\\u5df1\\u7684\\u51fd\\u6570\\u6765\\u6355\\u83b7\\u5b83\\u4eec\\u3002</p>\"},{\"location\":\"zh/#19\",\"title\":\"\\u6ca1\\u6709\\u900f\\u5f7b\\u7406\\u89e3\\u6d6e\\u70b9\\u6570 (#19)\",\"text\":\"<p>\\u6bd4\\u8f83\\u6d6e\\u70b9\\u6570\\u65f6\\uff0c\\u901a\\u8fc7\\u6bd4\\u8f83\\u4e8c\\u8005\\u7684 delta \\u503c\\u662f\\u5426\\u4ecb\\u4e8e\\u4e00\\u5b9a\\u7684\\u8303\\u56f4\\u5185\\uff0c\\u80fd\\u8ba9\\u4f60\\u5199\\u51fa\\u53ef\\u79fb\\u690d\\u6027\\u66f4\\u597d\\u7684\\u4ee3\\u7801\\u3002</p> <p>\\u5728\\u8fdb\\u884c\\u52a0\\u6cd5\\u6216\\u51cf\\u6cd5\\u65f6\\uff0c\\u5c06\\u5177\\u6709\\u76f8\\u4f3c\\u6570\\u91cf\\u7ea7\\u7684\\u64cd\\u4f5c\\u5206\\u6210\\u540c\\u4e00\\u7ec4\\u4ee5\\u63d0\\u9ad8\\u7cbe\\u5ea6 (\\u8fc7\\u65e9\\u6307\\u6570\\u5bf9\\u9f50\\u4e22\\u5931\\u7cbe\\u5ea6)\\u3002\\u6b64\\u5916\\uff0c\\u5728\\u8fdb\\u884c\\u52a0\\u6cd5\\u548c\\u51cf\\u6cd5\\u4e4b\\u524d\\uff0c\\u5e94\\u5148\\u8fdb\\u884c\\u4e58\\u6cd5\\u548c\\u9664\\u6cd5 (\\u52a0\\u51cf\\u6cd5\\u8bef\\u5dee\\u4f1a\\u88ab\\u4e58\\u9664\\u653e\\u5927)\\u3002</p>\"},{\"location\":\"zh/#slice-20\",\"title\":\"\\u4e0d\\u7406\\u89e3 slice \\u7684\\u957f\\u5ea6\\u548c\\u5bb9\\u91cf (#20)\",\"text\":\"<p>\\u7406\\u89e3 slice \\u7684\\u957f\\u5ea6\\u548c\\u5bb9\\u91cf\\u7684\\u533a\\u522b\\uff0c\\u662f\\u4e00\\u4e2a Go \\u5f00\\u53d1\\u8005\\u7684\\u6838\\u5fc3\\u77e5\\u8bc6\\u70b9\\u4e4b\\u4e00\\u3002slice \\u7684\\u957f\\u5ea6\\u6307\\u7684\\u662f slice \\u5df2\\u7ecf\\u5b58\\u50a8\\u7684\\u5143\\u7d20\\u7684\\u6570\\u91cf\\uff0c\\u800c\\u5bb9\\u91cf\\u6307\\u7684\\u662f slice \\u5f53\\u524d\\u5e95\\u5c42\\u5f00\\u8f9f\\u7684\\u6570\\u7ec4\\u6700\\u591a\\u80fd\\u5bb9\\u7eb3\\u7684\\u5143\\u7d20\\u7684\\u6570\\u91cf\\u3002</p>\"},{\"location\":\"zh/#slice-21\",\"title\":\"\\u4e0d\\u9ad8\\u6548\\u7684 slice \\u521d\\u59cb\\u5316 (#21)\",\"text\":\"<p>\\u5f53\\u521b\\u5efa\\u4e00\\u4e2a slice \\u65f6\\uff0c\\u5982\\u679c\\u5176\\u957f\\u5ea6\\u53ef\\u4ee5\\u9884\\u5148\\u786e\\u5b9a\\uff0c\\u90a3\\u4e48\\u53ef\\u4ee5\\u5728\\u5b9a\\u4e49\\u65f6\\u6307\\u5b9a\\u5b83\\u7684\\u957f\\u5ea6\\u548c\\u5bb9\\u91cf\\u3002\\u8fd9\\u53ef\\u4ee5\\u6539\\u5584\\u540e\\u671f append \\u65f6\\u4e00\\u6b21\\u6216\\u8005\\u591a\\u6b21\\u7684\\u5185\\u5b58\\u5206\\u914d\\u64cd\\u4f5c\\uff0c\\u4ece\\u800c\\u6539\\u5584\\u6027\\u80fd\\u3002\\u5bf9\\u4e8e map \\u7684\\u521d\\u59cb\\u5316\\u4e5f\\u662f\\u5982\\u6b64\\u3002</p>\"},{\"location\":\"zh/#nil-slice-22\",\"title\":\"\\u56f0\\u60d1\\u4e8e nil \\u548c\\u7a7a slice (#22)\",\"text\":\"<p>\\u4e3a\\u4e86\\u907f\\u514d\\u5e38\\u89c1\\u7684\\u5bf9 nil \\u548c empty slice \\u5904\\u7406\\u884c\\u4e3a\\u7684\\u6df7\\u6dc6\\uff0c\\u4f8b\\u5982\\u5728\\u4f7f\\u7528 encoding/json \\u6216 reflect \\u5305\\u65f6\\uff0c\\u4f60\\u9700\\u8981\\u7406\\u89e3 nil \\u548c empty slice \\u7684\\u533a\\u522b\\u3002\\u4e24\\u8005\\u90fd\\u662f\\u957f\\u5ea6\\u4e3a\\u96f6\\u3001\\u5bb9\\u91cf\\u4e3a\\u96f6\\u7684\\u5207\\u7247\\uff0c\\u4f46\\u662f nil \\u5207\\u7247\\u4e0d\\u9700\\u8981\\u5206\\u914d\\u5185\\u5b58\\u3002</p>\"},{\"location\":\"zh/#slice-23\",\"title\":\"\\u6ca1\\u6709\\u9002\\u5f53\\u68c0\\u67e5 slice \\u662f\\u5426\\u4e3a\\u7a7a (#23)\",\"text\":\"<p>\\u68c0\\u67e5\\u4e00\\u4e2a slice \\u662f\\u5426\\u5305\\u542b\\u4efb\\u4f55\\u5143\\u7d20\\uff0c\\u53ef\\u4ee5\\u68c0\\u67e5\\u5176\\u957f\\u5ea6\\uff0c\\u4e0d\\u7ba1 slice \\u662f nil \\u8fd8\\u662f empty\\uff0c\\u68c0\\u67e5\\u957f\\u5ea6\\u90fd\\u662f\\u6709\\u6548\\u7684\\u3002\\u8fd9\\u4e2a\\u68c0\\u67e5\\u65b9\\u6cd5\\u4e5f\\u9002\\u7528\\u4e8e map\\u3002</p> <p>\\u4e3a\\u4e86\\u8bbe\\u8ba1\\u66f4\\u660e\\u786e\\u7684 API\\uff0cAPI \\u4e0d\\u5e94\\u533a\\u5206 nil \\u548c\\u7a7a\\u5207\\u7247\\u3002</p>\"},{\"location\":\"zh/#slice-24\",\"title\":\"\\u6ca1\\u6709\\u6b63\\u786e\\u62f7\\u8d1d slice (#24)\",\"text\":\"<p>\\u4f7f\\u7528 <code>copy</code> \\u62f7\\u8d1d\\u4e00\\u4e2a slice \\u5143\\u7d20\\u5230\\u53e6\\u4e00\\u4e2a slice \\u65f6\\uff0c\\u9700\\u8981\\u8bb0\\u5f97\\uff0c\\u5b9e\\u9645\\u62f7\\u8d1d\\u7684\\u5143\\u7d20\\u6570\\u91cf\\u662f\\u4e8c\\u8005 slice \\u957f\\u5ea6\\u4e2d\\u7684\\u8f83\\u5c0f\\u503c\\u3002</p>\"},{\"location\":\"zh/#slice-append-25\",\"title\":\"slice append \\u5e26\\u6765\\u7684\\u9884\\u671f\\u4e4b\\u5916\\u7684\\u526f\\u4f5c\\u7528 (#25)\",\"text\":\"<p>\\u5982\\u679c\\u4e24\\u4e2a\\u4e0d\\u540c\\u7684\\u51fd\\u6570\\u64cd\\u4f5c\\u7684 slice \\u590d\\u7528\\u4e86\\u76f8\\u540c\\u7684\\u5e95\\u5c42\\u6570\\u7ec4\\uff0c\\u5b83\\u4eec\\u5bf9 slice \\u6267\\u884c append \\u64cd\\u4f5c\\u65f6\\u53ef\\u80fd\\u4f1a\\u4ea7\\u751f\\u51b2\\u7a81\\u3002\\u4f7f\\u7528 copy \\u6765\\u5b8c\\u6574\\u590d\\u5236\\u4e00\\u4e2a slice \\u6216\\u8005\\u4f7f\\u7528\\u5b8c\\u6574\\u7684 slice \\u8868\\u8fbe\\u5f0f <code>[low:high:max]</code> \\u9650\\u5236\\u6700\\u5927\\u5bb9\\u91cf\\uff0c\\u6709\\u52a9\\u4e8e\\u907f\\u514d\\u4ea7\\u751f\\u51b2\\u7a81\\u3002\\u5f53\\u60f3\\u5bf9\\u4e00\\u4e2a\\u5927 slice \\u8fdb\\u884c shrink \\u64cd\\u4f5c\\u65f6\\uff0c\\u4e24\\u79cd\\u65b9\\u5f0f\\u4e2d\\uff0c\\u53ea\\u6709 copy \\u624d\\u53ef\\u4ee5\\u907f\\u514d\\u5185\\u5b58\\u6cc4\\u6f0f\\u3002</p>\"},{\"location\":\"zh/#slice-26\",\"title\":\"slice \\u548c\\u5185\\u5b58\\u6cc4\\u6f0f (#26)\",\"text\":\"<p>\\u5bf9\\u4e8e slice \\u5143\\u7d20\\u4e3a\\u6307\\u9488\\uff0c\\u6216\\u8005 slice \\u5143\\u7d20\\u4e3a struct \\u4f46\\u662f\\u8be5 struct \\u542b\\u6709\\u6307\\u9488\\u5b57\\u6bb5\\uff0c\\u5f53\\u901a\\u8fc7 <code>slice[low:high]</code> \\u64cd\\u4f5c\\u53d6 subslice \\u65f6\\uff0c\\u5bf9\\u4e8e\\u90a3\\u4e9b\\u4e0d\\u53ef\\u8bbf\\u95ee\\u7684\\u5143\\u7d20\\u53ef\\u4ee5\\u663e\\u5f0f\\u8bbe\\u7f6e\\u4e3a nil \\u6765\\u907f\\u514d\\u5185\\u5b58\\u6cc4\\u9732\\u3002</p>\"},{\"location\":\"zh/#map-27\",\"title\":\"\\u4e0d\\u9ad8\\u6548\\u7684 map \\u521d\\u59cb\\u5316 (#27)\",\"text\":\"<p>\\u89c1 #21.</p>\"},{\"location\":\"zh/#map-28\",\"title\":\"map \\u548c\\u5185\\u5b58\\u6cc4\\u6f0f (#28)\",\"text\":\"<p>\\u4e00\\u4e2a map \\u7684 buckets \\u5360\\u7528\\u7684\\u5185\\u5b58\\u53ea\\u4f1a\\u589e\\u957f\\uff0c\\u4e0d\\u4f1a\\u7f29\\u51cf\\u3002\\u56e0\\u6b64\\uff0c\\u5982\\u679c\\u5b83\\u5bfc\\u81f4\\u4e86\\u4e00\\u4e9b\\u5185\\u5b58\\u5360\\u7528\\u7684\\u95ee\\u9898\\uff0c\\u4f60\\u9700\\u8981\\u5c1d\\u8bd5\\u4e0d\\u540c\\u7684\\u65b9\\u5f0f\\u6765\\u89e3\\u51b3\\uff0c\\u6bd4\\u5982\\u91cd\\u65b0\\u521b\\u5efa\\u4e00\\u4e2a map \\u4ee3\\u66ff\\u539f\\u6765\\u7684\\uff08\\u539f\\u6765\\u7684 map \\u4f1a\\u88ab GC \\u6389\\uff09\\uff0c\\u6216\\u8005 <code>map[keyType]valueType</code> \\u4e2d\\u7684 valueType \\u4f7f\\u7528\\u6307\\u9488\\u4ee3\\u66ff\\u957f\\u5ea6\\u56fa\\u5b9a\\u7684\\u6570\\u7ec4\\u6216\\u8005 sliceHeader \\u6765\\u7f13\\u89e3\\u8fc7\\u591a\\u7684\\u5185\\u5b58\\u5360\\u7528\\u3002</p>\"},{\"location\":\"zh/#29\",\"title\":\"\\u4e0d\\u6b63\\u786e\\u7684\\u503c\\u6bd4\\u8f83 (#29)\",\"text\":\"<p>Go \\u4e2d\\u6bd4\\u8f83\\u4e24\\u4e2a\\u7c7b\\u578b\\u503c\\u65f6\\uff0c\\u5982\\u679c\\u662f\\u53ef\\u6bd4\\u8f83\\u7c7b\\u578b\\uff0c\\u90a3\\u4e48\\u53ef\\u4ee5\\u4f7f\\u7528 <code>==</code> \\u6216\\u8005 <code>!=</code> \\u8fd0\\u7b97\\u7b26\\u8fdb\\u884c\\u6bd4\\u8f83\\uff0c\\u6bd4\\u5982\\uff1abooleans\\u3001numerals\\u3001strings\\u3001pointers\\u3001channels\\uff0c\\u4ee5\\u53ca\\u5b57\\u6bb5\\u5168\\u90e8\\u662f\\u53ef\\u6bd4\\u8f83\\u7c7b\\u578b\\u7684 structs\\u3002\\u5176\\u4ed6\\u60c5\\u51b5\\u4e0b\\uff0c\\u4f60\\u53ef\\u4ee5\\u4f7f\\u7528 <code>reflect.DeepEqual</code> \\u6765\\u6bd4\\u8f83\\uff0c\\u7528\\u53cd\\u5c04\\u7684\\u8bdd\\u4f1a\\u727a\\u7272\\u4e00\\u70b9\\u6027\\u80fd\\uff0c\\u4e5f\\u53ef\\u4ee5\\u4f7f\\u7528\\u81ea\\u5b9a\\u4e49\\u7684\\u5b9e\\u73b0\\u548c\\u5176\\u4ed6\\u5e93\\u6765\\u5b8c\\u6210\\u3002</p>\"},{\"location\":\"zh/#_3\",\"title\":\"\\u63a7\\u5236\\u7ed3\\u6784\",\"text\":\"\"},{\"location\":\"zh/#range-30\",\"title\":\"\\u5ffd\\u7565\\u4e86 <code>range</code> \\u5faa\\u73af\\u53d8\\u91cf\\u662f\\u4e00\\u4e2a\\u62f7\\u8d1d (#30)\",\"text\":\"<p><code>range</code> \\u5faa\\u73af\\u4e2d\\u7684\\u5faa\\u73af\\u53d8\\u91cf\\u662f\\u904d\\u5386\\u5bb9\\u5668\\u4e2d\\u5143\\u7d20\\u503c\\u7684\\u4e00\\u4e2a\\u62f7\\u8d1d\\u3002\\u56e0\\u6b64\\uff0c\\u5982\\u679c\\u5143\\u7d20\\u503c\\u662f\\u4e00\\u4e2a struct \\u5e76\\u4e14\\u60f3\\u5728 <code>range</code> \\u4e2d\\u4fee\\u6539\\u5b83\\uff0c\\u53ef\\u4ee5\\u901a\\u8fc7\\u7d22\\u5f15\\u503c\\u6765\\u8bbf\\u95ee\\u5e76\\u4fee\\u6539\\u5b83\\uff0c\\u6216\\u8005\\u4f7f\\u7528\\u7ecf\\u5178\\u7684 for \\u5faa\\u73af+\\u7d22\\u5f15\\u503c\\u7684\\u5199\\u6cd5\\uff08\\u9664\\u975e\\u904d\\u5386\\u7684\\u5143\\u7d20\\u662f\\u4e00\\u4e2a\\u6307\\u9488\\uff09\\u3002</p>\"},{\"location\":\"zh/#range-channels-arrays-31\",\"title\":\"\\u5ffd\\u7565\\u4e86 <code>range</code> \\u5faa\\u73af\\u4e2d\\u8fed\\u4ee3\\u76ee\\u6807\\u503c\\u7684\\u8ba1\\u7b97\\u65b9\\u5f0f (channels \\u548c arrays) (#31)\",\"text\":\"<p>\\u4f20\\u9012\\u7ed9 <code>range</code> \\u64cd\\u4f5c\\u7684\\u8fed\\u4ee3\\u76ee\\u6807\\u5bf9\\u5e94\\u7684\\u8868\\u8fbe\\u5f0f\\u7684\\u503c\\uff0c\\u53ea\\u4f1a\\u5728\\u5faa\\u73af\\u6267\\u884c\\u524d\\u88ab\\u8ba1\\u7b97\\u4e00\\u6b21\\uff0c\\u7406\\u89e3\\u8fd9\\u4e2a\\u6709\\u52a9\\u4e8e\\u907f\\u514d\\u72af\\u4e00\\u4e9b\\u5e38\\u89c1\\u7684\\u9519\\u8bef\\uff0c\\u4f8b\\u5982\\u4e0d\\u9ad8\\u6548\\u7684 channel \\u8d4b\\u503c\\u64cd\\u4f5c\\u548c slice \\u8fed\\u4ee3\\u64cd\\u4f5c\\u3002</p>\"},{\"location\":\"zh/#range-32\",\"title\":\"\\u5ffd\\u7565\\u4e86 <code>range</code> \\u5faa\\u73af\\u4e2d\\u6307\\u9488\\u5143\\u7d20\\u7684\\u5f71\\u54cd (#32)\",\"text\":\"<p>\\u8fd9\\u91cc\\u5176\\u5b9e\\u5f3a\\u8c03\\u7684\\u662f <code>range</code> \\u8fed\\u4ee3\\u8fc7\\u7a0b\\u4e2d\\uff0c\\u8fed\\u4ee3\\u53d8\\u91cf\\u5b9e\\u9645\\u4e0a\\u662f\\u4e00\\u4e2a\\u62f7\\u8d1d\\u3002\\u5047\\u8bbe\\u7ed9\\u53e6\\u5916\\u4e00\\u4e2a\\u5bb9\\u5668\\u5143\\u7d20\\uff08\\u6307\\u9488\\u7c7b\\u578b\\uff09\\u8d4b\\u503c\\uff0c\\u4e14\\u9700\\u8981\\u5bf9\\u8fed\\u4ee3\\u53d8\\u91cf\\u53d6\\u5730\\u5740\\u8f6c\\u6362\\u6210\\u6307\\u9488\\u518d\\u8d4b\\u503c\\u7684\\u8bdd\\uff0c\\u8fd9\\u91cc\\u6f5c\\u85cf\\u7740\\u4e00\\u4e2a\\u9519\\u8bef\\uff0c\\u5c31\\u662f for \\u5faa\\u73af\\u8fed\\u4ee3\\u53d8\\u91cf\\u662f per-variable-per-loop \\u800c\\u4e0d\\u662f per-variable-per-iteration\\u3002\\u5982\\u679c\\u662f\\u901a\\u8fc7\\u5c40\\u90e8\\u53d8\\u91cf\\uff08\\u7528\\u8fed\\u4ee3\\u53d8\\u91cf\\u6765\\u521d\\u59cb\\u5316\\uff09\\u6216\\u8005\\u4f7f\\u7528\\u7d22\\u5f15\\u503c\\u6765\\u76f4\\u63a5\\u5f15\\u7528\\u8fed\\u4ee3\\u7684\\u5143\\u7d20\\uff0c\\u5c06\\u6709\\u52a9\\u4e8e\\u907f\\u514d\\u62f7\\u8d1d\\u6307\\u9488(\\u8fed\\u4ee3\\u53d8\\u91cf\\u7684\\u5730\\u5740)\\u4e4b\\u7c7b\\u7684 bug\\u3002</p>\"},{\"location\":\"zh/#map-33\",\"title\":\"map \\u8fed\\u4ee3\\u8fc7\\u7a0b\\u4e2d\\u7684\\u9519\\u8bef\\u5047\\u8bbe\\uff08\\u904d\\u5386\\u987a\\u5e8f\\u548c\\u8fed\\u4ee3\\u8fc7\\u7a0b\\u4e2d\\u63d2\\u5165\\uff09(#33)\",\"text\":\"<p>\\u4f7f\\u7528 map \\u65f6\\uff0c\\u4e3a\\u4e86\\u80fd\\u5f97\\u5230\\u786e\\u5b9a\\u4e00\\u81f4\\u7684\\u7ed3\\u679c\\uff0c\\u5e94\\u8be5\\u8bb0\\u4f4f Go \\u4e2d\\u7684 map \\u6570\\u636e\\u7ed3\\u6784\\uff1a * \\u4e0d\\u4f1a\\u6309\\u7167 key \\u5bf9 data \\u8fdb\\u884c\\u6392\\u5e8f\\uff0c\\u904d\\u5386\\u65f6 key \\u4e0d\\u662f\\u6709\\u5e8f\\u7684\\uff1b * \\u904d\\u5386\\u65f6\\u7684\\u987a\\u5e8f\\uff0c\\u4e5f\\u4e0d\\u662f\\u6309\\u7167\\u63d2\\u5165\\u65f6\\u7684\\u987a\\u5e8f\\uff1b * \\u6ca1\\u6709\\u4e00\\u4e2a\\u786e\\u5b9a\\u6027\\u7684\\u904d\\u5386\\u987a\\u5e8f\\uff0c\\u6bcf\\u6b21\\u904d\\u5386\\u987a\\u5e8f\\u662f\\u4e0d\\u540c\\u7684\\uff1b * \\u4e0d\\u80fd\\u4fdd\\u8bc1\\u8fed\\u4ee3\\u8fc7\\u7a0b\\u4e2d\\u65b0\\u63d2\\u5165\\u7684\\u5143\\u7d20\\uff0c\\u5728\\u5f53\\u524d\\u8fed\\u4ee3\\u4e2d\\u80fd\\u591f\\u88ab\\u904d\\u5386\\u5230\\uff1b</p>\"},{\"location\":\"zh/#break-34\",\"title\":\"\\u5ffd\\u7565\\u4e86 <code>break</code> \\u8bed\\u53e5\\u662f\\u5982\\u4f55\\u5de5\\u4f5c\\u7684 (#34)\",\"text\":\"<p>\\u914d\\u5408 label \\u4f7f\\u7528 <code>break</code> \\u548c <code>continue</code>\\uff0c\\u80fd\\u591f\\u8df3\\u8fc7\\u4e00\\u4e2a\\u7279\\u5b9a\\u7684\\u8bed\\u53e5\\uff0c\\u5728\\u67d0\\u4e9b\\u5faa\\u73af\\u4e2d\\u5b58\\u5728 <code>switch</code> \\u548c <code>select</code> \\u8bed\\u53e5\\u7684\\u573a\\u666f\\u4e2d\\u5c31\\u6bd4\\u8f83\\u6709\\u5e2e\\u52a9\\u3002</p>\"},{\"location\":\"zh/#defer-35\",\"title\":\"\\u5728\\u5faa\\u73af\\u4e2d\\u4f7f\\u7528 <code>defer</code>  (#35)\",\"text\":\"<p>\\u5728\\u5faa\\u73af\\u4e2d\\u4f7f\\u7528 defer \\u4e0d\\u80fd\\u5728\\u6bcf\\u8f6e\\u8fed\\u4ee3\\u7ed3\\u675f\\u65f6\\u6267\\u884c defer \\u8bed\\u53e5\\uff0c\\u4f46\\u662f\\u5c06\\u5faa\\u73af\\u903b\\u8f91\\u63d0\\u53d6\\u5230\\u51fd\\u6570\\u5185\\u90e8\\u4f1a\\u5728\\u6bcf\\u6b21\\u8fed\\u4ee3\\u7ed3\\u675f\\u65f6\\u6267\\u884c defer \\u8bed\\u53e5\\u3002</p>\"},{\"location\":\"zh/#_4\",\"title\":\"\\u5b57\\u7b26\\u4e32\",\"text\":\"\"},{\"location\":\"zh/#rune-36\",\"title\":\"\\u6ca1\\u6709\\u7406\\u89e3 rune (#36)\",\"text\":\"<p>\\u7406\\u89e3 rune \\u7c7b\\u578b\\u5bf9\\u5e94\\u7684\\u662f\\u4e00\\u4e2a unicode \\u7801\\u70b9\\uff0c\\u6bcf\\u4e00\\u4e2a unicode \\u7801\\u70b9\\u5176\\u5b9e\\u662f\\u4e00\\u4e2a\\u591a\\u5b57\\u8282\\u7684\\u5e8f\\u5217\\uff0c\\u4e0d\\u662f\\u4e00\\u4e2a byte\\u3002\\u8fd9\\u5e94\\u8be5\\u662f Go \\u5f00\\u53d1\\u8005\\u7684\\u6838\\u5fc3\\u77e5\\u8bc6\\u70b9\\u4e4b\\u4e00\\uff0c\\u7406\\u89e3\\u4e86\\u8fd9\\u4e2a\\u6709\\u52a9\\u4e8e\\u66f4\\u51c6\\u786e\\u5730\\u5904\\u7406\\u5b57\\u7b26\\u4e32\\u3002</p>\"},{\"location\":\"zh/#37\",\"title\":\"\\u4e0d\\u6b63\\u786e\\u7684\\u5b57\\u7b26\\u4e32\\u904d\\u5386 (#37)\",\"text\":\"<p>\\u4f7f\\u7528 <code>range</code> \\u64cd\\u4f5c\\u7b26\\u5bf9\\u4e00\\u4e2a string \\u8fdb\\u884c\\u904d\\u5386\\u5b9e\\u9645\\u4e0a\\u662f\\u5bf9 string \\u5bf9\\u5e94\\u7684 <code>[]rune</code> \\u8fdb\\u884c\\u904d\\u5386\\uff0c\\u8fed\\u4ee3\\u53d8\\u91cf\\u4e2d\\u7684\\u7d22\\u5f15\\u503c\\uff0c\\u8868\\u793a\\u7684\\u5f53\\u524d rune \\u5bf9\\u5e94\\u7684 <code>[]rune</code> \\u5728\\u6574\\u4e2a <code>[]rune(string)</code> \\u4e2d\\u7684\\u8d77\\u59cb\\u7d22\\u5f15\\u3002\\u5982\\u679c\\u8981\\u8bbf\\u95ee string \\u4e2d\\u7684\\u67d0\\u4e00\\u4e2a rune\\uff08\\u6bd4\\u5982\\u7b2c\\u4e09\\u4e2a\\uff09\\uff0c\\u9996\\u5148\\u8981\\u5c06\\u5b57\\u7b26\\u4e32\\u8f6c\\u6362\\u4e3a <code>[]rune</code> \\u7136\\u540e\\u518d\\u6309\\u7d22\\u5f15\\u503c\\u8bbf\\u95ee\\u3002</p>\"},{\"location\":\"zh/#trim-38\",\"title\":\"\\u8bef\\u7528 trim \\u51fd\\u6570 (#38)\",\"text\":\"<p><code>strings.TrimRight</code>/<code>strings.TrimLeft</code> \\u79fb\\u9664\\u5728\\u5b57\\u7b26\\u4e32\\u5c3e\\u90e8\\u6216\\u8005\\u5f00\\u5934\\u51fa\\u73b0\\u7684\\u4e00\\u4e9b runes\\uff0c\\u51fd\\u6570\\u4f1a\\u6307\\u5b9a\\u4e00\\u4e2a rune \\u96c6\\u5408\\uff0c\\u51fa\\u73b0\\u5728\\u96c6\\u5408\\u4e2d\\u7684 rune \\u5c06\\u88ab\\u4ece\\u5b57\\u7b26\\u4e32\\u79fb\\u9664\\u3002\\u800c <code>strings.TrimSuffix</code>/<code>strings.TrimPrefix</code> \\u662f\\u79fb\\u9664\\u5b57\\u7b26\\u4e32\\u7684\\u4e00\\u4e2a\\u540e\\u7f00/\\u524d\\u7f00\\u3002</p>\"},{\"location\":\"zh/#39\",\"title\":\"\\u4e0d\\u7ecf\\u4f18\\u5316\\u7684\\u5b57\\u7b26\\u4e32\\u62fc\\u63a5\\u64cd\\u4f5c (#39)\",\"text\":\"<p>\\u5bf9\\u4e00\\u4e2a\\u5b57\\u7b26\\u4e32\\u5217\\u8868\\u8fdb\\u884c\\u904d\\u5386\\u62fc\\u63a5\\u64cd\\u4f5c\\uff0c\\u5e94\\u8be5\\u901a\\u8fc7 <code>strings.Builder</code> \\u6765\\u5b8c\\u6210\\uff0c\\u4ee5\\u907f\\u514d\\u6bcf\\u6b21\\u8fed\\u4ee3\\u62fc\\u63a5\\u65f6\\u90fd\\u5206\\u914d\\u4e00\\u4e2a\\u65b0\\u7684 string \\u5bf9\\u8c61\\u51fa\\u6765\\u3002</p>\"},{\"location\":\"zh/#40\",\"title\":\"\\u65e0\\u7528\\u7684\\u5b57\\u7b26\\u4e32\\u8f6c\\u6362 (#40)\",\"text\":\"<p><code>bytes</code> \\u5305\\u63d0\\u4f9b\\u4e86\\u4e00\\u4e9b\\u548c <code>strings</code> \\u5305\\u76f8\\u4f3c\\u7684\\u64cd\\u4f5c\\uff0c\\u53ef\\u4ee5\\u5e2e\\u52a9\\u907f\\u514d []byte/string \\u4e4b\\u95f4\\u7684\\u8f6c\\u6362\\u3002</p>\"},{\"location\":\"zh/#41\",\"title\":\"\\u5b50\\u5b57\\u7b26\\u4e32\\u548c\\u5185\\u5b58\\u6cc4\\u6f0f (#41)\",\"text\":\"<p>\\u4f7f\\u7528\\u4e00\\u4e2a\\u5b50\\u5b57\\u7b26\\u4e32\\u7684\\u62f7\\u8d1d\\uff0c\\u6709\\u52a9\\u4e8e\\u907f\\u514d\\u5185\\u5b58\\u6cc4\\u6f0f\\uff0c\\u56e0\\u4e3a\\u5bf9\\u4e00\\u4e2a\\u5b57\\u7b26\\u4e32\\u7684 <code>s[low:high]</code> \\u64cd\\u4f5c\\u8fd4\\u56de\\u7684\\u5b50\\u5b57\\u7b26\\u4e32\\uff0c\\u5176\\u4f7f\\u7528\\u4e86\\u548c\\u539f\\u5b57\\u7b26\\u4e32 s \\u76f8\\u540c\\u7684\\u5e95\\u5c42\\u6570\\u7ec4\\u3002</p>\"},{\"location\":\"zh/#_5\",\"title\":\"\\u51fd\\u6570\\u548c\\u65b9\\u6cd5\",\"text\":\"\"},{\"location\":\"zh/#42\",\"title\":\"\\u4e0d\\u77e5\\u9053\\u4f7f\\u7528\\u54ea\\u79cd\\u63a5\\u6536\\u5668\\u7c7b\\u578b (#42)\",\"text\":\"<p>\\u5bf9\\u4e8e\\u63a5\\u6536\\u5668\\u7c7b\\u578b\\u662f\\u91c7\\u7528 value \\u7c7b\\u578b\\u8fd8\\u662f pointer \\u7c7b\\u578b\\uff0c\\u5e94\\u8be5\\u53d6\\u51b3\\u4e8e\\u4e0b\\u9762\\u8fd9\\u51e0\\u79cd\\u56e0\\u7d20\\uff0c\\u6bd4\\u5982\\uff1a\\u65b9\\u6cd5\\u5185\\u662f\\u5426\\u4f1a\\u5bf9\\u5b83\\u8fdb\\u884c\\u4fee\\u6539\\uff0c\\u5b83\\u662f\\u5426\\u5305\\u542b\\u4e86\\u4e00\\u4e2a\\u4e0d\\u80fd\\u88ab\\u62f7\\u8d1d\\u7684\\u5b57\\u6bb5\\uff0c\\u4ee5\\u53ca\\u5b83\\u8868\\u793a\\u7684\\u5bf9\\u8c61\\u6709\\u591a\\u5927\\u3002\\u5982\\u679c\\u6709\\u7591\\u95ee\\uff0c\\u63a5\\u6536\\u5668\\u53ef\\u4ee5\\u8003\\u8651\\u4f7f\\u7528 pointer \\u7c7b\\u578b\\u3002</p>\"},{\"location\":\"zh/#43\",\"title\":\"\\u4ece\\u4e0d\\u4f7f\\u7528\\u547d\\u540d\\u7684\\u8fd4\\u56de\\u503c (#43)\",\"text\":\"<p>\\u4f7f\\u7528\\u547d\\u540d\\u7684\\u8fd4\\u56de\\u503c\\uff0c\\u662f\\u4e00\\u79cd\\u6709\\u6548\\u6539\\u5584\\u51fd\\u6570\\u3001\\u65b9\\u6cd5\\u53ef\\u8bfb\\u6027\\u7684\\u65b9\\u6cd5\\uff0c\\u7279\\u522b\\u662f\\u8fd4\\u56de\\u503c\\u5217\\u8868\\u4e2d\\u6709\\u591a\\u4e2a\\u7c7b\\u578b\\u76f8\\u540c\\u7684\\u53c2\\u6570\\u3002\\u53e6\\u5916\\uff0c\\u56e0\\u4e3a\\u8fd4\\u56de\\u503c\\u5217\\u8868\\u4e2d\\u7684\\u53c2\\u6570\\u662f\\u7ecf\\u8fc7\\u96f6\\u503c\\u521d\\u59cb\\u5316\\u8fc7\\u7684\\uff0c\\u67d0\\u4e9b\\u573a\\u666f\\u4e0b\\u4e5f\\u4f1a\\u7b80\\u5316\\u51fd\\u6570\\u3001\\u65b9\\u6cd5\\u7684\\u5b9e\\u73b0\\u3002\\u4f46\\u662f\\u9700\\u8981\\u6ce8\\u610f\\u5b83\\u7684\\u4e00\\u4e9b\\u6f5c\\u5728\\u526f\\u4f5c\\u7528\\u3002</p>\"},{\"location\":\"zh/#44\",\"title\":\"\\u4f7f\\u7528\\u547d\\u540d\\u7684\\u8fd4\\u56de\\u503c\\u65f6\\u9884\\u671f\\u5916\\u7684\\u526f\\u4f5c\\u7528 (#44)\",\"text\":\"<p>\\u89c1 #43.</p> <p>\\u4f7f\\u7528\\u547d\\u540d\\u7684\\u8fd4\\u56de\\u503c\\uff0c\\u56e0\\u4e3a\\u5b83\\u5df2\\u7ecf\\u88ab\\u521d\\u59cb\\u5316\\u4e86\\u96f6\\u503c\\uff0c\\u9700\\u8981\\u6ce8\\u610f\\u5728\\u67d0\\u4e9b\\u60c5\\u51b5\\u4e0b\\u5f02\\u5e38\\u8fd4\\u56de\\u65f6\\u662f\\u5426\\u9700\\u8981\\u7ed9\\u5b83\\u8d4b\\u4e88\\u4e00\\u4e2a\\u4e0d\\u540c\\u7684\\u503c\\uff0c\\u6bd4\\u5982\\u8fd4\\u56de\\u503c\\u5217\\u8868\\u5b9a\\u4e49\\u4e86\\u4e00\\u4e2a\\u6709\\u540d\\u53c2\\u6570 <code>err error</code>\\uff0c\\u9700\\u8981\\u6ce8\\u610f <code>return err</code> \\u65f6\\u662f\\u5426\\u6b63\\u786e\\u5730\\u5bf9 <code>err</code> \\u8fdb\\u884c\\u4e86\\u8d4b\\u503c\\u3002</p>\"},{\"location\":\"zh/#nil-45\",\"title\":\"\\u8fd4\\u56de\\u4e00\\u4e2a nil \\u63a5\\u6536\\u5668 (#45)\",\"text\":\"<p>\\u5f53\\u8fd4\\u56de\\u4e00\\u4e2a interface \\u53c2\\u6570\\u65f6\\uff0c\\u9700\\u8981\\u5c0f\\u5fc3\\uff0c\\u4e0d\\u8981\\u8fd4\\u56de\\u4e00\\u4e2a nil \\u6307\\u9488\\uff0c\\u800c\\u662f\\u5e94\\u8be5\\u663e\\u5f0f\\u8fd4\\u56de\\u4e00\\u4e2a nil \\u503c\\u3002\\u5426\\u5219\\uff0c\\u53ef\\u80fd\\u4f1a\\u53d1\\u751f\\u4e00\\u4e9b\\u9884\\u671f\\u5916\\u7684\\u95ee\\u9898\\uff0c\\u56e0\\u4e3a\\u8c03\\u7528\\u65b9\\u4f1a\\u6536\\u5230\\u4e00\\u4e2a\\u975e nil \\u7684\\u503c\\u3002</p>\"},{\"location\":\"zh/#46\",\"title\":\"\\u4f7f\\u7528\\u6587\\u4ef6\\u540d\\u4f5c\\u4e3a\\u51fd\\u6570\\u5165\\u53c2 (#46)\",\"text\":\"<p>\\u8bbe\\u8ba1\\u51fd\\u6570\\u65f6\\u4f7f\\u7528 <code>io.Reader</code> \\u7c7b\\u578b\\u4f5c\\u4e3a\\u5165\\u53c2\\uff0c\\u800c\\u4e0d\\u662f\\u6587\\u4ef6\\u540d\\uff0c\\u5c06\\u6709\\u52a9\\u4e8e\\u6539\\u5584\\u51fd\\u6570\\u7684\\u53ef\\u590d\\u7528\\u6027\\u3001\\u6613\\u6d4b\\u8bd5\\u6027\\u3002</p>\"},{\"location\":\"zh/#defer-value-47\",\"title\":\"\\u5ffd\\u7565 <code>defer</code> \\u8bed\\u53e5\\u4e2d\\u53c2\\u6570\\u3001\\u63a5\\u6536\\u5668\\u503c\\u7684\\u8ba1\\u7b97\\u65b9\\u5f0f (\\u53c2\\u6570\\u503c\\u8ba1\\u7b97, \\u6307\\u9488, \\u548c value \\u7c7b\\u578b\\u63a5\\u6536\\u5668) (#47)\",\"text\":\"<p>\\u4e3a\\u4e86\\u907f\\u514d <code>defer</code> \\u8bed\\u53e5\\u6267\\u884c\\u65f6\\u5c31\\u7acb\\u5373\\u5bf9 defer \\u8981\\u6267\\u884c\\u7684\\u51fd\\u6570\\u7684\\u53c2\\u6570\\u8fdb\\u884c\\u8ba1\\u7b97\\uff0c\\u53ef\\u4ee5\\u8003\\u8651\\u5c06\\u8981\\u6267\\u884c\\u7684\\u51fd\\u6570\\u653e\\u5230\\u95ed\\u5305\\u91cc\\u9762\\uff0c\\u7136\\u540e\\u901a\\u8fc7\\u6307\\u9488\\u4f20\\u9012\\u53c2\\u6570\\u7ed9\\u95ed\\u5305\\u5185\\u51fd\\u6570\\uff08\\u6216\\u8005\\u901a\\u8fc7\\u95ed\\u5305\\u6355\\u83b7\\u5916\\u90e8\\u53d8\\u91cf\\uff09\\uff0c\\u6765\\u89e3\\u51b3\\u8fd9\\u4e2a\\u95ee\\u9898\\u3002</p>\"},{\"location\":\"zh/#_6\",\"title\":\"\\u9519\\u8bef\\u7ba1\\u7406\",\"text\":\"\"},{\"location\":\"zh/#panicking-48\",\"title\":\"Panicking (#48)\",\"text\":\"<p>\\u4f7f\\u7528 <code>panic</code> \\u662f Go \\u4e2d\\u4e00\\u79cd\\u5904\\u7406\\u9519\\u8bef\\u7684\\u65b9\\u5f0f\\uff0c\\u4f46\\u662f\\u53ea\\u80fd\\u5728\\u9047\\u5230\\u4e0d\\u53ef\\u6062\\u590d\\u7684\\u9519\\u8bef\\u65f6\\u4f7f\\u7528\\uff0c\\u4f8b\\u5982\\uff1a\\u901a\\u77e5\\u5f00\\u53d1\\u4eba\\u5458\\u4e00\\u4e2a\\u5f3a\\u4f9d\\u8d56\\u7684\\u6a21\\u5757\\u52a0\\u8f7d\\u5931\\u8d25\\u4e86\\u3002</p>\"},{\"location\":\"zh/#error-49\",\"title\":\"\\u672a\\u8003\\u8651\\u4f55\\u65f6\\u624d\\u5e94\\u8be5\\u5305\\u88c5 error (#49)\",\"text\":\"<p>Wrapping\\uff08\\u5305\\u88c5\\uff09\\u9519\\u8bef\\u5141\\u8bb8\\u60a8\\u6807\\u8bb0\\u9519\\u8bef\\u3001\\u63d0\\u4f9b\\u989d\\u5916\\u7684\\u4e0a\\u4e0b\\u6587\\u4fe1\\u606f\\u3002\\u7136\\u800c\\uff0c\\u5305\\u88c5\\u9519\\u8bef\\u4f1a\\u521b\\u5efa\\u6f5c\\u5728\\u7684\\u8026\\u5408\\uff0c\\u56e0\\u4e3a\\u5b83\\u4f7f\\u5f97\\u539f\\u6765\\u7684\\u9519\\u8bef\\u5bf9\\u8c03\\u7528\\u8005\\u53ef\\u89c1\\u3002\\u5982\\u679c\\u60a8\\u60f3\\u8981\\u9632\\u6b62\\u8fd9\\u79cd\\u60c5\\u51b5\\uff0c\\u8bf7\\u4e0d\\u8981\\u4f7f\\u7528\\u5305\\u88c5\\u9519\\u8bef\\u7684\\u65b9\\u5f0f\\u3002</p>\"},{\"location\":\"zh/#50\",\"title\":\"\\u4e0d\\u6b63\\u786e\\u7684\\u9519\\u8bef\\u7c7b\\u578b\\u6bd4\\u8f83 (#50)\",\"text\":\"<p>\\u5982\\u679c\\u4f60\\u4f7f\\u7528 Go 1.13 \\u5f15\\u5165\\u7684\\u7279\\u6027 <code>fmt.Errorf</code> + <code>%w</code> \\u6765\\u5305\\u88c5\\u4e00\\u4e2a\\u9519\\u8bef\\uff0c\\u5f53\\u8fdb\\u884c\\u9519\\u8bef\\u6bd4\\u8f83\\u65f6\\uff0c\\u5982\\u679c\\u60f3\\u5224\\u65ad\\u8be5\\u5305\\u88c5\\u540e\\u7684\\u9519\\u8bef\\u662f\\u4e0d\\u662f\\u6307\\u5b9a\\u7684\\u9519\\u8bef\\u7c7b\\u578b\\uff0c\\u5c31\\u9700\\u8981\\u4f7f\\u7528 <code>errors.As</code>\\uff0c\\u5982\\u679c\\u60f3\\u5224\\u65ad\\u662f\\u4e0d\\u662f\\u6307\\u5b9a\\u7684 error \\u5bf9\\u8c61\\u5c31\\u9700\\u8981\\u7528 <code>errors.Is</code>\\u3002</p>\"},{\"location\":\"zh/#51\",\"title\":\"\\u4e0d\\u6b63\\u786e\\u7684\\u9519\\u8bef\\u5bf9\\u8c61\\u503c\\u6bd4\\u8f83 (#51)\",\"text\":\"<p>\\u89c1 #50.</p> <p>\\u4e3a\\u4e86\\u8868\\u8fbe\\u4e00\\u4e2a\\u9884\\u671f\\u5185\\u7684\\u9519\\u8bef\\uff0c\\u8bf7\\u4f7f\\u7528\\u9519\\u8bef\\u503c\\u7684\\u65b9\\u5f0f\\uff0c\\u5e76\\u901a\\u8fc7 <code>==</code> \\u6216\\u8005 <code>errors.Is</code> \\u6765\\u6bd4\\u8f83\\u3002\\u800c\\u5bf9\\u4e8e\\u610f\\u5916\\u9519\\u8bef\\uff0c\\u5219\\u5e94\\u4f7f\\u7528\\u7279\\u5b9a\\u7684\\u9519\\u8bef\\u7c7b\\u578b\\uff08\\u53ef\\u4ee5\\u901a\\u8fc7 <code>errors.As</code> \\u6765\\u6bd4\\u8f83\\uff09\\u3002</p>\"},{\"location\":\"zh/#52\",\"title\":\"\\u4e24\\u6b21\\u5904\\u7406\\u540c\\u4e00\\u4e2a\\u9519\\u8bef (#52)\",\"text\":\"<p>\\u5927\\u591a\\u6570\\u60c5\\u51b5\\u4e0b\\uff0c\\u9519\\u8bef\\u4ec5\\u9700\\u8981\\u5904\\u7406\\u4e00\\u6b21\\u3002\\u6253\\u5370\\u9519\\u8bef\\u65e5\\u5fd7\\u4e5f\\u662f\\u4e00\\u79cd\\u9519\\u8bef\\u5904\\u7406\\u3002\\u56e0\\u6b64\\uff0c\\u5f53\\u51fd\\u6570\\u5185\\u53d1\\u751f\\u9519\\u8bef\\u65f6\\uff0c\\u5e94\\u8be5\\u5728\\u6253\\u5370\\u65e5\\u5fd7\\u548c\\u8fd4\\u56de\\u9519\\u8bef\\u4e2d\\u9009\\u62e9\\u5176\\u4e2d\\u4e00\\u79cd\\u3002\\u5305\\u88c5\\u9519\\u8bef\\u4e5f\\u53ef\\u4ee5\\u63d0\\u4f9b\\u95ee\\u9898\\u53d1\\u751f\\u7684\\u989d\\u5916\\u4e0a\\u4e0b\\u6587\\u4fe1\\u606f\\uff0c\\u4e5f\\u5305\\u62ec\\u4e86\\u539f\\u6765\\u7684\\u9519\\u8bef\\uff08\\u53ef\\u8003\\u8651\\u4ea4\\u7ed9\\u8c03\\u7528\\u65b9\\u8d1f\\u8d23\\u6253\\u65e5\\u5fd7\\uff09\\u3002</p>\"},{\"location\":\"zh/#53\",\"title\":\"\\u4e0d\\u5904\\u7406\\u9519\\u8bef (#53)\",\"text\":\"<p>\\u4e0d\\u7ba1\\u662f\\u5728\\u51fd\\u6570\\u8c03\\u7528\\u65f6\\uff0c\\u8fd8\\u662f\\u5728\\u4e00\\u4e2a <code>defer</code> \\u51fd\\u6570\\u6267\\u884c\\u65f6\\uff0c\\u5982\\u679c\\u60f3\\u8981\\u5ffd\\u7565\\u4e00\\u4e2a\\u9519\\u8bef\\uff0c\\u5e94\\u8be5\\u663e\\u5f0f\\u5730\\u901a\\u8fc7 <code>_</code> \\u6765\\u5ffd\\u7565\\uff08\\u53ef\\u6ce8\\u660e\\u5ffd\\u7565\\u7684\\u539f\\u56e0\\uff09\\u3002\\u5426\\u5219\\uff0c\\u5c06\\u6765\\u7684\\u8bfb\\u8005\\u5c31\\u4f1a\\u611f\\u89c9\\u5230\\u56f0\\u60d1\\uff0c\\u5ffd\\u7565\\u8fd9\\u4e2a\\u9519\\u8bef\\u662f\\u6709\\u610f\\u4e3a\\u4e4b\\u8fd8\\u662f\\u65e0\\u610f\\u4e2d\\u6f0f\\u6389\\u4e86\\u3002</p>\"},{\"location\":\"zh/#defer-54\",\"title\":\"\\u4e0d\\u5904\\u7406 <code>defer</code> \\u4e2d\\u7684\\u9519\\u8bef (#54)\",\"text\":\"<p>\\u5927\\u591a\\u6570\\u60c5\\u51b5\\u4e0b\\uff0c\\u4f60\\u4e0d\\u5e94\\u8be5\\u5ffd\\u7565 <code>defer</code> \\u51fd\\u6570\\u6267\\u884c\\u65f6\\u8fd4\\u56de\\u7684\\u9519\\u8bef\\uff0c\\u6216\\u8005\\u663e\\u5f0f\\u5904\\u7406\\u5b83\\uff0c\\u6216\\u8005\\u5c06\\u5b83\\u4f20\\u9012\\u7ed9\\u8c03\\u7528\\u65b9\\u5904\\u7406\\uff0c\\u53ef\\u4ee5\\u6839\\u636e\\u60c5\\u666f\\u8fdb\\u884c\\u9009\\u62e9\\u3002\\u5982\\u679c\\u4f60\\u786e\\u5b9a\\u8981\\u5ffd\\u7565\\u8fd9\\u4e2a\\u9519\\u8bef\\uff0c\\u8bf7\\u663e\\u5f0f\\u4f7f\\u7528 <code>_</code> \\u6765\\u5ffd\\u7565\\u3002</p>\"},{\"location\":\"zh/#_7\",\"title\":\"\\u5e76\\u53d1\\u7f16\\u7a0b: \\u57fa\\u7840\",\"text\":\"\"},{\"location\":\"zh/#55\",\"title\":\"\\u6df7\\u6dc6\\u5e76\\u53d1\\u548c\\u5e76\\u884c (#55)\",\"text\":\"<p>\\u7406\\u89e3\\u5e76\\u53d1\\uff08concurrency\\uff09\\u3001\\u5e76\\u884c\\uff08parallelism\\uff09\\u4e4b\\u95f4\\u7684\\u672c\\u8d28\\u533a\\u522b\\u662f Go \\u5f00\\u53d1\\u4eba\\u5458\\u5fc5\\u987b\\u8981\\u638c\\u63e1\\u7684\\u3002\\u5e76\\u53d1\\u662f\\u5173\\u4e8e\\u7ed3\\u6784\\u8bbe\\u8ba1\\u4e0a\\u7684\\uff0c\\u5e76\\u884c\\u662f\\u5173\\u4e8e\\u5177\\u4f53\\u6267\\u884c\\u4e0a\\u7684\\u3002</p>\"},{\"location\":\"zh/#56\",\"title\":\"\\u8ba4\\u4e3a\\u5e76\\u53d1\\u603b\\u662f\\u66f4\\u5feb (#56)\",\"text\":\"<p>\\u8981\\u6210\\u4e3a\\u4e00\\u540d\\u719f\\u7ec3\\u7684\\u5f00\\u53d1\\u4eba\\u5458\\uff0c\\u60a8\\u5fc5\\u987b\\u610f\\u8bc6\\u5230\\u5e76\\u975e\\u6240\\u6709\\u573a\\u666f\\u4e0b\\u90fd\\u662f\\u5e76\\u53d1\\u7684\\u65b9\\u6848\\u66f4\\u5feb\\u3002\\u5bf9\\u4e8e\\u4efb\\u52a1\\u4e2d\\u7684\\u6700\\u5c0f\\u5de5\\u4f5c\\u8d1f\\u8f7d\\u90e8\\u5206\\uff0c\\u5bf9\\u5b83\\u4eec\\u8fdb\\u884c\\u5e76\\u884c\\u5316\\u5904\\u7406\\u5e76\\u4e0d\\u4e00\\u5b9a\\u5c31\\u6709\\u660e\\u663e\\u6536\\u76ca\\u6216\\u8005\\u6bd4\\u4e32\\u884c\\u5316\\u65b9\\u6848\\u66f4\\u5feb\\u3002\\u5bf9\\u4e32\\u884c\\u5316\\u3001\\u5e76\\u53d1\\u65b9\\u6848\\u8fdb\\u884c benchmark \\u6d4b\\u8bd5\\uff0c\\u662f\\u9a8c\\u8bc1\\u5047\\u8bbe\\u7684\\u597d\\u529e\\u6cd5\\u3002</p>\"},{\"location\":\"zh/#channels-mutexes-57\",\"title\":\"\\u4e0d\\u6e05\\u695a\\u4f55\\u65f6\\u4f7f\\u7528 channels \\u6216 mutexes (#57)\",\"text\":\"<p>\\u4e86\\u89e3 goroutine \\u4e4b\\u95f4\\u7684\\u4ea4\\u4e92\\u4e5f\\u53ef\\u4ee5\\u5728\\u9009\\u62e9\\u4f7f\\u7528 channels \\u6216 mutexes \\u65f6\\u6709\\u6240\\u5e2e\\u52a9\\u3002\\u4e00\\u822c\\u6765\\u8bf4\\uff0c\\u5e76\\u884c\\u7684 goroutine \\u9700\\u8981\\u540c\\u6b65\\uff0c\\u56e0\\u6b64\\u9700\\u8981\\u4f7f\\u7528 mutexes\\u3002\\u76f8\\u53cd\\uff0c\\u5e76\\u53d1\\u7684 goroutine \\u901a\\u5e38\\u9700\\u8981\\u534f\\u8c03\\u548c\\u7f16\\u6392\\uff0c\\u56e0\\u6b64\\u9700\\u8981\\u4f7f\\u7528 channels\\u3002</p>\"},{\"location\":\"zh/#vs-go-58\",\"title\":\"\\u4e0d\\u660e\\u767d\\u7ade\\u6001\\u95ee\\u9898 (\\u6570\\u636e\\u7ade\\u6001 vs. \\u7ade\\u6001\\u6761\\u4ef6\\u548c Go \\u5185\\u5b58\\u6a21\\u578b) (#58)\",\"text\":\"<p>\\u638c\\u63e1\\u5e76\\u53d1\\u610f\\u5473\\u7740\\u8981\\u8ba4\\u8bc6\\u5230\\u6570\\u636e\\u7ade\\u4e89\\uff08data races\\uff09\\u548c\\u7ade\\u6001\\u6761\\u4ef6\\uff08race conditions\\uff09\\u662f\\u4e24\\u4e2a\\u4e0d\\u540c\\u7684\\u6982\\u5ff5\\u3002\\u6570\\u636e\\u7ade\\u4e89\\uff0c\\u6307\\u7684\\u662f\\u6709\\u591a\\u4e2a goroutines \\u540c\\u65f6\\u8bbf\\u95ee\\u76f8\\u540c\\u5185\\u5b58\\u533a\\u57df\\u65f6\\uff0c\\u7f3a\\u4e4f\\u5fc5\\u8981\\u7684\\u540c\\u6b65\\u63a7\\u5236\\uff0c\\u4e14\\u5176\\u4e2d\\u81f3\\u5c11\\u6709\\u4e00\\u4e2a goroutine \\u6267\\u884c\\u7684\\u662f\\u5199\\u64cd\\u4f5c\\u3002\\u540c\\u65f6\\u8981\\u8ba4\\u8bc6\\u5230\\uff0c\\u6ca1\\u6709\\u53d1\\u751f\\u6570\\u636e\\u7ade\\u4e89\\u4e0d\\u4ee3\\u8868\\u7a0b\\u5e8f\\u7684\\u6267\\u884c\\u662f\\u786e\\u5b9a\\u6027\\u7684\\u3001\\u6ca1\\u95ee\\u9898\\u7684\\u3002\\u5f53\\u5728\\u67d0\\u4e2a\\u7279\\u5b9a\\u7684\\u64cd\\u4f5c\\u987a\\u5e8f\\u6216\\u8005\\u7279\\u5b9a\\u7684\\u4e8b\\u4ef6\\u53d1\\u751f\\u987a\\u5e8f\\u4e0b\\uff0c\\u5982\\u679c\\u6700\\u7ec8\\u7684\\u884c\\u4e3a\\u662f\\u4e0d\\u53ef\\u63a7\\u7684\\uff0c\\u8fd9\\u5c31\\u662f\\u7ade\\u6001\\u6761\\u4ef6\\u3002</p> <p>ps\\uff1a\\u6570\\u636e\\u7ade\\u4e89\\u662f\\u7ade\\u6001\\u6761\\u4ef6\\u7684\\u5b50\\u96c6\\uff0c\\u7ade\\u6001\\u6761\\u4ef6\\u4e0d\\u4ec5\\u5c40\\u9650\\u4e8e\\u8bbf\\u5b58\\u672a\\u540c\\u6b65\\uff0c\\u5b83\\u53ef\\u4ee5\\u53d1\\u751f\\u5728\\u66f4\\u9ad8\\u7684\\u5c42\\u9762\\u3002<code>go test -race</code> \\u68c0\\u6d4b\\u7684\\u662f\\u6570\\u636e\\u7ade\\u4e89\\uff0c\\u9700\\u8981\\u540c\\u6b65\\u6765\\u89e3\\u51b3\\uff0c\\u800c\\u5f00\\u53d1\\u8005\\u8fd8\\u9700\\u8981\\u5173\\u6ce8\\u9762\\u66f4\\u5e7f\\u7684\\u7ade\\u6001\\u6761\\u4ef6\\uff0c\\u5b83\\u9700\\u8981\\u5bf9\\u591a\\u4e2a goroutines \\u7684\\u6267\\u884c\\u8fdb\\u884c\\u7f16\\u6392\\u3002</p> <p>\\u7406\\u89e3 Go \\u7684\\u5185\\u5b58\\u6a21\\u578b\\u4ee5\\u53ca\\u6709\\u5173\\u987a\\u5e8f\\u548c\\u540c\\u6b65\\u7684\\u5e95\\u5c42\\u4fdd\\u8bc1\\u662f\\u9632\\u6b62\\u53ef\\u80fd\\u7684\\u6570\\u636e\\u7ade\\u4e89\\u548c\\u7ade\\u6001\\u6761\\u4ef6\\u7684\\u5173\\u952e\\u3002</p>\"},{\"location\":\"zh/#59\",\"title\":\"\\u4e0d\\u7406\\u89e3\\u4e0d\\u540c\\u5de5\\u4f5c\\u8d1f\\u8f7d\\u7c7b\\u578b\\u5bf9\\u5e76\\u53d1\\u7684\\u5f71\\u54cd (#59)\",\"text\":\"<p>\\u5f53\\u521b\\u5efa\\u4e00\\u5b9a\\u6570\\u91cf\\u7684 goroutines \\u65f6\\uff0c\\u9700\\u8981\\u8003\\u8651\\u5de5\\u4f5c\\u8d1f\\u8f7d\\u7684\\u7c7b\\u578b\\u3002\\u5982\\u679c\\u5de5\\u4f5c\\u8d1f\\u8f7d\\u662f CPU \\u5bc6\\u96c6\\u578b\\u7684\\uff0c\\u90a3\\u4e48 goroutines \\u6570\\u91cf\\u5e94\\u8be5\\u63a5\\u8fd1\\u4e8e <code>GOMAXPROCS</code> \\u7684\\u503c\\uff08\\u8be5\\u503c\\u53d6\\u51b3\\u4e8e\\u4e3b\\u673a\\u5904\\u7406\\u5668\\u6838\\u5fc3\\u6570\\uff09\\u3002\\u5982\\u679c\\u5de5\\u4f5c\\u8d1f\\u8f7d\\u662f IO \\u5bc6\\u96c6\\u578b\\u7684\\uff0cgoroutines \\u6570\\u91cf\\u5c31\\u9700\\u8981\\u8003\\u8651\\u591a\\u79cd\\u56e0\\u7d20\\uff0c\\u6bd4\\u5982\\u5916\\u90e8\\u7cfb\\u7edf\\uff08\\u8003\\u8651\\u8bf7\\u6c42\\u3001\\u54cd\\u5e94\\u901f\\u7387\\uff09\\u3002</p>\"},{\"location\":\"zh/#go-contexts-60\",\"title\":\"\\u8bef\\u89e3\\u4e86 Go contexts (#60)\",\"text\":\"<p>Go \\u7684\\u4e0a\\u4e0b\\u6587\\uff08context\\uff09\\u4e5f\\u662f Go \\u5e76\\u53d1\\u7f16\\u7a0b\\u7684\\u57fa\\u77f3\\u4e4b\\u4e00\\u3002\\u4e0a\\u4e0b\\u6587\\u5141\\u8bb8\\u60a8\\u643a\\u5e26\\u622a\\u6b62\\u65f6\\u95f4\\u3001\\u53d6\\u6d88\\u4fe1\\u53f7\\u548c\\u952e\\u503c\\u5217\\u8868\\u3002</p>\"},{\"location\":\"zh/#_8\",\"title\":\"\\u5e76\\u53d1\\u7f16\\u7a0b: \\u5b9e\\u8df5\",\"text\":\"\"},{\"location\":\"zh/#context-61\",\"title\":\"\\u4f20\\u9012\\u4e0d\\u5408\\u9002\\u7684 context (#61)\",\"text\":\"<p>\\u5f53\\u6211\\u4eec\\u4f20\\u9012\\u4e86\\u4e00\\u4e2a context\\uff0c\\u6211\\u4eec\\u9700\\u8981\\u77e5\\u9053\\u8fd9\\u4e2a context \\u4ec0\\u4e48\\u65f6\\u5019\\u53ef\\u4ee5\\u88ab\\u53d6\\u6d88\\uff0c\\u8fd9\\u70b9\\u5f88\\u91cd\\u8981\\uff0c\\u4f8b\\u5982\\uff1a\\u4e00\\u4e2a HTTP \\u8bf7\\u6c42\\u5904\\u7406\\u5668\\u5728\\u53d1\\u9001\\u5b8c\\u54cd\\u5e94\\u540e\\u53d6\\u6d88 context\\u3002</p> <p>ps: \\u5b9e\\u9645\\u4e0a context \\u8868\\u8fbe\\u7684\\u662f\\u4e00\\u4e2a\\u52a8\\u4f5c\\u53ef\\u4ee5\\u6301\\u7eed\\u591a\\u4e45\\u4e4b\\u540e\\u88ab\\u505c\\u6b62\\u3002</p>\"},{\"location\":\"zh/#goroutine-62\",\"title\":\"\\u542f\\u52a8\\u4e86\\u4e00\\u4e2a goroutine \\u4f46\\u662f\\u4e0d\\u77e5\\u9053\\u5b83\\u4f55\\u65f6\\u4f1a\\u505c\\u6b62 (#62)\",\"text\":\"<p>\\u907f\\u514d goroutine \\u6cc4\\u6f0f\\uff0c\\u8981\\u6709\\u8fd9\\u79cd\\u610f\\u8bc6\\uff0c\\u5f53\\u521b\\u5efa\\u5e76\\u542f\\u52a8\\u4e00\\u4e2a goroutine \\u7684\\u65f6\\u5019\\uff0c\\u5e94\\u8be5\\u6709\\u5bf9\\u5e94\\u7684\\u8bbe\\u8ba1\\u8ba9\\u5b83\\u80fd\\u6b63\\u5e38\\u9000\\u51fa\\u3002</p>\"},{\"location\":\"zh/#goroutines-63\",\"title\":\"\\u4e0d\\u6ce8\\u610f\\u5904\\u7406 goroutines \\u548c\\u5faa\\u73af\\u4e2d\\u7684\\u8fed\\u4ee3\\u53d8\\u91cf (#63)\",\"text\":\"<p>\\u4e3a\\u4e86\\u907f\\u514d goroutines \\u548c\\u5faa\\u73af\\u4e2d\\u7684\\u8fed\\u4ee3\\u53d8\\u91cf\\u95ee\\u9898\\uff0c\\u53ef\\u4ee5\\u8003\\u8651\\u521b\\u5efa\\u5c40\\u90e8\\u53d8\\u91cf\\u5e76\\u5c06\\u8fed\\u4ee3\\u53d8\\u91cf\\u8d4b\\u503c\\u7ed9\\u5c40\\u90e8\\u53d8\\u91cf\\uff0c\\u6216\\u8005 goroutines \\u8c03\\u7528\\u5e26\\u53c2\\u6570\\u7684\\u51fd\\u6570\\uff0c\\u5c06\\u8fed\\u4ee3\\u53d8\\u91cf\\u503c\\u4f5c\\u4e3a\\u53c2\\u6570\\u503c\\u4f20\\u5165\\uff0c\\u6765\\u4ee3\\u66ff goroutines \\u8c03\\u7528\\u95ed\\u5305\\u3002</p>\"},{\"location\":\"zh/#select-channels-64\",\"title\":\"\\u4f7f\\u7528 select + channels \\u65f6\\u8bef\\u4ee5\\u4e3a\\u5206\\u652f\\u9009\\u62e9\\u987a\\u5e8f\\u662f\\u786e\\u5b9a\\u7684 (#64)\",\"text\":\"<p>\\u8981\\u660e\\u767d\\uff0c<code>select</code> \\u591a\\u4e2a channels \\u65f6\\uff0c\\u5982\\u679c\\u591a\\u4e2a channels \\u4e0a\\u7684\\u64cd\\u4f5c\\u90fd\\u5c31\\u7eea\\uff0c\\u90a3\\u4e48\\u4f1a\\u968f\\u673a\\u9009\\u62e9\\u4e00\\u4e2a <code>case</code> \\u5206\\u652f\\u6765\\u6267\\u884c\\uff0c\\u56e0\\u6b64\\u8981\\u907f\\u514d\\u6709\\u5206\\u652f\\u9009\\u62e9\\u987a\\u5e8f\\u662f\\u4ece\\u4e0a\\u5230\\u4e0b\\u7684\\u8fd9\\u79cd\\u9519\\u8bef\\u9884\\u8bbe\\uff0c\\u8fd9\\u53ef\\u80fd\\u4f1a\\u5bfc\\u81f4\\u8bbe\\u8ba1\\u4e0a\\u7684 bug\\u3002</p>\"},{\"location\":\"zh/#channels-65\",\"title\":\"\\u4e0d\\u6b63\\u786e\\u4f7f\\u7528\\u901a\\u77e5 channels (#65)\",\"text\":\"<p>\\u53d1\\u9001\\u901a\\u77e5\\u65f6\\u4f7f\\u7528 <code>chan struct{}</code> \\u7c7b\\u578b\\u3002</p> <p>ps: \\u5148\\u660e\\u767d\\u4ec0\\u4e48\\u662f\\u901a\\u77e5 channels\\uff0c\\u4e00\\u4e2a\\u901a\\u77e5 channels \\u6307\\u7684\\u662f\\u53ea\\u662f\\u7528\\u6765\\u505a\\u901a\\u77e5\\uff0c\\u800c\\u5176\\u4e2d\\u4f20\\u9012\\u7684\\u6570\\u636e\\u6ca1\\u6709\\u610f\\u4e49\\uff0c\\u6216\\u8005\\u7406\\u89e3\\u6210\\u4e0d\\u4f20\\u9012\\u6570\\u636e\\u7684 channels\\uff0c\\u8fd9\\u79cd\\u79f0\\u4e3a\\u901a\\u77e5 channels\\u3002\\u5176\\u4e2d\\u4f20\\u9012\\u7684\\u6570\\u636e\\u7684\\u7c7b\\u578b\\u4e3a struct{} \\u66f4\\u5408\\u9002\\u3002</p>\"},{\"location\":\"zh/#nil-channels-66\",\"title\":\"\\u4e0d\\u4f7f\\u7528 nil channels (#66)\",\"text\":\"<p>\\u4f7f\\u7528 nil channels \\u5e94\\u8be5\\u662f\\u5e76\\u53d1\\u5904\\u7406\\u65b9\\u5f0f\\u4e2d\\u7684\\u4e00\\u90e8\\u5206\\uff0c\\u4f8b\\u5982\\uff0c\\u5b83\\u80fd\\u591f\\u5e2e\\u52a9\\u7981\\u7528 <code>select</code> \\u8bed\\u53e5\\u4e2d\\u7684\\u7279\\u5b9a\\u7684\\u5206\\u652f\\u3002</p>\"},{\"location\":\"zh/#channel-size-67\",\"title\":\"\\u4e0d\\u6e05\\u695a\\u8be5\\u5982\\u4f55\\u786e\\u5b9a channel size (#67)\",\"text\":\"<p>\\u6839\\u636e\\u6307\\u5b9a\\u7684\\u573a\\u666f\\u4ed4\\u7ec6\\u8bc4\\u4f30\\u5e94\\u8be5\\u4f7f\\u7528\\u54ea\\u4e00\\u79cd channel \\u7c7b\\u578b\\uff08\\u5e26\\u7f13\\u51b2\\u7684\\uff0c\\u4e0d\\u5e26\\u7f13\\u51b2\\u7684\\uff09\\u3002\\u53ea\\u6709\\u4e0d\\u5e26\\u7f13\\u51b2\\u7684 channels \\u53ef\\u4ee5\\u63d0\\u4f9b\\u5f3a\\u540c\\u6b65\\u4fdd\\u8bc1\\u3002</p> <p>\\u4f7f\\u7528\\u5e26\\u7f13\\u51b2\\u7684 channels \\u65f6\\u5982\\u679c\\u4e0d\\u786e\\u5b9a size \\u8be5\\u5982\\u4f55\\u8bbe\\u7f6e\\uff0c\\u53ef\\u4ee5\\u5148\\u8bbe\\u4e3a 1\\uff0c\\u5982\\u679c\\u6709\\u5408\\u7406\\u7684\\u7406\\u7531\\u518d\\u53bb\\u6307\\u5b9a channels size\\u3002</p> <p>ps: \\u6839\\u636e disruptor \\u8fd9\\u4e2a\\u9ad8\\u6027\\u80fd\\u5185\\u5b58\\u6d88\\u606f\\u961f\\u5217\\u7684\\u5b9e\\u8df5\\uff0c\\u5728\\u67d0\\u79cd\\u8bfb\\u5199 pacing \\u4e0b\\uff0c\\u961f\\u5217\\u8981\\u4e48\\u6ee1\\u8981\\u4e48\\u7a7a\\uff0c\\u4e0d\\u5927\\u53ef\\u80fd\\u5904\\u4e8e\\u67d0\\u79cd\\u4ecb\\u4e8e\\u4e2d\\u95f4\\u7684\\u7a33\\u6001\\u3002</p>\"},{\"location\":\"zh/#etcd-68\",\"title\":\"\\u5fd8\\u8bb0\\u4e86\\u5b57\\u7b26\\u4e32\\u683c\\u5f0f\\u5316\\u53ef\\u80fd\\u5e26\\u6765\\u7684\\u526f\\u4f5c\\u7528\\uff08\\u4f8b\\u5982 etcd \\u6570\\u636e\\u7ade\\u4e89\\u548c\\u6b7b\\u9501\\uff09(#68)\",\"text\":\"<p>\\u610f\\u8bc6\\u5230\\u5b57\\u7b26\\u4e32\\u683c\\u5f0f\\u5316\\u53ef\\u80fd\\u4f1a\\u5bfc\\u81f4\\u8c03\\u7528\\u73b0\\u6709\\u51fd\\u6570\\uff0c\\u8fd9\\u610f\\u5473\\u7740\\u9700\\u8981\\u6ce8\\u610f\\u53ef\\u80fd\\u7684\\u6b7b\\u9501\\u548c\\u5176\\u4ed6\\u6570\\u636e\\u7ade\\u4e89\\u95ee\\u9898\\u3002</p> <p>ps: \\u6838\\u5fc3\\u662f\\u8981\\u5173\\u6ce8 <code>fmt.Sprintf</code> + <code>%v</code> \\u8fdb\\u884c\\u5b57\\u7b26\\u4e32\\u683c\\u5f0f\\u5316\\u65f6 <code>%v</code> \\u5177\\u4f53\\u5230\\u4e0d\\u540c\\u7684\\u7c7b\\u578b\\u503c\\u65f6\\uff0c\\u5b9e\\u9645\\u4e0a\\u6267\\u884c\\u7684\\u64cd\\u4f5c\\u662f\\u4ec0\\u4e48\\u3002\\u6bd4\\u5982 <code>%v</code> \\u8fd9\\u4e2a placeholder \\u5bf9\\u5e94\\u7684\\u503c\\u662f\\u4e00\\u4e2a <code>context.Context</code>\\uff0c\\u90a3\\u4e48\\u4f1a\\u5c31\\u904d\\u5386\\u5176\\u901a\\u8fc7 <code>context.WithValue</code> \\u9644\\u52a0\\u5728\\u5176\\u4e2d\\u7684 values\\uff0c\\u8fd9\\u4e2a\\u8fc7\\u7a0b\\u53ef\\u80fd\\u6d89\\u53ca\\u5230\\u6570\\u636e\\u7ade\\u4e89\\u95ee\\u9898\\u3002\\u4e66\\u4e2d\\u63d0\\u53ca\\u7684\\u53e6\\u4e00\\u4e2a\\u5bfc\\u81f4\\u6b7b\\u9501\\u7684\\u6848\\u4f8b\\u672c\\u8d28\\u4e0a\\u4e5f\\u662f\\u4e00\\u6837\\u7684\\u95ee\\u9898\\uff0c\\u53ea\\u4e0d\\u8fc7\\u53c8\\u989d\\u5916\\u7275\\u626f\\u5230\\u4e86 <code>sync.RWMutex</code> \\u4e0d\\u53ef\\u91cd\\u5165\\u7684\\u95ee\\u9898\\u3002</p>\"},{\"location\":\"zh/#append-69\",\"title\":\"\\u4f7f\\u7528 append \\u4e0d\\u5f53\\u5bfc\\u81f4\\u6570\\u636e\\u7ade\\u4e89 (#69)\",\"text\":\"<p>\\u8c03\\u7528 <code>append</code> \\u4e0d\\u603b\\u662f\\u6ca1\\u6709\\u6570\\u636e\\u7ade\\u4e89\\u7684\\uff0c\\u56e0\\u6b64\\u4e0d\\u8981\\u5728\\u4e00\\u4e2a\\u5171\\u4eab\\u7684 <code>slice</code> \\u4e0a\\u5e76\\u53d1\\u5730\\u6267\\u884c <code>append</code>\\u3002</p>\"},{\"location\":\"zh/#mutexes-slicesmaps-70\",\"title\":\"\\u8bef\\u7528 mutexes \\u548c slices\\u3001maps (#70)\",\"text\":\"<p>\\u8bf7\\u8bb0\\u4f4f slices \\u548c maps \\u662f\\u5f15\\u7528\\u7c7b\\u578b\\uff0c\\u6709\\u52a9\\u4e8e\\u907f\\u514d\\u5e38\\u89c1\\u7684\\u6570\\u636e\\u7ade\\u4e89\\u95ee\\u9898\\u3002</p> <p>ps: \\u8fd9\\u91cc\\u5b9e\\u9645\\u662f\\u56e0\\u4e3a\\u9519\\u8bef\\u7406\\u89e3\\u4e86 slices \\u548c maps\\uff0c\\u5bfc\\u81f4\\u5199\\u51fa\\u4e86\\u9519\\u8bef\\u5730\\u62f7\\u8d1d slices \\u548c maps \\u7684\\u4ee3\\u7801\\uff0c\\u8fdb\\u800c\\u5bfc\\u81f4\\u9501\\u4fdd\\u62a4\\u65e0\\u6548\\u3001\\u51fa\\u73b0\\u6570\\u636e\\u7ade\\u4e89\\u95ee\\u9898\\u3002</p>\"},{\"location\":\"zh/#syncwaitgroup-71\",\"title\":\"\\u8bef\\u7528 <code>sync.WaitGroup</code> (#71)\",\"text\":\"<p>\\u6b63\\u786e\\u5730\\u4f7f\\u7528 <code>sync.WaitGroup</code> \\u9700\\u8981\\u5728\\u542f\\u52a8 goroutines \\u4e4b\\u524d\\u5148\\u8c03\\u7528 <code>Add</code> \\u65b9\\u6cd5\\u3002</p>\"},{\"location\":\"zh/#synccond-72\",\"title\":\"\\u5fd8\\u8bb0\\u4f7f\\u7528 <code>sync.Cond</code> (#72)\",\"text\":\"<p>\\u4f60\\u53ef\\u4ee5\\u4f7f\\u7528 <code>sync.Cond</code> \\u5411\\u591a\\u4e2a goroutines \\u53d1\\u9001\\u91cd\\u590d\\u7684\\u901a\\u77e5\\u3002</p>\"},{\"location\":\"zh/#errgroup-73\",\"title\":\"\\u4e0d\\u4f7f\\u7528 <code>errgroup</code> (#73)\",\"text\":\"<p>\\u4f60\\u53ef\\u4ee5\\u4f7f\\u7528 <code>errgroup</code> \\u5305\\u6765\\u540c\\u6b65\\u4e00\\u7ec4 goroutines \\u5e76\\u5904\\u7406\\u9519\\u8bef\\u548c\\u4e0a\\u4e0b\\u6587\\u3002</p>\"},{\"location\":\"zh/#sync-74\",\"title\":\"\\u62f7\\u8d1d\\u4e00\\u4e2a <code>sync</code> \\u4e0b\\u7684\\u7c7b\\u578b (#74)\",\"text\":\"<p><code>sync</code> \\u5305\\u4e0b\\u7684\\u7c7b\\u578b\\u4e0d\\u5e94\\u8be5\\u88ab\\u62f7\\u8d1d\\u3002</p>\"},{\"location\":\"zh/#_9\",\"title\":\"\\u6807\\u51c6\\u5e93\",\"text\":\"\"},{\"location\":\"zh/#timeduration-75\",\"title\":\"\\u4f7f\\u7528\\u4e86\\u9519\\u8bef\\u7684 time.Duration (#75)\",\"text\":\"<p>\\u6ce8\\u610f\\u6709\\u4e9b\\u51fd\\u6570\\u63a5\\u6536\\u4e00\\u4e2a <code>time.Duration</code> \\u7c7b\\u578b\\u7684\\u53c2\\u6570\\u65f6\\uff0c\\u5c3d\\u7ba1\\u76f4\\u63a5\\u4f20\\u9012\\u4e00\\u4e2a\\u6574\\u6570\\u662f\\u53ef\\u4ee5\\u7684\\uff0c\\u4f46\\u6700\\u597d\\u8fd8\\u662f\\u4f7f\\u7528 time API \\u4e2d\\u7684\\u65b9\\u6cd5\\u6765\\u4f20\\u9012 duration\\uff0c\\u4ee5\\u907f\\u514d\\u53ef\\u80fd\\u9020\\u6210\\u7684\\u56f0\\u60d1\\u548c bug\\u3002</p> <p>ps: \\u91cd\\u70b9\\u662f\\u6ce8\\u610f time.Duration \\u5b9a\\u4e49\\u7684\\u662f nanoseconds \\u6570\\u3002</p>\"},{\"location\":\"zh/#timeafter-76\",\"title\":\"<code>time.After</code> \\u548c\\u5185\\u5b58\\u6cc4\\u6f0f (#76)\",\"text\":\"<p>\\u907f\\u514d\\u5728\\u91cd\\u590d\\u6267\\u884c\\u5f88\\u591a\\u6b21\\u7684\\u51fd\\u6570\\uff08\\u5982\\u5faa\\u73af\\u4e2d\\u6216 HTTP \\u5904\\u7406\\u51fd\\u6570\\uff09\\u4e2d\\u8c03\\u7528 <code>time.After</code>\\uff0c\\u8fd9\\u53ef\\u4ee5\\u907f\\u514d\\u5185\\u5b58\\u5cf0\\u503c\\u6d88\\u8017\\u3002\\u7531 <code>time.After</code> \\u521b\\u5efa\\u7684\\u8d44\\u6e90\\u4ec5\\u5728\\u8ba1\\u65f6\\u5668\\u8d85\\u65f6\\u624d\\u4f1a\\u88ab\\u91ca\\u653e\\u3002</p>\"},{\"location\":\"zh/#json-77\",\"title\":\"JSON \\u5904\\u7406\\u4e2d\\u7684\\u5e38\\u89c1\\u9519\\u8bef (#77)\",\"text\":\"<ul> <li>\\u7c7b\\u578b\\u5d4c\\u5957\\u5bfc\\u81f4\\u7684\\u9884\\u6599\\u5916\\u7684\\u884c\\u4e3a</li> </ul> <p>\\u8981\\u5f53\\u5fc3\\u5728 Go \\u7ed3\\u6784\\u4f53\\u4e2d\\u5d4c\\u5165\\u5b57\\u6bb5\\uff0c\\u8fd9\\u6837\\u505a\\u53ef\\u80fd\\u4f1a\\u5bfc\\u81f4\\u8bf8\\u5982\\u5d4c\\u5165\\u7684 <code>time.Time</code> \\u5b57\\u6bb5\\u5b9e\\u73b0 <code>json.Marshaler</code> \\u63a5\\u53e3\\uff0c\\u4ece\\u800c\\u8986\\u76d6\\u9ed8\\u8ba4\\u7684 JSON \\u5e8f\\u5217\\u3002</p> <ul> <li>JSON \\u548c\\u5355\\u8c03\\u65f6\\u949f</li> </ul> <p>\\u5f53\\u5bf9\\u4e24\\u4e2a <code>time.Time</code> \\u7c7b\\u578b\\u503c\\u8fdb\\u884c\\u6bd4\\u8f83\\u65f6\\uff0c\\u9700\\u8981\\u8bb0\\u4f4f <code>time.Time</code> \\u5305\\u542b\\u4e86\\u4e00\\u4e2a\\u5899\\u4e0a\\u65f6\\u949f\\uff08wall clock\\uff09\\u548c\\u4e00\\u4e2a\\u5355\\u8c03\\u65f6\\u949f \\uff08monotonic clock\\uff09\\uff0c\\u800c\\u4f7f\\u7528 <code>==</code> \\u8fd0\\u7b97\\u7b26\\u8fdb\\u884c\\u6bd4\\u8f83\\u65f6\\u4f1a\\u540c\\u65f6\\u6bd4\\u8f83\\u8fd9\\u4e24\\u4e2a\\u3002</p> <ul> <li>Map \\u952e\\u5bf9\\u5e94\\u503c\\u4e3a <code>any</code></li> </ul> <p>\\u5f53\\u63d0\\u4f9b\\u4e00\\u4e2a map \\u7528\\u6765 unmarshal JSON \\u6570\\u636e\\u65f6\\uff0c\\u4e3a\\u4e86\\u907f\\u514d\\u4e0d\\u786e\\u5b9a\\u7684 value \\u7ed3\\u6784\\u6211\\u4eec\\u4f1a\\u4f7f\\u7528 <code>any</code> \\u6765\\u4f5c\\u4e3a value \\u7684\\u7c7b\\u578b\\u800c\\u4e0d\\u662f\\u5b9a\\u4e49\\u4e00\\u4e2a struct\\uff0c\\u8fd9\\u79cd\\u60c5\\u51b5\\u4e0b\\u9700\\u8981\\u8bb0\\u5f97\\u6570\\u503c\\u9ed8\\u8ba4\\u4f1a\\u88ab\\u8f6c\\u6362\\u4e3a <code>float64</code>\\u3002</p>\"},{\"location\":\"zh/#sql-78\",\"title\":\"\\u5e38\\u89c1\\u7684 SQL \\u9519\\u8bef (#78)\",\"text\":\"<ul> <li>\\u5fd8\\u8bb0\\u4e86 <code>sql.Open</code> \\u5e76\\u6ca1\\u6709\\u4e0e db \\u670d\\u52a1\\u5668\\u5efa\\u7acb\\u5b9e\\u9645\\u8fde\\u63a5</li> </ul> <p>\\u9700\\u8981\\u8c03\\u7528 <code>Ping</code> \\u6216\\u8005 <code>PingContext</code> \\u65b9\\u6cd5\\u6765\\u6d4b\\u8bd5\\u914d\\u7f6e\\u5e76\\u786e\\u4fdd\\u6570\\u636e\\u5e93\\u662f\\u53ef\\u8fbe\\u7684\\u3002</p> <ul> <li>\\u5fd8\\u8bb0\\u4e86\\u4f7f\\u7528\\u8fde\\u63a5\\u6c60</li> </ul> <p>\\u4f5c\\u4e3a\\u751f\\u4ea7\\u7ea7\\u522b\\u7684\\u5e94\\u7528\\uff0c\\u8bbf\\u95ee\\u6570\\u636e\\u5e93\\u65f6\\u5e94\\u8be5\\u5173\\u6ce8\\u914d\\u7f6e\\u6570\\u636e\\u5e93\\u8fde\\u63a5\\u6c60\\u53c2\\u6570\\u3002</p> <ul> <li>\\u6ca1\\u6709\\u4f7f\\u7528 prepared \\u8bed\\u53e5</li> </ul> <p>\\u4f7f\\u7528 SQL prepared \\u8bed\\u53e5\\u80fd\\u591f\\u8ba9\\u67e5\\u8be2\\u66f4\\u52a0\\u9ad8\\u6548\\u548c\\u5b89\\u5168\\u3002</p> <ul> <li>\\u8bef\\u5904\\u7406 null \\u503c</li> </ul> <p>\\u4f7f\\u7528 <code>sql.NullXXX</code> \\u7c7b\\u578b\\u5904\\u7406\\u8868\\u4e2d\\u7684\\u53ef\\u7a7a\\u5217\\u3002</p> <ul> <li>\\u4e0d\\u5904\\u7406\\u884c\\u8fed\\u4ee3\\u65f6\\u7684\\u9519\\u8bef</li> </ul> <p>\\u8c03\\u7528 <code>sql.Rows</code> \\u7684 <code>Err</code> \\u65b9\\u6cd5\\u6765\\u786e\\u4fdd\\u5728\\u51c6\\u5907\\u4e0b\\u4e00\\u4e2a\\u884c\\u65f6\\u6ca1\\u6709\\u9057\\u6f0f\\u9519\\u8bef\\u3002</p>\"},{\"location\":\"zh/#http-sqlrows-osfile-79\",\"title\":\"\\u4e0d\\u5173\\u95ed\\u4e34\\u65f6\\u8d44\\u6e90\\uff08HTTP \\u8bf7\\u6c42\\u4f53\\u3001<code>sql.Rows</code> \\u548c <code>os.File</code>\\uff09 (#79)\",\"text\":\"<p>\\u6700\\u7ec8\\u8981\\u6ce8\\u610f\\u5173\\u95ed\\u6240\\u6709\\u5b9e\\u73b0 <code>io.Closer</code> \\u63a5\\u53e3\\u7684\\u7ed3\\u6784\\u4f53\\uff0c\\u4ee5\\u907f\\u514d\\u53ef\\u80fd\\u7684\\u6cc4\\u6f0f\\u3002</p>\"},{\"location\":\"zh/#http-80\",\"title\":\"\\u54cd\\u5e94 HTTP \\u8bf7\\u6c42\\u540e\\u6ca1\\u6709\\u8fd4\\u56de\\u8bed\\u53e5 (#80)\",\"text\":\"<p>\\u4e3a\\u4e86\\u907f\\u514d\\u5728 HTTP \\u5904\\u7406\\u51fd\\u6570\\u4e2d\\u51fa\\u73b0\\u67d0\\u4e9b\\u610f\\u5916\\u7684\\u95ee\\u9898\\uff0c\\u5982\\u679c\\u60f3\\u5728\\u53d1\\u751f <code>http.Error</code> \\u540e\\u8ba9 HTTP \\u5904\\u7406\\u51fd\\u6570\\u505c\\u6b62\\uff0c\\u90a3\\u4e48\\u5c31\\u4e0d\\u8981\\u5fd8\\u8bb0\\u4f7f\\u7528 <code>return</code> \\u8bed\\u53e5\\u6765\\u963b\\u6b62\\u540e\\u7eed\\u4ee3\\u7801\\u7684\\u6267\\u884c\\u3002</p>\"},{\"location\":\"zh/#http-client-server-81\",\"title\":\"\\u76f4\\u63a5\\u4f7f\\u7528\\u9ed8\\u8ba4\\u7684 HTTP client \\u548c server (#81)\",\"text\":\"<p>\\u5bf9\\u4e8e\\u751f\\u4ea7\\u7ea7\\u522b\\u7684\\u5e94\\u7528\\uff0c\\u4e0d\\u8981\\u4f7f\\u7528\\u9ed8\\u8ba4\\u7684 HTTP client \\u548c server \\u5b9e\\u73b0\\u3002\\u8fd9\\u4e9b\\u5b9e\\u73b0\\u7f3a\\u5c11\\u8d85\\u65f6\\u548c\\u751f\\u4ea7\\u73af\\u5883\\u4e2d\\u5e94\\u8be5\\u5f3a\\u5236\\u4f7f\\u7528\\u7684\\u884c\\u4e3a\\u3002</p>\"},{\"location\":\"zh/#_10\",\"title\":\"\\u6d4b\\u8bd5\",\"text\":\"\"},{\"location\":\"zh/#build-tags-82\",\"title\":\"\\u4e0d\\u5bf9\\u6d4b\\u8bd5\\u8fdb\\u884c\\u5206\\u7c7b \\uff08build tags, \\u73af\\u5883\\u53d8\\u91cf\\uff0c\\u77ed\\u6a21\\u5f0f\\uff09(#82)\",\"text\":\"<p>\\u5bf9\\u6d4b\\u8bd5\\u8fdb\\u884c\\u5fc5\\u8981\\u7684\\u5206\\u7c7b\\uff0c\\u53ef\\u4ee5\\u501f\\u52a9 build tags\\u3001\\u73af\\u5883\\u53d8\\u91cf\\u4ee5\\u53ca\\u77ed\\u6a21\\u5f0f\\uff0c\\u6765\\u4f7f\\u5f97\\u6d4b\\u8bd5\\u8fc7\\u7a0b\\u66f4\\u52a0\\u9ad8\\u6548\\u3002\\u4f60\\u53ef\\u4ee5\\u4f7f\\u7528 build tags \\u6216\\u73af\\u5883\\u53d8\\u91cf\\u6765\\u521b\\u5efa\\u6d4b\\u8bd5\\u7c7b\\u522b\\uff08\\u4f8b\\u5982\\u5355\\u5143\\u6d4b\\u8bd5\\u4e0e\\u96c6\\u6210\\u6d4b\\u8bd5\\uff09\\uff0c\\u5e76\\u533a\\u5206\\u77ed\\u6d4b\\u8bd5\\u4e0e\\u957f\\u65f6\\u95f4\\u6d4b\\u8bd5\\uff0c\\u6765\\u51b3\\u5b9a\\u6267\\u884c\\u54ea\\u79cd\\u7c7b\\u578b\\u7684\\u3002</p> <p>ps: \\u4e86\\u89e3\\u4e0b go build tags\\uff0c\\u4ee5\\u53ca <code>go test -short</code>\\u3002</p>\"},{\"location\":\"zh/#race-83\",\"title\":\"\\u4e0d\\u6253\\u5f00 race \\u5f00\\u5173 (#83)\",\"text\":\"<p>\\u6253\\u5f00 <code>-race</code> \\u5f00\\u5173\\u5728\\u7f16\\u5199\\u5e76\\u53d1\\u5e94\\u7528\\u65f6\\u975e\\u5e38\\u91cd\\u8981\\u3002\\u8fd9\\u80fd\\u5e2e\\u52a9\\u4f60\\u6355\\u83b7\\u53ef\\u80fd\\u7684\\u6570\\u636e\\u7ade\\u4e89\\uff0c\\u4ece\\u800c\\u907f\\u514d\\u8f6f\\u4ef6 bug\\u3002</p>\"},{\"location\":\"zh/#parallel-shuffle-84\",\"title\":\"\\u4e0d\\u6253\\u5f00\\u6d4b\\u8bd5\\u7684\\u6267\\u884c\\u6a21\\u5f0f\\u5f00\\u5173 (parallel \\u548c shuffle) (#84)\",\"text\":\"<p>\\u6253\\u5f00\\u5f00\\u5173 <code>-parallel</code> \\u6709\\u52a9\\u4e8e\\u52a0\\u901f\\u6d4b\\u8bd5\\u7684\\u6267\\u884c\\uff0c\\u7279\\u522b\\u662f\\u6d4b\\u8bd5\\u4e2d\\u5305\\u542b\\u4e00\\u4e9b\\u9700\\u8981\\u957f\\u671f\\u8fd0\\u884c\\u7684\\u7528\\u4f8b\\u7684\\u65f6\\u5019\\u3002</p> <p>\\u6253\\u5f00\\u5f00\\u5173 <code>-shuffle</code> \\u80fd\\u591f\\u6253\\u4e71\\u6d4b\\u8bd5\\u7528\\u4f8b\\u6267\\u884c\\u7684\\u987a\\u5e8f\\uff0c\\u907f\\u514d\\u4e00\\u4e2a\\u6d4b\\u8bd5\\u4f9d\\u8d56\\u4e8e\\u67d0\\u4e9b\\u4e0d\\u7b26\\u5408\\u771f\\u5b9e\\u60c5\\u51b5\\u7684\\u9884\\u8bbe\\uff0c\\u6709\\u52a9\\u4e8e\\u53ca\\u65e9\\u66b4\\u9732 bug\\u3002</p>\"},{\"location\":\"zh/#85\",\"title\":\"\\u4e0d\\u4f7f\\u7528\\u8868\\u9a71\\u52a8\\u7684\\u6d4b\\u8bd5 (#85)\",\"text\":\"<p>\\u8868\\u9a71\\u52a8\\u7684\\u6d4b\\u8bd5\\u662f\\u4e00\\u79cd\\u6709\\u6548\\u7684\\u65b9\\u5f0f\\uff0c\\u53ef\\u4ee5\\u5c06\\u4e00\\u7ec4\\u76f8\\u4f3c\\u7684\\u6d4b\\u8bd5\\u5206\\u7ec4\\u5728\\u4e00\\u8d77\\uff0c\\u4ee5\\u907f\\u514d\\u4ee3\\u7801\\u91cd\\u590d\\u548c\\u4f7f\\u672a\\u6765\\u7684\\u66f4\\u65b0\\u66f4\\u5bb9\\u6613\\u5904\\u7406\\u3002</p>\"},{\"location\":\"zh/#sleep-86\",\"title\":\"\\u5728\\u5355\\u5143\\u6d4b\\u8bd5\\u4e2d\\u6267\\u884c sleep \\u64cd\\u4f5c (#86)\",\"text\":\"<p>\\u4f7f\\u7528\\u540c\\u6b65\\u7684\\u65b9\\u5f0f\\u3001\\u907f\\u514d sleep\\uff0c\\u6765\\u5c3d\\u91cf\\u51cf\\u5c11\\u6d4b\\u8bd5\\u7684\\u4e0d\\u7a33\\u5b9a\\u6027\\u548c\\u63d0\\u9ad8\\u9c81\\u68d2\\u6027\\u3002\\u5982\\u679c\\u65e0\\u6cd5\\u4f7f\\u7528\\u540c\\u6b65\\u624b\\u6bb5,\\u53ef\\u4ee5\\u8003\\u8651\\u91cd\\u8bd5\\u7684\\u65b9\\u5f0f\\u3002</p>\"},{\"location\":\"zh/#time-api-87\",\"title\":\"\\u6ca1\\u6709\\u9ad8\\u6548\\u5730\\u5904\\u7406 time API (#87)\",\"text\":\"<p>\\u7406\\u89e3\\u5982\\u4f55\\u5904\\u7406\\u4f7f\\u7528 time API \\u7684\\u51fd\\u6570\\uff0c\\u662f\\u4f7f\\u6d4b\\u8bd5\\u66f4\\u52a0\\u7a33\\u5b9a\\u7684\\u53e6\\u4e00\\u79cd\\u65b9\\u5f0f\\u3002\\u60a8\\u53ef\\u4ee5\\u4f7f\\u7528\\u6807\\u51c6\\u6280\\u672f\\uff0c\\u4f8b\\u5982\\u5c06\\u65f6\\u95f4\\u4f5c\\u4e3a\\u9690\\u85cf\\u4f9d\\u8d56\\u9879\\u7684\\u4e00\\u90e8\\u5206\\u6765\\u5904\\u7406\\uff0c\\u6216\\u8005\\u8981\\u6c42\\u5ba2\\u6237\\u7aef\\u63d0\\u4f9b\\u65f6\\u95f4\\u3002</p>\"},{\"location\":\"zh/#httptest-iotest-88\",\"title\":\"\\u4e0d\\u4f7f\\u7528\\u6d4b\\u8bd5\\u76f8\\u5173\\u7684\\u5de5\\u5177\\u5305 (<code>httptest</code> \\u548c <code>iotest</code>) (#88)\",\"text\":\"<p>\\u8fd9\\u4e2a <code>httptest</code> \\u5305\\u5bf9\\u5904\\u7406 HTTP \\u5e94\\u7528\\u7a0b\\u5e8f\\u5f88\\u6709\\u5e2e\\u52a9\\u3002\\u5b83\\u63d0\\u4f9b\\u4e86\\u4e00\\u7ec4\\u5b9e\\u7528\\u7a0b\\u5e8f\\u6765\\u6d4b\\u8bd5\\u5ba2\\u6237\\u7aef\\u548c\\u670d\\u52a1\\u5668\\u3002</p> <p>\\u8fd9\\u4e2a <code>iotest</code> \\u5305\\u6709\\u52a9\\u4e8e\\u7f16\\u5199 io.Reader \\u5e76\\u6d4b\\u8bd5\\u5e94\\u7528\\u7a0b\\u5e8f\\u662f\\u5426\\u80fd\\u591f\\u5bb9\\u5fcd\\u9519\\u8bef\\u3002</p>\"},{\"location\":\"zh/#89\",\"title\":\"\\u4e0d\\u6b63\\u786e\\u7684\\u57fa\\u51c6\\u6d4b\\u8bd5 (#89)\",\"text\":\"<ul> <li>\\u4e0d\\u8981\\u91cd\\u7f6e\\u6216\\u8005\\u6682\\u505c timer</li> </ul> <p>\\u4f7f\\u7528 time \\u65b9\\u6cd5\\u6765\\u4fdd\\u6301\\u57fa\\u51c6\\u6d4b\\u8bd5\\u7684\\u51c6\\u786e\\u6027\\u3002</p> <ul> <li>\\u505a\\u51fa\\u9519\\u8bef\\u7684\\u5fae\\u57fa\\u51c6\\u6d4b\\u8bd5\\u5047\\u8bbe</li> </ul> <p>\\u589e\\u52a0 <code>benchtime</code> \\u6216\\u8005\\u4f7f\\u7528 <code>benchstat</code> \\u7b49\\u5de5\\u5177\\u53ef\\u4ee5\\u6709\\u52a9\\u4e8e\\u5fae\\u57fa\\u51c6\\u6d4b\\u8bd5\\u3002</p> <p>\\u5c0f\\u5fc3\\u5fae\\u57fa\\u51c6\\u6d4b\\u8bd5\\u7684\\u7ed3\\u679c\\uff0c\\u5982\\u679c\\u6700\\u7ec8\\u8fd0\\u884c\\u5e94\\u7528\\u7a0b\\u5e8f\\u7684\\u7cfb\\u7edf\\u4e0e\\u8fd0\\u884c\\u5fae\\u57fa\\u51c6\\u6d4b\\u8bd5\\u7684\\u7cfb\\u7edf\\u4e0d\\u540c\\u3002</p> <ul> <li>\\u5bf9\\u7f16\\u8bd1\\u671f\\u4f18\\u5316\\u8981\\u8db3\\u591f\\u5c0f\\u5fc3</li> </ul> <p>\\u786e\\u4fdd\\u6d4b\\u8bd5\\u51fd\\u6570\\u662f\\u5426\\u4f1a\\u4ea7\\u751f\\u4e00\\u4e9b\\u526f\\u4f5c\\u7528\\uff0c\\u9632\\u6b62\\u7f16\\u8bd1\\u5668\\u4f18\\u5316\\u6b3a\\u9a97\\u4f60\\u5f97\\u5230\\u7684\\u57fa\\u51c6\\u6d4b\\u8bd5\\u7ed3\\u679c\\u3002</p> <ul> <li>\\u88ab\\u89c2\\u5bdf\\u8005\\u6548\\u5e94\\u6240\\u6b3a\\u9a97</li> </ul> <p>\\u4e3a\\u4e86\\u907f\\u514d\\u88ab\\u89c2\\u5bdf\\u8005\\u6548\\u5e94\\u6b3a\\u9a97\\uff0c\\u5f3a\\u5236\\u91cd\\u65b0\\u521b\\u5efaCPU\\u5bc6\\u96c6\\u578b\\u51fd\\u6570\\u4f7f\\u7528\\u7684\\u6570\\u636e\\u3002</p>\"},{\"location\":\"zh/#go-test-90\",\"title\":\"\\u6ca1\\u6709\\u53bb\\u63a2\\u7d22 go test \\u6240\\u6709\\u7684\\u7279\\u6027 (#90)\",\"text\":\"<ul> <li>\\u4ee3\\u7801\\u8986\\u76d6\\u7387</li> </ul> <p>\\u4f7f\\u7528 <code>-coverprofile</code> \\u53c2\\u6570\\u53ef\\u4ee5\\u5feb\\u901f\\u67e5\\u770b\\u4ee3\\u7801\\u7684\\u6d4b\\u8bd5\\u8986\\u76d6\\u60c5\\u51b5\\uff0c\\u65b9\\u4fbf\\u5feb\\u901f\\u67e5\\u770b\\u54ea\\u4e2a\\u90e8\\u5206\\u9700\\u8981\\u66f4\\u591a\\u7684\\u5173\\u6ce8\\u3002</p> <ul> <li>\\u5728\\u4e0d\\u540c\\u7684\\u5305\\u4e2d\\u6267\\u884c\\u6d4b\\u8bd5</li> </ul> <p>\\u5355\\u5143\\u6d4b\\u8bd5\\u7ec4\\u7ec7\\u5230\\u4e00\\u4e2a\\u72ec\\u7acb\\u7684\\u5305\\u4e2d\\uff0c\\u5bf9\\u4e8e\\u5bf9\\u5916\\u5c42\\u66b4\\u9732\\u7684\\u63a5\\u53e3\\uff0c\\u9700\\u8981\\u5199\\u4e00\\u4e9b\\u6d4b\\u8bd5\\u7528\\u4f8b\\u3002\\u6d4b\\u8bd5\\u5e94\\u8be5\\u5173\\u6ce8\\u516c\\u5f00\\u7684\\u884c\\u4e3a\\uff0c\\u800c\\u975e\\u5185\\u90e8\\u5b9e\\u73b0\\u7ec6\\u8282\\u3002</p> <ul> <li>Utility \\u51fd\\u6570</li> </ul> <p>\\u5904\\u7406\\u9519\\u8bef\\u65f6\\uff0c\\u4f7f\\u7528 <code>*testing.T</code> \\u53d8\\u91cf\\u800c\\u4e0d\\u662f\\u7ecf\\u5178\\u7684 <code>if err != nil</code> \\u53ef\\u4ee5\\u8ba9\\u4ee3\\u7801\\u66f4\\u52a0\\u7b80\\u6d01\\u6613\\u8bfb\\u3002</p> <ul> <li>\\u8bbe\\u7f6e\\u548c\\u9500\\u6bc1</li> </ul> <p>\\u4f60\\u53ef\\u4ee5\\u4f7f\\u7528 setup \\u548c teardown \\u51fd\\u6570\\u6765\\u914d\\u7f6e\\u4e00\\u4e2a\\u590d\\u6742\\u7684\\u73af\\u5883\\uff0c\\u6bd4\\u5982\\u5728\\u96c6\\u6210\\u6d4b\\u8bd5\\u7684\\u60c5\\u51b5\\u4e0b\\u3002</p>\"},{\"location\":\"zh/#_11\",\"title\":\"\\u4e0d\\u4f7f\\u7528\\u6a21\\u7cca\\u6d4b\\u8bd5 (\\u793e\\u533a\\u53cd\\u9988\\u9519\\u8bef)\",\"text\":\"<p>\\u6a21\\u7cca\\u6d4b\\u8bd5\\u662f\\u4e00\\u79cd\\u9ad8\\u6548\\u7684\\u7b56\\u7565\\uff0c\\u4f7f\\u7528\\u5b83\\u80fd\\u68c0\\u6d4b\\u51fa\\u968f\\u673a\\u3001\\u610f\\u6599\\u5916\\u7684\\u548c\\u4e00\\u4e9b\\u6076\\u610f\\u7684\\u6570\\u636e\\u8f93\\u5165\\uff0c\\u6765\\u5b8c\\u6210\\u4e00\\u4e9b\\u590d\\u6742\\u7684\\u64cd\\u4f5c\\u3002</p> <p>\\u89c1: @jeromedoucet</p>\"},{\"location\":\"zh/#_12\",\"title\":\"\\u4f18\\u5316\\u6280\\u672f\",\"text\":\"\"},{\"location\":\"zh/#cpu-cache-91\",\"title\":\"\\u4e0d\\u7406\\u89e3 CPU cache (#91)\",\"text\":\"<ul> <li>CPU \\u67b6\\u6784</li> </ul> <p>\\u7406\\u89e3 CPU \\u7f13\\u5b58\\u7684\\u4f7f\\u7528\\u5bf9\\u4e8e\\u4f18\\u5316 CPU \\u5bc6\\u96c6\\u578b\\u5e94\\u7528\\u5f88\\u91cd\\u8981\\uff0c\\u56e0\\u4e3a L1 \\u7f13\\u5b58\\u6bd4\\u4e3b\\u5b58\\u5feb 50 \\u5230 100 \\u500d\\u3002</p> <ul> <li>Cache line</li> </ul> <p>\\u610f\\u8bc6\\u5230 cache line \\u6982\\u5ff5\\u5bf9\\u4e8e\\u7406\\u89e3\\u5982\\u4f55\\u5728\\u6570\\u636e\\u5bc6\\u96c6\\u578b\\u5e94\\u7528\\u4e2d\\u7ec4\\u7ec7\\u6570\\u636e\\u975e\\u5e38\\u5173\\u952e\\u3002CPU \\u5e76\\u4e0d\\u662f\\u4e00\\u4e2a\\u4e00\\u4e2a\\u5b57\\u6765\\u83b7\\u53d6\\u5185\\u5b58\\u3002\\u76f8\\u53cd\\uff0c\\u5b83\\u901a\\u5e38\\u590d\\u5236\\u4e00\\u4e2a 64 \\u5b57\\u8282\\u957f\\u5ea6\\u7684 cache line\\u3002\\u4e3a\\u4e86\\u83b7\\u5f97\\u6bcf\\u4e2a cache line \\u7684\\u6700\\u5927\\u6548\\u7528\\uff0c\\u9700\\u8981\\u5b9e\\u65bd\\u7a7a\\u95f4\\u5c40\\u90e8\\u6027\\u3002</p> <ul> <li> <p>\\u4e00\\u7cfb\\u5217 struct \\u5143\\u7d20\\u6784\\u6210\\u7684 slice vs. \\u591a\\u4e2a slice \\u5b57\\u6bb5\\u6784\\u6210\\u7684 struct</p> </li> <li> <p>\\u6982\\u7387\\u6027\\u7684\\u95ee\\u9898</p> </li> </ul> <p>\\u63d0\\u9ad8 CPU \\u6267\\u884c\\u4ee3\\u7801\\u65f6\\u7684\\u53ef\\u9884\\u6d4b\\u6027\\uff0c\\u4e5f\\u662f\\u4f18\\u5316\\u67d0\\u4e9b\\u51fd\\u6570\\u7684\\u4e00\\u4e2a\\u6709\\u6548\\u65b9\\u6cd5\\u3002\\u6bd4\\u5982\\uff0c\\u56fa\\u5b9a\\u6b65\\u957f\\u6216\\u8fde\\u7eed\\u8bbf\\u95ee\\u5bf9 CPU \\u6765\\u8bf4\\u662f\\u53ef\\u9884\\u6d4b\\u7684\\uff0c\\u4f46\\u975e\\u8fde\\u7eed\\u8bbf\\u95ee\\uff08\\u4f8b\\u5982\\u94fe\\u8868\\uff09\\u5c31\\u662f\\u4e0d\\u53ef\\u9884\\u6d4b\\u7684\\u3002</p> <ul> <li>cache \\u653e\\u7f6e\\u7b56\\u7565</li> </ul> <p>\\u8981\\u6ce8\\u610f\\u73b0\\u4ee3\\u7f13\\u5b58\\u662f\\u5206\\u533a\\u7684\\uff08set associative placement\\uff0c\\u7ec4\\u76f8\\u8fde\\u6620\\u5c04\\uff09\\uff0c\\u8981\\u6ce8\\u610f\\u907f\\u514d\\u4f7f\\u7528 <code>critical stride</code>\\uff0c\\u8fd9\\u79cd\\u6b65\\u957f\\u60c5\\u51b5\\u4e0b\\u53ea\\u80fd\\u5229\\u7528 cache \\u7684\\u4e00\\u5c0f\\u90e8\\u5206\\u3002</p> <p>critical stride\\uff0c\\u8fd9\\u79cd\\u7c7b\\u578b\\u7684\\u6b65\\u957f\\uff0c\\u6307\\u7684\\u662f\\u5185\\u5b58\\u8bbf\\u95ee\\u7684\\u6b65\\u957f\\u521a\\u597d\\u7b49\\u4e8e cache \\u5927\\u5c0f\\u3002\\u8fd9\\u79cd\\u60c5\\u51b5\\u4e0b\\uff0c\\u53ea\\u6709\\u5c11\\u90e8\\u5206 cacheline \\u88ab\\u5229\\u7528\\u3002</p>\"},{\"location\":\"zh/#false-sharing-92\",\"title\":\"\\u5199\\u7684\\u5e76\\u53d1\\u5904\\u7406\\u903b\\u8f91\\u4f1a\\u5bfc\\u81f4 false sharing (#92)\",\"text\":\"<p>\\u4e86\\u89e3 CPU \\u7f13\\u5b58\\u7684\\u8f83\\u4f4e\\u5c42\\u7684 L1\\u3001L2 cache \\u4e0d\\u4f1a\\u5728\\u6240\\u6709\\u6838\\u95f4\\u5171\\u4eab\\uff0c\\u7f16\\u5199\\u5e76\\u53d1\\u5904\\u7406\\u903b\\u8f91\\u65f6\\u80fd\\u907f\\u514d\\u5199\\u51fa\\u4e00\\u4e9b\\u964d\\u4f4e\\u6027\\u80fd\\u7684\\u95ee\\u9898\\uff0c\\u6bd4\\u5982\\u4f2a\\u5171\\u4eab\\uff08false sharing\\uff09\\u3002\\u5185\\u5b58\\u5171\\u4eab\\u53ea\\u662f\\u4e00\\u79cd\\u5047\\u8c61\\u3002</p>\"},{\"location\":\"zh/#93\",\"title\":\"\\u6ca1\\u6709\\u8003\\u8651\\u6307\\u4ee4\\u7ea7\\u7684\\u5e76\\u884c (#93)\",\"text\":\"<p>\\u4f7f\\u7528\\u6307\\u4ee4\\u7ea7\\u5e76\\u884c\\uff08ILP\\uff09\\u4f18\\u5316\\u4ee3\\u7801\\u7684\\u7279\\u5b9a\\u90e8\\u5206\\uff0c\\u4ee5\\u5141\\u8bb8 CPU \\u5c3d\\u53ef\\u80fd\\u6267\\u884c\\u66f4\\u591a\\u53ef\\u4ee5\\u5e76\\u884c\\u6267\\u884c\\u7684\\u6307\\u4ee4\\u3002\\u8bc6\\u522b\\u6307\\u4ee4\\u7684\\u6570\\u636e\\u4f9d\\u8d56\\u95ee\\u9898\\uff08data hazards\\uff09\\u662f\\u4e3b\\u8981\\u6b65\\u9aa4\\u4e4b\\u4e00\\u3002</p>\"},{\"location\":\"zh/#94\",\"title\":\"\\u4e0d\\u4e86\\u89e3\\u6570\\u636e\\u5bf9\\u9f50 (#94)\",\"text\":\"<p>\\u8bb0\\u4f4f Go \\u4e2d\\u57fa\\u672c\\u7c7b\\u578b\\u4e0e\\u5176\\u81ea\\u8eab\\u5927\\u5c0f\\u5bf9\\u9f50\\uff0c\\u4f8b\\u5982\\uff0c\\u6309\\u5927\\u5c0f\\u964d\\u5e8f\\u91cd\\u65b0\\u7ec4\\u7ec7\\u7ed3\\u6784\\u4f53\\u7684\\u5b57\\u6bb5\\u53ef\\u4ee5\\u5f62\\u6210\\u66f4\\u7d27\\u51d1\\u7684\\u7ed3\\u6784\\u4f53\\uff08\\u51cf\\u5c11\\u5185\\u5b58\\u5206\\u914d\\uff0c\\u66f4\\u597d\\u7684\\u7a7a\\u95f4\\u5c40\\u90e8\\u6027\\uff09\\uff0c\\u8fd9\\u6709\\u52a9\\u4e8e\\u907f\\u514d\\u4e00\\u4e9b\\u5e38\\u89c1\\u7684\\u9519\\u8bef\\u3002</p>\"},{\"location\":\"zh/#stack-vs-heap-95\",\"title\":\"\\u4e0d\\u4e86\\u89e3 stack vs. heap (#95)\",\"text\":\"<p>\\u4e86\\u89e3\\u5806\\u548c\\u6808\\u4e4b\\u95f4\\u7684\\u533a\\u522b\\u662f\\u5f00\\u53d1\\u4eba\\u5458\\u7684\\u6838\\u5fc3\\u77e5\\u8bc6\\u70b9\\uff0c\\u7279\\u522b\\u662f\\u8981\\u53bb\\u4f18\\u5316\\u4e00\\u4e2a Go \\u7a0b\\u5e8f\\u65f6\\u3002\\u6808\\u5206\\u914d\\u7684\\u5f00\\u9500\\u51e0\\u4e4e\\u4e3a\\u96f6\\uff0c\\u800c\\u5806\\u5206\\u914d\\u5219\\u8f83\\u6162\\uff0c\\u5e76\\u4e14\\u4f9d\\u8d56 GC \\u6765\\u6e05\\u7406\\u5185\\u5b58\\u3002</p>\"},{\"location\":\"zh/#api-syncpool-96\",\"title\":\"\\u4e0d\\u77e5\\u9053\\u5982\\u4f55\\u51cf\\u5c11\\u5185\\u5b58\\u5206\\u914d\\u6b21\\u6570\\uff08API \\u8c03\\u6574\\uff0c\\u7f16\\u8bd1\\u5668\\u4f18\\u5316\\u548c <code>sync.Pool</code>\\uff09 (#96)\",\"text\":\"<p>\\u51cf\\u5c11\\u5185\\u5b58\\u5206\\u914d\\u6b21\\u6570\\u4e5f\\u662f\\u4f18\\u5316 Go \\u5e94\\u7528\\u7684\\u4e00\\u4e2a\\u91cd\\u8981\\u65b9\\u9762\\u3002\\u8fd9\\u53ef\\u4ee5\\u901a\\u8fc7\\u4e0d\\u540c\\u7684\\u65b9\\u5f0f\\u6765\\u5b9e\\u73b0\\uff0c\\u6bd4\\u5982\\u4ed4\\u7ec6\\u8bbe\\u8ba1 API \\u6765\\u907f\\u514d\\u4e0d\\u5fc5\\u8981\\u7684\\u62f7\\u8d1d\\uff0c\\u4ee5\\u53ca\\u4f7f\\u7528 <code>sync.Pool</code> \\u6765\\u5bf9\\u5206\\u914d\\u5bf9\\u8c61\\u8fdb\\u884c\\u6c60\\u5316\\u3002</p>\"},{\"location\":\"zh/#97\",\"title\":\"\\u4e0d\\u6ce8\\u610f\\u4f7f\\u7528\\u5185\\u8054 (#97)\",\"text\":\"<p>\\u4f7f\\u7528\\u5feb\\u901f\\u8def\\u5f84\\u7684\\u5185\\u8054\\u6280\\u672f\\u6765\\u66f4\\u52a0\\u6709\\u6548\\u5730\\u51cf\\u5c11\\u8c03\\u7528\\u51fd\\u6570\\u7684\\u644a\\u9500\\u65f6\\u95f4\\u3002</p>\"},{\"location\":\"zh/#go-98\",\"title\":\"\\u4e0d\\u4f7f\\u7528 Go \\u95ee\\u9898\\u8bca\\u65ad\\u5de5\\u5177 (#98)\",\"text\":\"<p>\\u4e86\\u89e3 Go profiling \\u5de5\\u5177\\u3001\\u6267\\u884c\\u65f6 tracer \\u6765\\u8f85\\u52a9\\u5224\\u65ad\\u4e00\\u4e2a\\u5e94\\u7528\\u7a0b\\u5e8f\\u662f\\u5426\\u6b63\\u5e38\\uff0c\\u4ee5\\u53ca\\u5217\\u51fa\\u9700\\u8981\\u4f18\\u5316\\u7684\\u90e8\\u5206\\u3002</p>\"},{\"location\":\"zh/#gc-99\",\"title\":\"\\u4e0d\\u7406\\u89e3 GC \\u662f\\u5982\\u4f55\\u5de5\\u4f5c\\u7684 (#99)\",\"text\":\"<p>\\u7406\\u89e3\\u5982\\u4f55\\u8c03\\u4f18 GC \\u80fd\\u591f\\u5e26\\u6765\\u5f88\\u591a\\u6536\\u76ca\\uff0c\\u4f8b\\u5982\\u6709\\u52a9\\u4e8e\\u66f4\\u9ad8\\u6548\\u5730\\u5904\\u7406\\u7a81\\u589e\\u7684\\u8d1f\\u8f7d\\u3002</p>\"},{\"location\":\"zh/#docker-k8s-go-100\",\"title\":\"\\u4e0d\\u4e86\\u89e3 Docker \\u6216\\u8005 K8S \\u5bf9\\u8fd0\\u884c\\u7684 Go \\u5e94\\u7528\\u7684\\u6027\\u80fd\\u5f71\\u54cd (#100)\",\"text\":\"<p>\\u4e3a\\u4e86\\u907f\\u514d CPU throttling\\uff08CPU \\u9650\\u9891\\uff09\\u95ee\\u9898\\uff0c\\u5f53\\u6211\\u4eec\\u5728 Docker \\u548c Kubernetes \\u90e8\\u7f72\\u5e94\\u7528\\u65f6\\uff0c\\u8981\\u77e5\\u9053 Go \\u8bed\\u8a00\\u5bf9 CFS\\uff08\\u5b8c\\u5168\\u516c\\u5e73\\u8c03\\u5ea6\\u5668\\uff09\\u65e0\\u611f\\u77e5\\u3002</p>\"}]}"
  },
  {
    "path": "site/sitemap.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n    <url>\n         <loc>https://100go.co/</loc>\n         <lastmod>2025-09-24</lastmod>\n    </url>\n    <url>\n         <loc>https://100go.co/20-slice/</loc>\n         <lastmod>2025-09-24</lastmod>\n    </url>\n    <url>\n         <loc>https://100go.co/28-maps-memory-leaks/</loc>\n         <lastmod>2025-09-24</lastmod>\n    </url>\n    <url>\n         <loc>https://100go.co/5-interface-pollution/</loc>\n         <lastmod>2025-09-24</lastmod>\n    </url>\n    <url>\n         <loc>https://100go.co/56-concurrency-faster/</loc>\n         <lastmod>2025-09-24</lastmod>\n    </url>\n    <url>\n         <loc>https://100go.co/89-benchmarks/</loc>\n         <lastmod>2025-09-24</lastmod>\n    </url>\n    <url>\n         <loc>https://100go.co/9-generics/</loc>\n         <lastmod>2025-09-24</lastmod>\n    </url>\n    <url>\n         <loc>https://100go.co/92-false-sharing/</loc>\n         <lastmod>2025-09-24</lastmod>\n    </url>\n    <url>\n         <loc>https://100go.co/98-profiling-execution-tracing/</loc>\n         <lastmod>2025-09-24</lastmod>\n    </url>\n    <url>\n         <loc>https://100go.co/book/</loc>\n         <lastmod>2025-09-24</lastmod>\n    </url>\n    <url>\n         <loc>https://100go.co/chapter-1/</loc>\n         <lastmod>2025-09-24</lastmod>\n    </url>\n    <url>\n         <loc>https://100go.co/external/</loc>\n         <lastmod>2025-09-24</lastmod>\n    </url>\n    <url>\n         <loc>https://100go.co/ja/</loc>\n         <lastmod>2025-09-24</lastmod>\n    </url>\n    <url>\n         <loc>https://100go.co/pt-br/</loc>\n         <lastmod>2025-09-24</lastmod>\n    </url>\n    <url>\n         <loc>https://100go.co/zh/</loc>\n         <lastmod>2025-09-24</lastmod>\n    </url>\n</urlset>"
  },
  {
    "path": "site/stylesheets/extra.css",
    "content": ".md-typeset figure img {\n  display: inline;\n}\n\n.md-typeset .admonition,\n.md-typeset details {\n  font-size: 15px\n}\n"
  },
  {
    "path": "site/zh/index.html",
    "content": "<!DOCTYPE html><html lang=\"en\" class=\"no-js\"><head>\n    \n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      \n      \n      \n        <link rel=\"canonical\" href=\"https://100go.co/zh/\">\n      \n      \n        <link rel=\"prev\" href=\"../98-profiling-execution-tracing/\">\n      \n      \n        <link rel=\"next\" href=\"../ja/\">\n      \n      \n      <link rel=\"icon\" href=\"../img/Go-Logo_LightBlue.svg\">\n      <meta name=\"generator\" content=\"mkdocs-1.6.1, mkdocs-material-9.6.20\">\n    \n    \n      \n        <title>Chinese (Simplified) Version - 100 Go Mistakes and How to Avoid Them</title>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../assets/stylesheets/main.e53b48f4.min.css\">\n      \n        \n        <link rel=\"stylesheet\" href=\"../assets/stylesheets/palette.06af60db.min.css\">\n      \n      \n\n\n    \n    \n      \n    \n    \n      \n        \n        \n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback\">\n        <style>:root{--md-text-font:\"Roboto\";--md-code-font:\"Roboto Mono\"}</style>\n      \n    \n    \n      <link rel=\"stylesheet\" href=\"../stylesheets/extra.css\">\n    \n    <script>__md_scope=new URL(\"..\",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+\".\"+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+\".\"+e,JSON.stringify(_))}catch(e){}}</script>\n    \n      \n  \n\n\n  \n  \n\n<script id=\"__analytics\">function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e(\"js\",new Date),e(\"config\",\"G-HMY1HYDM93\"),document.addEventListener(\"DOMContentLoaded\",(function(){document.forms.search&&document.forms.search.query.addEventListener(\"blur\",(function(){this.value&&e(\"event\",\"search\",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll(\"[type=submit]\"))a.addEventListener(\"click\",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute(\"data-md-value\");e(\"event\",\"feedback\",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(\".md-feedback__note [data-md-value='\"+d+\"']\");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e(\"config\",\"G-HMY1HYDM93\",{page_path:t.pathname})}))}));var t=document.createElement(\"script\");t.async=!0,t.src=\"https://www.googletagmanager.com/gtag/js?id=G-HMY1HYDM93\",document.getElementById(\"__analytics\").insertAdjacentElement(\"afterEnd\",t)}</script>\n  \n    <script>\"undefined\"!=typeof __md_analytics&&__md_analytics()</script>\n  \n\n    \n    \n      \n        <meta property=\"og:type\" content=\"website\">\n      \n        <meta property=\"og:title\" content=\"Chinese (Simplified) Version - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta property=\"og:description\" content=\"None\">\n      \n        <meta property=\"og:image\" content=\"https://100go.co/assets/images/social/zh.png\">\n      \n        <meta property=\"og:image:type\" content=\"image/png\">\n      \n        <meta property=\"og:image:width\" content=\"1200\">\n      \n        <meta property=\"og:image:height\" content=\"630\">\n      \n        <meta property=\"og:url\" content=\"https://100go.co/zh/\">\n      \n        <meta name=\"twitter:card\" content=\"summary_large_image\">\n      \n        <meta name=\"twitter:title\" content=\"Chinese (Simplified) Version - 100 Go Mistakes and How to Avoid Them\">\n      \n        <meta name=\"twitter:description\" content=\"None\">\n      \n        <meta name=\"twitter:image\" content=\"https://100go.co/assets/images/social/zh.png\">\n      \n    \n    \n  <link href=\"../assets/stylesheets/glightbox.min.css\" rel=\"stylesheet\"><script src=\"../assets/javascripts/glightbox.min.js\"></script><style id=\"glightbox-style\">\n            html.glightbox-open { overflow: initial; height: 100%; }\n            .gslide-title { margin-top: 0px; user-select: text; }\n            .gslide-desc { color: #666; user-select: text; }\n            .gslide-image img { background: white; }\n            .gscrollbar-fixer { padding-right: 15px; }\n            .gdesc-inner { font-size: 0.75rem; }\n            body[data-md-color-scheme=\"slate\"] .gdesc-inner { background: var(--md-default-bg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-title { color: var(--md-default-fg-color); }\n            body[data-md-color-scheme=\"slate\"] .gslide-desc { color: var(--md-default-fg-color); }\n        </style></head>\n  \n  \n    \n    \n      \n    \n    \n    \n    \n    <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\">\n  \n    \n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" for=\"__drawer\"></label>\n    <div data-md-component=\"skip\">\n      \n        \n        <a href=\"#100-go\" class=\"md-skip\">\n          Skip to content\n        </a>\n      \n    </div>\n    <div data-md-component=\"announce\">\n      \n    </div>\n    \n    \n      \n\n  \n\n<header class=\"md-header md-header--shadow md-header--lifted\" data-md-component=\"header\">\n  <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-header__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    <label class=\"md-header__button md-icon\" for=\"__drawer\">\n      \n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"></path></svg>\n    </label>\n    <div class=\"md-header__title\" data-md-component=\"header-title\">\n      <div class=\"md-header__ellipsis\">\n        <div class=\"md-header__topic\">\n          <span class=\"md-ellipsis\">\n            100 Go Mistakes and How to Avoid Them\n          </span>\n        </div>\n        <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n          <span class=\"md-ellipsis\">\n            \n              Chinese (Simplified) Version\n            \n          </span>\n        </div>\n      </div>\n    </div>\n    \n      \n        <form class=\"md-header__option\" data-md-component=\"palette\">\n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"default\" data-md-color-primary=\"cyan\" data-md-color-accent=\"deep-orange\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n    \n    \n    \n    <input class=\"md-option\" data-md-color-media=\"\" data-md-color-scheme=\"slate\" data-md-color-primary=\"blue-grey\" data-md-color-accent=\"teal\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n    \n      <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z\"></path></svg>\n      </label>\n    \n  \n</form>\n      \n    \n    \n      <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n    \n    \n      <div class=\"md-header__option\">\n  <div class=\"md-select\">\n    \n    <button class=\"md-header__button md-icon\" aria-label=\"Select language\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"m12.87 15.07-2.54-2.51.03-.03A17.5 17.5 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2zm-2.62 7 1.62-4.33L19.12 17z\"></path></svg>\n    </button>\n    <div class=\"md-select__inner\">\n      <ul class=\"md-select__list\">\n        \n          <li class=\"md-select__item\">\n            <a href=\"/\" hreflang=\"en\" class=\"md-select__link\">\n              🇬🇧 English\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/zh/\" hreflang=\"zh\" class=\"md-select__link\">\n              🇨🇳 简体中文\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/ja/\" hreflang=\"ja\" class=\"md-select__link\">\n              🇯🇵 日本語\n            </a>\n          </li>\n        \n          <li class=\"md-select__item\">\n            <a href=\"/pt-br/\" hreflang=\"pt-br\" class=\"md-select__link\">\n              🇧🇷 Português Brasileiro\n            </a>\n          </li>\n        \n      </ul>\n    </div>\n  </div>\n</div>\n    \n    \n      \n      \n        <label class=\"md-header__button md-icon\" for=\"__search\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        </label>\n        <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" aria-label=\"Search\" placeholder=\"Search\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"search-query\" required>\n      <label class=\"md-search__icon md-icon\" for=\"__search\">\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5\"></path></svg>\n        \n        <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z\"></path></svg>\n      </label>\n      <nav class=\"md-search__options\" aria-label=\"Search\">\n        \n          <a href=\"javascript:void(0)\" class=\"md-search__icon md-icon\" title=\"Share\" aria-label=\"Share\" data-clipboard data-clipboard-text=\"\" data-md-component=\"search-share\" tabindex=\"-1\">\n            \n            <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08\"></path></svg>\n          </a>\n        \n        <button type=\"reset\" class=\"md-search__icon md-icon\" title=\"Clear\" aria-label=\"Clear\" tabindex=\"-1\">\n          \n          <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"></path></svg>\n        </button>\n      </nav>\n      \n        <div class=\"md-search__suggest\" data-md-component=\"search-suggest\"></div>\n      \n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" tabindex=\"0\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"search-result\">\n          <div class=\"md-search-result__meta\">\n            Initializing search\n          </div>\n          <ol class=\"md-search-result__list\" role=\"presentation\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n      \n    \n    \n      <div class=\"md-header__source\">\n        <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n      </div>\n    \n  </nav>\n  \n    \n      \n<nav class=\"md-tabs\" aria-label=\"Tabs\" data-md-component=\"tabs\">\n  <div class=\"md-grid\">\n    <ul class=\"md-tabs__list\">\n      \n        \n  \n  \n  \n    \n  \n  \n    \n    \n      <li class=\"md-tabs__item md-tabs__item--active\">\n        <a href=\"..\" class=\"md-tabs__link\">\n          \n  \n  \n  Go Mistakes\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    \n    \n      <li class=\"md-tabs__item\">\n        <a href=\"../book/\" class=\"md-tabs__link\">\n          \n  \n  \n  Book Details\n\n        </a>\n      </li>\n    \n  \n\n      \n        \n  \n  \n  \n  \n    <li class=\"md-tabs__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-tabs__link\">\n        \n  \n  \n    \n  \n  The Story Behind 100 Go Mistakes\n\n      </a>\n    </li>\n  \n\n      \n    </ul>\n  </div>\n</nav>\n    \n  \n</header>\n    \n    <div class=\"md-container\" data-md-component=\"container\">\n      \n      \n        \n      \n      <main class=\"md-main\" data-md-component=\"main\">\n        <div class=\"md-main__inner md-grid\">\n          \n            \n              \n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n\n  \n\n\n<nav class=\"md-nav md-nav--primary md-nav--lifted\" aria-label=\"Navigation\" data-md-level=\"0\">\n  <label class=\"md-nav__title\" for=\"__drawer\">\n    <a href=\"..\" title=\"100 Go Mistakes and How to Avoid Them\" class=\"md-nav__button md-logo\" aria-label=\"100 Go Mistakes and How to Avoid Them\" data-md-component=\"logo\">\n      \n  <img src=\"../img/Go-Logo_White.svg\" alt=\"logo\">\n\n    </a>\n    100 Go Mistakes and How to Avoid Them\n  </label>\n  \n    <div class=\"md-nav__source\">\n      <a href=\"https://github.com/teivah/100-go-mistakes\" title=\"Go to repository\" class=\"md-source\" data-md-component=\"source\">\n  <div class=\"md-source__icon md-icon\">\n    \n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2\"></path></svg>\n  </div>\n  <div class=\"md-source__repository\">\n    teivah/100-go-mistakes\n  </div>\n</a>\n    </div>\n  \n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    \n      \n      \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n        \n        \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1\" id=\"__nav_1_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Go Mistakes\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_1_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Go Mistakes\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"..\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Common Go Mistakes\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_1_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_2\" id=\"__nav_1_2_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Full Sections\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_1_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Full Sections\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../5-interface-pollution/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Interface pollution (#5)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../9-generics/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Being confused about when to use generics (#9)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../20-slice/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not understanding slice length and capacity (#20)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../28-maps-memory-leaks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Maps and memory leaks (#28)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../56-concurrency-faster/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Thinking concurrency is always faster (#56)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../89-benchmarks/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing inaccurate benchmarks (#89)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../92-false-sharing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Writing concurrent code that leads to false sharing (#92)\n    \n  </span>\n  \n    \n  \n  \n    <span class=\"md-status md-status--new\" title=\"New content\">\n    </span>\n  \n\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../98-profiling-execution-tracing/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Not using Go diagnostics tooling (#98)\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n    \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n          \n          \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n      \n        \n        \n        <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_1_3\" checked>\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_1_3\" id=\"__nav_1_3_label\" tabindex=\"\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Translations\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"2\" aria-labelledby=\"__nav_1_3_label\" aria-expanded=\"true\">\n          <label class=\"md-nav__title\" for=\"__nav_1_3\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Translations\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n    \n  \n  \n  \n    <li class=\"md-nav__item md-nav__item--active\">\n      \n      <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n      \n      \n        \n      \n      \n        <label class=\"md-nav__link md-nav__link--active\" for=\"__toc\">\n          \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n          <span class=\"md-nav__icon md-icon\"></span>\n        </label>\n      \n      <a href=\"./\" class=\"md-nav__link md-nav__link--active\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇨🇳 简体中文\n    \n  </span>\n  \n\n      </a>\n      \n        \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      代码及工程组织\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"代码及工程组织\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      意外的变量隐藏 (#1)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#2\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不必要的代码嵌套 (#2)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#init-3\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      误用 init 函数 (#3)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#getterssetters-4\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      滥用 getters/setters (#4)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#5\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      接口污染 (#5)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#6\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      将接口定义在实现方一侧 (#6)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#7\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      将接口作为返回值 (#7)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#any-8\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      any 没传递任何信息 (#8)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#9\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      困惑何时该用范型 (#9)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#10\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      未意识到类型嵌套的可能问题 (#10)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#function-option-11\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用 function option 模式 (#11)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#12\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      工程组织不合理 (工程结构和包的组织) (#12)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#13\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      创建工具包 (#13)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#14\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忽略了包名冲突 (#14)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#15\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      代码缺少文档 (#15)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#linters-16\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用 linters 检查 (#16)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_2\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      数据类型\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"数据类型\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#17\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      八进制字面量引发的困惑 (#17)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#18\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      未注意可能的整数溢出 (#18)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#19\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      没有透彻理解浮点数 (#19)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-20\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不理解 slice 的长度和容量 (#20)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-21\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不高效的 slice 初始化 (#21)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nil-slice-22\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      困惑于 nil 和空 slice (#22)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-23\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      没有适当检查 slice 是否为空 (#23)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-24\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      没有正确拷贝 slice (#24)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-append-25\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      slice append 带来的预期之外的副作用 (#25)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-26\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      slice 和内存泄漏 (#26)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#map-27\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不高效的 map 初始化 (#27)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#map-28\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      map 和内存泄漏 (#28)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#29\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不正确的值比较 (#29)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_3\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      控制结构\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"控制结构\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#range-30\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忽略了 range 循环变量是一个拷贝 (#30)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#range-channels-arrays-31\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忽略了 range 循环中迭代目标值的计算方式 (channels 和 arrays) (#31)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#range-32\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忽略了 range 循环中指针元素的影响 (#32)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#map-33\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      map 迭代过程中的错误假设（遍历顺序和迭代过程中插入）(#33)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#break-34\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忽略了 break 语句是如何工作的 (#34)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#defer-35\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      在循环中使用 defer (#35)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_4\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      字符串\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"字符串\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#rune-36\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      没有理解 rune (#36)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#37\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不正确的字符串遍历 (#37)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#trim-38\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      误用 trim 函数 (#38)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#39\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不经优化的字符串拼接操作 (#39)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#40\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      无用的字符串转换 (#40)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#41\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      子字符串和内存泄漏 (#41)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_5\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      函数和方法\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"函数和方法\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#42\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不知道使用哪种接收器类型 (#42)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#43\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      从不使用命名的返回值 (#43)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#44\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      使用命名的返回值时预期外的副作用 (#44)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nil-45\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      返回一个 nil 接收器 (#45)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#46\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      使用文件名作为函数入参 (#46)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#defer-value-47\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忽略 defer 语句中参数、接收器值的计算方式 (参数值计算, 指针, 和 value 类型接收器) (#47)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_6\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      错误管理\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"错误管理\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#panicking-48\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Panicking (#48)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#error-49\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      未考虑何时才应该包装 error (#49)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#50\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不正确的错误类型比较 (#50)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#51\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不正确的错误对象值比较 (#51)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#52\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      两次处理同一个错误 (#52)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#53\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不处理错误 (#53)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#defer-54\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不处理 defer 中的错误 (#54)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_7\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      并发编程: 基础\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"并发编程: 基础\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#55\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      混淆并发和并行 (#55)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#56\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      认为并发总是更快 (#56)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#channels-mutexes-57\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不清楚何时使用 channels 或 mutexes (#57)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#vs-go-58\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不明白竞态问题 (数据竞态 vs. 竞态条件和 Go 内存模型) (#58)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#59\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不理解不同工作负载类型对并发的影响 (#59)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-contexts-60\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      误解了 Go contexts (#60)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_8\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      并发编程: 实践\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"并发编程: 实践\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#context-61\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      传递不合适的 context (#61)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#goroutine-62\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      启动了一个 goroutine 但是不知道它何时会停止 (#62)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#goroutines-63\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不注意处理 goroutines 和循环中的迭代变量 (#63)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#select-channels-64\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      使用 select + channels 时误以为分支选择顺序是确定的 (#64)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#channels-65\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不正确使用通知 channels (#65)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nil-channels-66\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用 nil channels (#66)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#channel-size-67\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不清楚该如何确定 channel size (#67)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#etcd-68\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忘记了字符串格式化可能带来的副作用（例如 etcd 数据竞争和死锁）(#68)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#append-69\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      使用 append 不当导致数据竞争 (#69)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#mutexes-slicesmaps-70\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      误用 mutexes 和 slices、maps (#70)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#syncwaitgroup-71\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      误用 sync.WaitGroup (#71)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#synccond-72\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忘记使用 sync.Cond (#72)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#errgroup-73\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用 errgroup (#73)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#sync-74\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      拷贝一个 sync 下的类型 (#74)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_9\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      标准库\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"标准库\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#timeduration-75\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      使用了错误的 time.Duration (#75)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#timeafter-76\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      time.After 和内存泄漏 (#76)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#json-77\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      JSON 处理中的常见错误 (#77)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#sql-78\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      常见的 SQL 错误 (#78)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#http-sqlrows-osfile-79\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不关闭临时资源（HTTP 请求体、sql.Rows 和 os.File） (#79)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#http-80\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      响应 HTTP 请求后没有返回语句 (#80)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#http-client-server-81\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      直接使用默认的 HTTP client 和 server (#81)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_10\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      测试\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"测试\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#build-tags-82\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不对测试进行分类 （build tags, 环境变量，短模式）(#82)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#race-83\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不打开 race 开关 (#83)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#parallel-shuffle-84\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不打开测试的执行模式开关 (parallel 和 shuffle) (#84)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#85\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用表驱动的测试 (#85)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#sleep-86\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      在单元测试中执行 sleep 操作 (#86)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#time-api-87\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      没有高效地处理 time API (#87)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#httptest-iotest-88\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用测试相关的工具包 (httptest 和 iotest) (#88)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#89\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不正确的基准测试 (#89)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-test-90\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      没有去探索 go test 所有的特性 (#90)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#_11\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用模糊测试 (社区反馈错误)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_12\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      优化技术\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"优化技术\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#cpu-cache-91\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不理解 CPU cache (#91)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#false-sharing-92\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      写的并发处理逻辑会导致 false sharing (#92)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#93\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      没有考虑指令级的并行 (#93)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#94\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不了解数据对齐 (#94)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#stack-vs-heap-95\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不了解 stack vs. heap (#95)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#api-syncpool-96\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不知道如何减少内存分配次数（API 调整，编译器优化和 sync.Pool） (#96)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#97\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不注意使用内联 (#97)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-98\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用 Go 问题诊断工具 (#98)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#gc-99\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不理解 GC 是如何工作的 (#99)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#docker-k8s-go-100\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不了解 Docker 或者 K8S 对运行的 Go 应用的性能影响 (#100)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n      \n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../ja/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇯🇵 日本語\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../pt-br/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    🇧🇷 Português Brasileiro\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    \n    \n    \n    \n      \n      \n        \n      \n    \n    \n    <li class=\"md-nav__item md-nav__item--nested\">\n      \n        \n        \n          \n        \n        <input class=\"md-nav__toggle md-toggle md-toggle--indeterminate\" type=\"checkbox\" id=\"__nav_2\">\n        \n          \n          <label class=\"md-nav__link\" for=\"__nav_2\" id=\"__nav_2_label\" tabindex=\"0\">\n            \n  \n  \n  <span class=\"md-ellipsis\">\n    Book Details\n    \n  </span>\n  \n\n            <span class=\"md-nav__icon md-icon\"></span>\n          </label>\n        \n        <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_2_label\" aria-expanded=\"false\">\n          <label class=\"md-nav__title\" for=\"__nav_2\">\n            <span class=\"md-nav__icon md-icon\"></span>\n            Book Details\n          </label>\n          <ul class=\"md-nav__list\" data-md-scrollfix>\n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../book/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    100 Go Mistakes and How to Avoid Them\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../chapter-1/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    Read the First Chapter\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n              \n                \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"../external/\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    External Resources\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n              \n            \n          </ul>\n        </nav>\n      \n    </li>\n  \n\n    \n      \n      \n  \n  \n  \n  \n    <li class=\"md-nav__item\">\n      <a href=\"https://www.thecoder.cafe/p/100-go-mistakes\" class=\"md-nav__link\">\n        \n  \n  \n  <span class=\"md-ellipsis\">\n    The Story Behind 100 Go Mistakes\n    \n  </span>\n  \n\n      </a>\n    </li>\n  \n\n    \n  </ul>\n</nav>\n                  </div>\n                </div>\n              </div>\n            \n            \n              \n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    \n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"Table of contents\">\n  \n  \n  \n    \n  \n  \n    <label class=\"md-nav__title\" for=\"__toc\">\n      <span class=\"md-nav__icon md-icon\"></span>\n      Table of contents\n    </label>\n    <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      代码及工程组织\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"代码及工程组织\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#1\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      意外的变量隐藏 (#1)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#2\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不必要的代码嵌套 (#2)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#init-3\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      误用 init 函数 (#3)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#getterssetters-4\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      滥用 getters/setters (#4)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#5\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      接口污染 (#5)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#6\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      将接口定义在实现方一侧 (#6)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#7\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      将接口作为返回值 (#7)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#any-8\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      any 没传递任何信息 (#8)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#9\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      困惑何时该用范型 (#9)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#10\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      未意识到类型嵌套的可能问题 (#10)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#function-option-11\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用 function option 模式 (#11)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#12\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      工程组织不合理 (工程结构和包的组织) (#12)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#13\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      创建工具包 (#13)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#14\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忽略了包名冲突 (#14)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#15\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      代码缺少文档 (#15)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#linters-16\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用 linters 检查 (#16)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_2\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      数据类型\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"数据类型\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#17\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      八进制字面量引发的困惑 (#17)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#18\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      未注意可能的整数溢出 (#18)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#19\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      没有透彻理解浮点数 (#19)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-20\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不理解 slice 的长度和容量 (#20)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-21\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不高效的 slice 初始化 (#21)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nil-slice-22\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      困惑于 nil 和空 slice (#22)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-23\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      没有适当检查 slice 是否为空 (#23)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-24\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      没有正确拷贝 slice (#24)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-append-25\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      slice append 带来的预期之外的副作用 (#25)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#slice-26\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      slice 和内存泄漏 (#26)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#map-27\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不高效的 map 初始化 (#27)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#map-28\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      map 和内存泄漏 (#28)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#29\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不正确的值比较 (#29)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_3\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      控制结构\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"控制结构\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#range-30\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忽略了 range 循环变量是一个拷贝 (#30)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#range-channels-arrays-31\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忽略了 range 循环中迭代目标值的计算方式 (channels 和 arrays) (#31)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#range-32\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忽略了 range 循环中指针元素的影响 (#32)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#map-33\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      map 迭代过程中的错误假设（遍历顺序和迭代过程中插入）(#33)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#break-34\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忽略了 break 语句是如何工作的 (#34)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#defer-35\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      在循环中使用 defer (#35)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_4\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      字符串\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"字符串\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#rune-36\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      没有理解 rune (#36)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#37\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不正确的字符串遍历 (#37)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#trim-38\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      误用 trim 函数 (#38)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#39\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不经优化的字符串拼接操作 (#39)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#40\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      无用的字符串转换 (#40)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#41\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      子字符串和内存泄漏 (#41)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_5\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      函数和方法\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"函数和方法\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#42\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不知道使用哪种接收器类型 (#42)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#43\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      从不使用命名的返回值 (#43)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#44\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      使用命名的返回值时预期外的副作用 (#44)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nil-45\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      返回一个 nil 接收器 (#45)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#46\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      使用文件名作为函数入参 (#46)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#defer-value-47\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忽略 defer 语句中参数、接收器值的计算方式 (参数值计算, 指针, 和 value 类型接收器) (#47)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_6\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      错误管理\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"错误管理\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#panicking-48\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      Panicking (#48)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#error-49\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      未考虑何时才应该包装 error (#49)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#50\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不正确的错误类型比较 (#50)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#51\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不正确的错误对象值比较 (#51)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#52\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      两次处理同一个错误 (#52)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#53\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不处理错误 (#53)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#defer-54\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不处理 defer 中的错误 (#54)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_7\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      并发编程: 基础\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"并发编程: 基础\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#55\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      混淆并发和并行 (#55)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#56\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      认为并发总是更快 (#56)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#channels-mutexes-57\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不清楚何时使用 channels 或 mutexes (#57)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#vs-go-58\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不明白竞态问题 (数据竞态 vs. 竞态条件和 Go 内存模型) (#58)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#59\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不理解不同工作负载类型对并发的影响 (#59)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-contexts-60\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      误解了 Go contexts (#60)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_8\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      并发编程: 实践\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"并发编程: 实践\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#context-61\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      传递不合适的 context (#61)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#goroutine-62\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      启动了一个 goroutine 但是不知道它何时会停止 (#62)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#goroutines-63\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不注意处理 goroutines 和循环中的迭代变量 (#63)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#select-channels-64\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      使用 select + channels 时误以为分支选择顺序是确定的 (#64)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#channels-65\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不正确使用通知 channels (#65)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#nil-channels-66\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用 nil channels (#66)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#channel-size-67\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不清楚该如何确定 channel size (#67)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#etcd-68\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忘记了字符串格式化可能带来的副作用（例如 etcd 数据竞争和死锁）(#68)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#append-69\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      使用 append 不当导致数据竞争 (#69)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#mutexes-slicesmaps-70\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      误用 mutexes 和 slices、maps (#70)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#syncwaitgroup-71\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      误用 sync.WaitGroup (#71)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#synccond-72\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      忘记使用 sync.Cond (#72)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#errgroup-73\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用 errgroup (#73)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#sync-74\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      拷贝一个 sync 下的类型 (#74)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_9\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      标准库\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"标准库\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#timeduration-75\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      使用了错误的 time.Duration (#75)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#timeafter-76\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      time.After 和内存泄漏 (#76)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#json-77\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      JSON 处理中的常见错误 (#77)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#sql-78\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      常见的 SQL 错误 (#78)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#http-sqlrows-osfile-79\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不关闭临时资源（HTTP 请求体、sql.Rows 和 os.File） (#79)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#http-80\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      响应 HTTP 请求后没有返回语句 (#80)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#http-client-server-81\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      直接使用默认的 HTTP client 和 server (#81)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_10\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      测试\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"测试\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#build-tags-82\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不对测试进行分类 （build tags, 环境变量，短模式）(#82)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#race-83\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不打开 race 开关 (#83)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#parallel-shuffle-84\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不打开测试的执行模式开关 (parallel 和 shuffle) (#84)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#85\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用表驱动的测试 (#85)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#sleep-86\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      在单元测试中执行 sleep 操作 (#86)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#time-api-87\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      没有高效地处理 time API (#87)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#httptest-iotest-88\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用测试相关的工具包 (httptest 和 iotest) (#88)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#89\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不正确的基准测试 (#89)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-test-90\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      没有去探索 go test 所有的特性 (#90)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#_11\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用模糊测试 (社区反馈错误)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n        <li class=\"md-nav__item\">\n  <a href=\"#_12\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      优化技术\n    </span>\n  </a>\n  \n    <nav class=\"md-nav\" aria-label=\"优化技术\">\n      <ul class=\"md-nav__list\">\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#cpu-cache-91\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不理解 CPU cache (#91)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#false-sharing-92\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      写的并发处理逻辑会导致 false sharing (#92)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#93\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      没有考虑指令级的并行 (#93)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#94\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不了解数据对齐 (#94)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#stack-vs-heap-95\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不了解 stack vs. heap (#95)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#api-syncpool-96\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不知道如何减少内存分配次数（API 调整，编译器优化和 sync.Pool） (#96)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#97\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不注意使用内联 (#97)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#go-98\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不使用 Go 问题诊断工具 (#98)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#gc-99\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不理解 GC 是如何工作的 (#99)\n    </span>\n  </a>\n  \n</li>\n        \n          <li class=\"md-nav__item\">\n  <a href=\"#docker-k8s-go-100\" class=\"md-nav__link\">\n    <span class=\"md-ellipsis\">\n      不了解 Docker 或者 K8S 对运行的 Go 应用的性能影响 (#100)\n    </span>\n  </a>\n  \n</li>\n        \n      </ul>\n    </nav>\n  \n</li>\n      \n    </ul>\n  \n</nav>\n                  </div>\n                </div>\n              </div>\n            \n          \n          \n            <div class=\"md-content\" data-md-component=\"content\">\n              <article class=\"md-content__inner md-typeset\">\n                \n                  \n\n\n  \n  \n\n\n<h1 id=\"100-go\">100 个 Go 常见错误及如何避免</h1>\n<details class=\"tip\" open=\"open\">\n<summary>The Coder Cafe</summary>\n<p>如果您喜欢我的书，您可能会对我的最新项目感兴趣：<a href=\"https://thecoder.cafe?rd=100go.co/zh\">The Coder Cafe</a>，这是一个为程序员提供的每日简报。</p>\n<blockquote>\n<p>Feeling overwhelmed by the endless stream of tech content? At The Coder Cafe, we serve one essential concept for coders. Written by a senior software engineer at Google, it's perfectly brewed for your morning coffee, helping you grow your skills deeply.</p>\n</blockquote>\n<p></p><center><a href=\"https://thecoder.cafe?rd=100go.co/zh\"><img src=\"../img/thecodercafe.png\" alt=\"\" style=\"width:480px;height:240px;\"></a></center><p></p>\n</details>\n<p><a class=\"glightbox\" data-type=\"image\" data-width=\"auto\" data-height=\"auto\" href=\"../img/inside-cover.png\" data-desc-position=\"bottom\"><img alt=\"\" src=\"../img/inside-cover.png\"></a></p>\n<h2 id=\"_1\">代码及工程组织</h2>\n<h3 id=\"1\">意外的变量隐藏 (#1)</h3>\n<p>避免变量隐藏（外部作用域变量被内部作用域同名变量隐藏），有助于避免变量引用错误，有助于他人阅读理解。</p>\n<h3 id=\"2\">不必要的代码嵌套 (#2)</h3>\n<p>避免不必要的、过多的嵌套层次，并且让正常代码路径尽量左对齐（而不是放在分支路径中），有助于构建可读性更好的代码。</p>\n<h3 id=\"init-3\">误用 init 函数 (#3)</h3>\n<p>初始化变量时，请记住 init 函数具有有限的错误处理能力，并且会使状态处理和测试变得更加复杂。在大多数情况下，初始化应该作为特定函数来处理。</p>\n<h3 id=\"getterssetters-4\">滥用 getters/setters (#4)</h3>\n<p>在 Go 语言中，强制使用 getter 和 setter 方法并不符合 Go 惯例。在实践中，应该找到效率和盲目遵循某些惯用法之间的平衡点。</p>\n<h3 id=\"5\">接口污染 (#5)</h3>\n<p>抽象应该被发现，而不是被创造。为了避免不必要的复杂性，需要时才创建接口，而不是预见到需要它，或者至少可以证明这种抽象是有价值的。</p>\n<h3 id=\"6\">将接口定义在实现方一侧 (#6)</h3>\n<p>将接口保留在引用方一侧（而不是实现方一侧）可以避免不必要的抽象。</p>\n<h3 id=\"7\">将接口作为返回值 (#7)</h3>\n<p>为了避免在灵活性方面受到限制，大多数情况下函数不应该返回接口，而应该返回具体的实现。相反，函数应该尽可能地使用接口作为参数。</p>\n<h3 id=\"any-8\"><code>any</code> 没传递任何信息 (#8)</h3>\n<p>只有在需要接受或返回任意类型时，才使用 <code>any</code>，例如 <code>json.Marshal</code>。其他情况下，因为 <code>any</code> 不提供有意义的信息，可能会导致编译时问题，如允许调用者调用方法处理任意类型数据。</p>\n<h3 id=\"9\"><a href=\"https://100go.co/9-generics/\">困惑何时该用范型</a> (#9)</h3>\n<p>使用泛型，可以通过类型参数分离具体的数据类型和行为，避免写很多重复度很高的代码。然而，不要过早地使用泛型、类型参数，只有在你看到真正需要时才使用。否则，它们会引入不必要的抽象和复杂性。</p>\n<h3 id=\"10\">未意识到类型嵌套的可能问题 (#10)</h3>\n<p>使用类型嵌套也可以避免写一些重复代码，然而，在使用时需要确保不会导致不合理的可见性问题，比如有些字段应该对外隐藏不应该被暴露。</p>\n<h3 id=\"function-option-11\">不使用 function option 模式 (#11)</h3>\n<p>为了设计并提供更友好的 API（可选参数），为了更好地处理选项，应该使用 function option 模式。</p>\n<h3 id=\"12\">工程组织不合理 (工程结构和包的组织) (#12)</h3>\n<p>遵循像 project-layout 的建议来组织 Go 工程是一个不错的方法，尤其是你正在寻找一些类似的经验、惯例来组织一个新的 Go 工程的时候。</p>\n<h3 id=\"13\">创建工具包 (#13)</h3>\n<p>命名是软件设计开发中非常重要的一个部分，创建一些名如 <code>common</code>、<code>util</code>、<code>shared</code> 之类的包名并不会给读者带来太大价值，应该将这些包名重构为更清晰、更具体的包名。</p>\n<h3 id=\"14\">忽略了包名冲突 (#14)</h3>\n<p>为了避免变量名和包名之间的冲突，导致混淆或甚至错误，应为每个变量和包使用唯一的名称。如果这不可行，可以考虑使用导入别名 <code>import importAlias 'importPath'</code> 以区分包名和变量名，或者考虑一个更好的变量名。</p>\n<h3 id=\"15\">代码缺少文档 (#15)</h3>\n<p>为了让使用方、维护人员能更清晰地了解你的代码的意图，导出的元素（函数、类型、字段）需要添加注释。</p>\n<h3 id=\"linters-16\">不使用 linters 检查 (#16)</h3>\n<p>为了改善代码质量、整体代码的一致性，应该使用 linters 和 formatters。</p>\n<h2 id=\"_2\">数据类型</h2>\n<h3 id=\"17\">八进制字面量引发的困惑 (#17)</h3>\n<p>在阅读现有代码时，请记住以 0 开头的整数字面量是八进制数。此外，为了提高可读性，可以通过在前面加上 0o 来显式地表示八进制整数。</p>\n<h3 id=\"18\">未注意可能的整数溢出 (#18)</h3>\n<p>在 Go 中整数上溢出和下溢是静默处理的，所以你可以实现自己的函数来捕获它们。</p>\n<h3 id=\"19\">没有透彻理解浮点数 (#19)</h3>\n<p>比较浮点数时，通过比较二者的 delta 值是否介于一定的范围内，能让你写出可移植性更好的代码。</p>\n<p>在进行加法或减法时，将具有相似数量级的操作分成同一组以提高精度 (过早指数对齐丢失精度)。此外，在进行加法和减法之前，应先进行乘法和除法 (加减法误差会被乘除放大)。</p>\n<h3 id=\"slice-20\"><a href=\"https://100go.co/20-slice/\">不理解 slice 的长度和容量</a> (#20)</h3>\n<p>理解 slice 的长度和容量的区别，是一个 Go 开发者的核心知识点之一。slice 的长度指的是 slice 已经存储的元素的数量，而容量指的是 slice 当前底层开辟的数组最多能容纳的元素的数量。</p>\n<h3 id=\"slice-21\">不高效的 slice 初始化 (#21)</h3>\n<p>当创建一个 slice 时，如果其长度可以预先确定，那么可以在定义时指定它的长度和容量。这可以改善后期 append 时一次或者多次的内存分配操作，从而改善性能。对于 map 的初始化也是如此。</p>\n<h3 id=\"nil-slice-22\">困惑于 nil 和空 slice (#22)</h3>\n<p>为了避免常见的对 nil 和 empty slice 处理行为的混淆，例如在使用 encoding/json 或 reflect 包时，你需要理解 nil 和 empty slice 的区别。两者都是长度为零、容量为零的切片，但是 nil 切片不需要分配内存。</p>\n<h3 id=\"slice-23\">没有适当检查 slice 是否为空 (#23)</h3>\n<p>检查一个 slice 是否包含任何元素，可以检查其长度，不管 slice 是 nil 还是 empty，检查长度都是有效的。这个检查方法也适用于 map。</p>\n<p>为了设计更明确的 API，API 不应区分 nil 和空切片。</p>\n<h3 id=\"slice-24\">没有正确拷贝 slice (#24)</h3>\n<p>使用 <code>copy</code> 拷贝一个 slice 元素到另一个 slice 时，需要记得，实际拷贝的元素数量是二者 slice 长度中的较小值。</p>\n<h3 id=\"slice-append-25\">slice append 带来的预期之外的副作用 (#25)</h3>\n<p>如果两个不同的函数操作的 slice 复用了相同的底层数组，它们对 slice 执行 append 操作时可能会产生冲突。使用 copy 来完整复制一个 slice 或者使用完整的 slice 表达式 <code>[low:high:max]</code> 限制最大容量，有助于避免产生冲突。当想对一个大 slice 进行 shrink 操作时，两种方式中，只有 copy 才可以避免内存泄漏。</p>\n<h3 id=\"slice-26\">slice 和内存泄漏 (#26)</h3>\n<p>对于 slice 元素为指针，或者 slice 元素为 struct 但是该 struct 含有指针字段，当通过 <code>slice[low:high]</code> 操作取 subslice 时，对于那些不可访问的元素可以显式设置为 nil 来避免内存泄露。</p>\n<h3 id=\"map-27\">不高效的 map 初始化 (#27)</h3>\n<p>见 <a href=\"#inefficient-slice-initialization-21\">#21</a>.</p>\n<h3 id=\"map-28\"><a href=\"https://100go.co/28-maps-memory-leaks/\">map 和内存泄漏</a> (#28)</h3>\n<p>一个 map 的 buckets 占用的内存只会增长，不会缩减。因此，如果它导致了一些内存占用的问题，你需要尝试不同的方式来解决，比如重新创建一个 map 代替原来的（原来的 map 会被 <abbr title=\"Garbage Collector\">GC</abbr> 掉），或者 <code>map[keyType]valueType</code> 中的 valueType 使用指针代替长度固定的数组或者 sliceHeader 来缓解过多的内存占用。</p>\n<h3 id=\"29\">不正确的值比较 (#29)</h3>\n<p>Go 中比较两个类型值时，如果是可比较类型，那么可以使用 <code>==</code> 或者 <code>!=</code> 运算符进行比较，比如：booleans、numerals、strings、pointers、channels，以及字段全部是可比较类型的 structs。其他情况下，你可以使用 <code>reflect.DeepEqual</code> 来比较，用反射的话会牺牲一点性能，也可以使用自定义的实现和其他库来完成。</p>\n<h2 id=\"_3\">控制结构</h2>\n<h3 id=\"range-30\">忽略了 <code>range</code> 循环变量是一个拷贝 (#30)</h3>\n<p><code>range</code> 循环中的循环变量是遍历容器中元素值的一个拷贝。因此，如果元素值是一个 struct 并且想在 <code>range</code> 中修改它，可以通过索引值来访问并修改它，或者使用经典的 for 循环+索引值的写法（除非遍历的元素是一个指针）。</p>\n<h3 id=\"range-channels-arrays-31\">忽略了 <code>range</code> 循环中迭代目标值的计算方式 (channels 和 arrays) (#31)</h3>\n<p>传递给 <code>range</code> 操作的迭代目标对应的表达式的值，只会在循环执行前被计算一次，理解这个有助于避免犯一些常见的错误，例如不高效的 channel 赋值操作和 slice 迭代操作。</p>\n<h3 id=\"range-32\">忽略了 <code>range</code> 循环中指针元素的影响 (#32)</h3>\n<p>这里其实强调的是 <code>range</code> 迭代过程中，迭代变量实际上是一个拷贝。假设给另外一个容器元素（指针类型）赋值，且需要对迭代变量取地址转换成指针再赋值的话，这里潜藏着一个错误，就是 for 循环迭代变量是 per-variable-per-loop 而不是 per-variable-per-iteration。如果是通过局部变量（用迭代变量来初始化）或者使用索引值来直接引用迭代的元素，将有助于避免拷贝指针(迭代变量的地址)之类的 bug。</p>\n<h3 id=\"map-33\">map 迭代过程中的错误假设（遍历顺序和迭代过程中插入）(#33)</h3>\n<p>使用 map 时，为了能得到确定一致的结果，应该记住 Go 中的 map 数据结构：\n* 不会按照 key 对 data 进行排序，遍历时 key 不是有序的；\n* 遍历时的顺序，也不是按照插入时的顺序；\n* 没有一个确定性的遍历顺序，每次遍历顺序是不同的；\n* 不能保证迭代过程中新插入的元素，在当前迭代中能够被遍历到；</p>\n<h3 id=\"break-34\">忽略了 <code>break</code> 语句是如何工作的 (#34)</h3>\n<p>配合 label 使用 <code>break</code> 和 <code>continue</code>，能够跳过一个特定的语句，在某些循环中存在 <code>switch</code> 和 <code>select</code> 语句的场景中就比较有帮助。</p>\n<h3 id=\"defer-35\">在循环中使用 <code>defer</code>  (#35)</h3>\n<p>在循环中使用 defer 不能在每轮迭代结束时执行 defer 语句，但是将循环逻辑提取到函数内部会在每次迭代结束时执行 defer 语句。</p>\n<h2 id=\"_4\">字符串</h2>\n<h3 id=\"rune-36\">没有理解 rune (#36)</h3>\n<p>理解 rune 类型对应的是一个 unicode 码点，每一个 unicode 码点其实是一个多字节的序列，不是一个 byte。这应该是 Go 开发者的核心知识点之一，理解了这个有助于更准确地处理字符串。</p>\n<h3 id=\"37\">不正确的字符串遍历 (#37)</h3>\n<p>使用 <code>range</code> 操作符对一个 string 进行遍历实际上是对 string 对应的 <code>[]rune</code> 进行遍历，迭代变量中的索引值，表示的当前 rune 对应的 <code>[]rune</code> 在整个 <code>[]rune(string)</code> 中的起始索引。如果要访问 string 中的某一个 rune（比如第三个），首先要将字符串转换为 <code>[]rune</code> 然后再按索引值访问。</p>\n<h3 id=\"trim-38\">误用 trim 函数 (#38)</h3>\n<p><code>strings.TrimRight</code>/<code>strings.TrimLeft</code> 移除在字符串尾部或者开头出现的一些 runes，函数会指定一个 rune 集合，出现在集合中的 rune 将被从字符串移除。而 <code>strings.TrimSuffix</code>/<code>strings.TrimPrefix</code> 是移除字符串的一个后缀/前缀。</p>\n<h3 id=\"39\">不经优化的字符串拼接操作 (#39)</h3>\n<p>对一个字符串列表进行遍历拼接操作，应该通过 <code>strings.Builder</code> 来完成，以避免每次迭代拼接时都分配一个新的 string 对象出来。</p>\n<h3 id=\"40\">无用的字符串转换 (#40)</h3>\n<p><code>bytes</code> 包提供了一些和 <code>strings</code> 包相似的操作，可以帮助避免 []byte/string 之间的转换。</p>\n<h3 id=\"41\">子字符串和内存泄漏 (#41)</h3>\n<p>使用一个子字符串的拷贝，有助于避免内存泄漏，因为对一个字符串的 <code>s[low:high]</code> 操作返回的子字符串，其使用了和原字符串 s 相同的底层数组。</p>\n<h2 id=\"_5\">函数和方法</h2>\n<h3 id=\"42\">不知道使用哪种接收器类型 (#42)</h3>\n<p>对于接收器类型是采用 value 类型还是 pointer 类型，应该取决于下面这几种因素，比如：方法内是否会对它进行修改，它是否包含了一个不能被拷贝的字段，以及它表示的对象有多大。如果有疑问，接收器可以考虑使用 pointer 类型。</p>\n<h3 id=\"43\">从不使用命名的返回值 (#43)</h3>\n<p>使用命名的返回值，是一种有效改善函数、方法可读性的方法，特别是返回值列表中有多个类型相同的参数。另外，因为返回值列表中的参数是经过零值初始化过的，某些场景下也会简化函数、方法的实现。但是需要注意它的一些潜在副作用。</p>\n<h3 id=\"44\">使用命名的返回值时预期外的副作用 (#44)</h3>\n<p>见 <a href=\"#从不使用命名的返回值-43\">#43</a>.</p>\n<p>使用命名的返回值，因为它已经被初始化了零值，需要注意在某些情况下异常返回时是否需要给它赋予一个不同的值，比如返回值列表定义了一个有名参数 <code>err error</code>，需要注意 <code>return err</code> 时是否正确地对 <code>err</code> 进行了赋值。</p>\n<h3 id=\"nil-45\">返回一个 nil 接收器 (#45)</h3>\n<p>当返回一个 interface 参数时，需要小心，不要返回一个 nil 指针，而是应该显式返回一个 nil 值。否则，可能会发生一些预期外的问题，因为调用方会收到一个非 nil 的值。</p>\n<h3 id=\"46\">使用文件名作为函数入参 (#46)</h3>\n<p>设计函数时使用 <code>io.Reader</code> 类型作为入参，而不是文件名，将有助于改善函数的可复用性、易测试性。</p>\n<h3 id=\"defer-value-47\">忽略 <code>defer</code> 语句中参数、接收器值的计算方式 (参数值计算, 指针, 和 value 类型接收器) (#47)</h3>\n<p>为了避免 <code>defer</code> 语句执行时就立即对 defer 要执行的函数的参数进行计算，可以考虑将要执行的函数放到闭包里面，然后通过指针传递参数给闭包内函数（或者通过闭包捕获外部变量），来解决这个问题。</p>\n<h2 id=\"_6\">错误管理</h2>\n<h3 id=\"panicking-48\">Panicking (#48)</h3>\n<p>使用 <code>panic</code> 是 Go 中一种处理错误的方式，但是只能在遇到不可恢复的错误时使用，例如：通知开发人员一个强依赖的模块加载失败了。</p>\n<h3 id=\"error-49\">未考虑何时才应该包装 error (#49)</h3>\n<p>Wrapping（包装）错误允许您标记错误、提供额外的上下文信息。然而，包装错误会创建潜在的耦合，因为它使得原来的错误对调用者可见。如果您想要防止这种情况，请不要使用包装错误的方式。</p>\n<h3 id=\"50\">不正确的错误类型比较 (#50)</h3>\n<p>如果你使用 Go 1.13 引入的特性 <code>fmt.Errorf</code> + <code>%w</code> 来包装一个错误，当进行错误比较时，如果想判断该包装后的错误是不是指定的错误类型，就需要使用 <code>errors.As</code>，如果想判断是不是指定的 error 对象就需要用 <code>errors.Is</code>。</p>\n<h3 id=\"51\">不正确的错误对象值比较 (#51)</h3>\n<p>见 <a href=\"#不正确的错误类型比较-50\">#50</a>.</p>\n<p>为了表达一个预期内的错误，请使用错误值的方式，并通过 <code>==</code> 或者 <code>errors.Is</code> 来比较。而对于意外错误，则应使用特定的错误类型（可以通过 <code>errors.As</code> 来比较）。</p>\n<h3 id=\"52\">两次处理同一个错误 (#52)</h3>\n<p>大多数情况下，错误仅需要处理一次。打印错误日志也是一种错误处理。因此，当函数内发生错误时，应该在打印日志和返回错误中选择其中一种。包装错误也可以提供问题发生的额外上下文信息，也包括了原来的错误（可考虑交给调用方负责打日志）。</p>\n<h3 id=\"53\">不处理错误 (#53)</h3>\n<p>不管是在函数调用时，还是在一个 <code>defer</code> 函数执行时，如果想要忽略一个错误，应该显式地通过 <code>_</code> 来忽略（可注明忽略的原因）。否则，将来的读者就会感觉到困惑，忽略这个错误是有意为之还是无意中漏掉了。</p>\n<h3 id=\"defer-54\">不处理 <code>defer</code> 中的错误 (#54)</h3>\n<p>大多数情况下，你不应该忽略 <code>defer</code> 函数执行时返回的错误，或者显式处理它，或者将它传递给调用方处理，可以根据情景进行选择。如果你确定要忽略这个错误，请显式使用 <code>_</code> 来忽略。</p>\n<h2 id=\"_7\">并发编程: 基础</h2>\n<h3 id=\"55\">混淆并发和并行 (#55)</h3>\n<p>理解并发（concurrency）、并行（parallelism）之间的本质区别是 Go 开发人员必须要掌握的。并发是关于结构设计上的，并行是关于具体执行上的。</p>\n<h3 id=\"56\"><a href=\"https://100go.co/56-concurrency-faster/\">认为并发总是更快</a> (#56)</h3>\n<p>要成为一名熟练的开发人员，您必须意识到并非所有场景下都是并发的方案更快。对于任务中的最小工作负载部分，对它们进行并行化处理并不一定就有明显收益或者比串行化方案更快。对串行化、并发方案进行 benchmark 测试，是验证假设的好办法。</p>\n<h3 id=\"channels-mutexes-57\">不清楚何时使用 channels 或 mutexes (#57)</h3>\n<p>了解 goroutine 之间的交互也可以在选择使用 channels 或 mutexes 时有所帮助。一般来说，并行的 goroutine 需要同步，因此需要使用 mutexes。相反，并发的 goroutine 通常需要协调和编排，因此需要使用 channels。</p>\n<h3 id=\"vs-go-58\">不明白竞态问题 (数据竞态 vs. 竞态条件和 Go 内存模型) (#58)</h3>\n<p>掌握并发意味着要认识到数据竞争（data races）和竞态条件（race conditions）是两个不同的概念。数据竞争，指的是有多个 goroutines 同时访问相同内存区域时，缺乏必要的同步控制，且其中至少有一个 goroutine 执行的是写操作。同时要认识到，没有发生数据竞争不代表程序的执行是确定性的、没问题的。当在某个特定的操作顺序或者特定的事件发生顺序下，如果最终的行为是不可控的，这就是竞态条件。</p>\n<blockquote>\n<p>ps：数据竞争是竞态条件的子集，竞态条件不仅局限于访存未同步，它可以发生在更高的层面。<code>go test -race</code> 检测的是数据竞争，需要同步来解决，而开发者还需要关注面更广的竞态条件，它需要对多个 goroutines 的执行进行编排。</p>\n</blockquote>\n<p>理解 Go 的内存模型以及有关顺序和同步的底层保证是防止可能的数据竞争和竞态条件的关键。</p>\n<h3 id=\"59\">不理解不同工作负载类型对并发的影响 (#59)</h3>\n<p>当创建一定数量的 goroutines 时，需要考虑工作负载的类型。如果工作负载是 CPU 密集型的，那么 goroutines 数量应该接近于 <code>GOMAXPROCS</code> 的值（该值取决于主机处理器核心数）。如果工作负载是 IO 密集型的，goroutines 数量就需要考虑多种因素，比如外部系统（考虑请求、响应速率）。</p>\n<h3 id=\"go-contexts-60\">误解了 Go contexts (#60)</h3>\n<p>Go 的上下文（context）也是 Go 并发编程的基石之一。上下文允许您携带截止时间、取消信号和键值列表。</p>\n<h2 id=\"_8\">并发编程: 实践</h2>\n<h3 id=\"context-61\">传递不合适的 context (#61)</h3>\n<p>当我们传递了一个 context，我们需要知道这个 context 什么时候可以被取消，这点很重要，例如：一个 HTTP 请求处理器在发送完响应后取消 context。</p>\n<blockquote>\n<p>ps: 实际上 context 表达的是一个动作可以持续多久之后被停止。</p>\n</blockquote>\n<h3 id=\"goroutine-62\">启动了一个 goroutine 但是不知道它何时会停止 (#62)</h3>\n<p>避免 goroutine 泄漏，要有这种意识，当创建并启动一个 goroutine 的时候，应该有对应的设计让它能正常退出。</p>\n<h3 id=\"goroutines-63\">不注意处理 goroutines 和循环中的迭代变量 (#63)</h3>\n<p>为了避免 goroutines 和循环中的迭代变量问题，可以考虑创建局部变量并将迭代变量赋值给局部变量，或者 goroutines 调用带参数的函数，将迭代变量值作为参数值传入，来代替 goroutines 调用闭包。</p>\n<h3 id=\"select-channels-64\">使用 select + channels 时误以为分支选择顺序是确定的 (#64)</h3>\n<p>要明白，<code>select</code> 多个 channels 时，如果多个 channels 上的操作都就绪，那么会随机选择一个 <code>case</code> 分支来执行，因此要避免有分支选择顺序是从上到下的这种错误预设，这可能会导致设计上的 bug。</p>\n<h3 id=\"channels-65\">不正确使用通知 channels (#65)</h3>\n<p>发送通知时使用 <code>chan struct{}</code> 类型。</p>\n<blockquote>\n<p>ps: 先明白什么是通知 channels，一个通知 channels 指的是只是用来做通知，而其中传递的数据没有意义，或者理解成不传递数据的 channels，这种称为通知 channels。其中传递的数据的类型为 struct{} 更合适。</p>\n</blockquote>\n<h3 id=\"nil-channels-66\">不使用 nil channels (#66)</h3>\n<p>使用 nil channels 应该是并发处理方式中的一部分，例如，它能够帮助禁用 <code>select</code> 语句中的特定的分支。</p>\n<h3 id=\"channel-size-67\">不清楚该如何确定 channel size (#67)</h3>\n<p>根据指定的场景仔细评估应该使用哪一种 channel 类型（带缓冲的，不带缓冲的）。只有不带缓冲的 channels 可以提供强同步保证。</p>\n<p>使用带缓冲的 channels 时如果不确定 size 该如何设置，可以先设为 1，如果有合理的理由再去指定 channels size。</p>\n<blockquote>\n<p>ps: 根据 disruptor 这个高性能内存消息队列的实践，在某种读写 pacing 下，队列要么满要么空，不大可能处于某种介于中间的稳态。</p>\n</blockquote>\n<h3 id=\"etcd-68\">忘记了字符串格式化可能带来的副作用（例如 etcd 数据竞争和死锁）(#68)</h3>\n<p>意识到字符串格式化可能会导致调用现有函数，这意味着需要注意可能的死锁和其他数据竞争问题。</p>\n<blockquote>\n<p>ps: 核心是要关注 <code>fmt.Sprintf</code> + <code>%v</code> 进行字符串格式化时 <code>%v</code> 具体到不同的类型值时，实际上执行的操作是什么。比如 <code>%v</code> 这个 placeholder 对应的值是一个 <code>context.Context</code>，那么会就遍历其通过 <code>context.WithValue</code> 附加在其中的 values，这个过程可能涉及到数据竞争问题。书中提及的另一个导致死锁的案例本质上也是一样的问题，只不过又额外牵扯到了 <code>sync.RWMutex</code> 不可重入的问题。</p>\n</blockquote>\n<h3 id=\"append-69\">使用 append 不当导致数据竞争 (#69)</h3>\n<p>调用 <code>append</code> 不总是没有数据竞争的，因此不要在一个共享的 <code>slice</code> 上并发地执行 <code>append</code>。</p>\n<h3 id=\"mutexes-slicesmaps-70\">误用 mutexes 和 slices、maps (#70)</h3>\n<p>请记住 slices 和 maps 是引用类型，有助于避免常见的数据竞争问题。</p>\n<blockquote>\n<p>ps: 这里实际是因为错误理解了 slices 和 maps，导致写出了错误地拷贝 slices 和 maps 的代码，进而导致锁保护无效、出现数据竞争问题。</p>\n</blockquote>\n<h3 id=\"syncwaitgroup-71\">误用 <code>sync.WaitGroup</code> (#71)</h3>\n<p>正确地使用 <code>sync.WaitGroup</code> 需要在启动 goroutines 之前先调用 <code>Add</code> 方法。</p>\n<h3 id=\"synccond-72\">忘记使用 <code>sync.Cond</code> (#72)</h3>\n<p>你可以使用 <code>sync.Cond</code> 向多个 goroutines 发送重复的通知。</p>\n<h3 id=\"errgroup-73\">不使用 <code>errgroup</code> (#73)</h3>\n<p>你可以使用 <code>errgroup</code> 包来同步一组 goroutines 并处理错误和上下文。</p>\n<h3 id=\"sync-74\">拷贝一个 <code>sync</code> 下的类型 (#74)</h3>\n<p><code>sync</code> 包下的类型不应该被拷贝。</p>\n<h2 id=\"_9\">标准库</h2>\n<h3 id=\"timeduration-75\">使用了错误的 time.Duration (#75)</h3>\n<p>注意有些函数接收一个 <code>time.Duration</code> 类型的参数时，尽管直接传递一个整数是可以的，但最好还是使用 time API 中的方法来传递 duration，以避免可能造成的困惑和 bug。</p>\n<blockquote>\n<p>ps: 重点是注意 time.Duration 定义的是 nanoseconds 数。</p>\n</blockquote>\n<h3 id=\"timeafter-76\"><code>time.After</code> 和内存泄漏 (#76)</h3>\n<p>避免在重复执行很多次的函数（如循环中或 HTTP 处理函数）中调用 <code>time.After</code>，这可以避免内存峰值消耗。由 <code>time.After</code> 创建的资源仅在计时器超时才会被释放。</p>\n<h3 id=\"json-77\">JSON 处理中的常见错误 (#77)</h3>\n<ul>\n<li>类型嵌套导致的预料外的行为</li>\n</ul>\n<p>要当心在 Go 结构体中嵌入字段，这样做可能会导致诸如嵌入的 <code>time.Time</code> 字段实现 <code>json.Marshaler</code> 接口，从而覆盖默认的 JSON 序列。</p>\n<ul>\n<li>JSON 和单调时钟</li>\n</ul>\n<p>当对两个 <code>time.Time</code> 类型值进行比较时，需要记住 <code>time.Time</code> 包含了一个墙上时钟（wall clock）和一个单调时钟 （monotonic clock），而使用 <code>==</code> 运算符进行比较时会同时比较这两个。</p>\n<ul>\n<li>Map 键对应值为 <code>any</code></li>\n</ul>\n<p>当提供一个 map 用来 unmarshal JSON 数据时，为了避免不确定的 value 结构我们会使用 <code>any</code> 来作为 value 的类型而不是定义一个 struct，这种情况下需要记得数值默认会被转换为 <code>float64</code>。</p>\n<h3 id=\"sql-78\">常见的 SQL 错误 (#78)</h3>\n<ul>\n<li>忘记了 <code>sql.Open</code> 并没有与 db 服务器建立实际连接</li>\n</ul>\n<p>需要调用 <code>Ping</code> 或者 <code>PingContext</code> 方法来测试配置并确保数据库是可达的。</p>\n<ul>\n<li>忘记了使用连接池</li>\n</ul>\n<p>作为生产级别的应用，访问数据库时应该关注配置数据库连接池参数。</p>\n<ul>\n<li>没有使用 prepared 语句</li>\n</ul>\n<p>使用 SQL prepared 语句能够让查询更加高效和安全。</p>\n<ul>\n<li>误处理 null 值</li>\n</ul>\n<p>使用 <code>sql.NullXXX</code> 类型处理表中的可空列。</p>\n<ul>\n<li>不处理行迭代时的错误</li>\n</ul>\n<p>调用 <code>sql.Rows</code> 的 <code>Err</code> 方法来确保在准备下一个行时没有遗漏错误。</p>\n<h3 id=\"http-sqlrows-osfile-79\">不关闭临时资源（HTTP 请求体、<code>sql.Rows</code> 和 <code>os.File</code>） (#79)</h3>\n<p>最终要注意关闭所有实现 <code>io.Closer</code> 接口的结构体，以避免可能的泄漏。</p>\n<h3 id=\"http-80\">响应 HTTP 请求后没有返回语句 (#80)</h3>\n<p>为了避免在 HTTP 处理函数中出现某些意外的问题，如果想在发生 <code>http.Error</code> 后让 HTTP 处理函数停止，那么就不要忘记使用 <code>return</code> 语句来阻止后续代码的执行。</p>\n<h3 id=\"http-client-server-81\">直接使用默认的 HTTP client 和 server (#81)</h3>\n<p>对于生产级别的应用，不要使用默认的 HTTP client 和 server 实现。这些实现缺少超时和生产环境中应该强制使用的行为。</p>\n<h2 id=\"_10\">测试</h2>\n<h3 id=\"build-tags-82\">不对测试进行分类 （build tags, 环境变量，短模式）(#82)</h3>\n<p>对测试进行必要的分类，可以借助 build tags、环境变量以及短模式，来使得测试过程更加高效。你可以使用 build tags 或环境变量来创建测试类别（例如单元测试与集成测试），并区分短测试与长时间测试，来决定执行哪种类型的。</p>\n<blockquote>\n<p>ps: 了解下 go build tags，以及 <code>go test -short</code>。</p>\n</blockquote>\n<h3 id=\"race-83\">不打开 race 开关 (#83)</h3>\n<p>打开 <code>-race</code> 开关在编写并发应用时非常重要。这能帮助你捕获可能的数据竞争，从而避免软件 bug。</p>\n<h3 id=\"parallel-shuffle-84\">不打开测试的执行模式开关 (parallel 和 shuffle) (#84)</h3>\n<p>打开开关 <code>-parallel</code> 有助于加速测试的执行，特别是测试中包含一些需要长期运行的用例的时候。</p>\n<p>打开开关 <code>-shuffle</code> 能够打乱测试用例执行的顺序，避免一个测试依赖于某些不符合真实情况的预设，有助于及早暴露 bug。</p>\n<h3 id=\"85\">不使用表驱动的测试 (#85)</h3>\n<p>表驱动的测试是一种有效的方式，可以将一组相似的测试分组在一起，以避免代码重复和使未来的更新更容易处理。</p>\n<h3 id=\"sleep-86\">在单元测试中执行 sleep 操作 (#86)</h3>\n<p>使用同步的方式、避免 sleep，来尽量减少测试的不稳定性和提高鲁棒性。如果无法使用同步手段,可以考虑重试的方式。</p>\n<h3 id=\"time-api-87\">没有高效地处理 time API (#87)</h3>\n<p>理解如何处理使用 time API 的函数，是使测试更加稳定的另一种方式。您可以使用标准技术，例如将时间作为隐藏依赖项的一部分来处理，或者要求客户端提供时间。</p>\n<h3 id=\"httptest-iotest-88\">不使用测试相关的工具包 (<code>httptest</code> 和 <code>iotest</code>) (#88)</h3>\n<p>这个 <code>httptest</code> 包对处理 HTTP 应用程序很有帮助。它提供了一组实用程序来测试客户端和服务器。</p>\n<p>这个 <code>iotest</code> 包有助于编写 io.Reader 并测试应用程序是否能够容忍错误。</p>\n<h3 id=\"89\"><a href=\"https://100go.co/89-benchmarks/\">不正确的基准测试</a> (#89)</h3>\n<ul>\n<li>不要重置或者暂停 timer</li>\n</ul>\n<p>使用 time 方法来保持基准测试的准确性。</p>\n<ul>\n<li>做出错误的微基准测试假设</li>\n</ul>\n<p>增加 <code>benchtime</code> 或者使用 <code>benchstat</code> 等工具可以有助于微基准测试。</p>\n<p>小心微基准测试的结果，如果最终运行应用程序的系统与运行微基准测试的系统不同。</p>\n<ul>\n<li>对编译期优化要足够小心</li>\n</ul>\n<p>确保测试函数是否会产生一些副作用，防止编译器优化欺骗你得到的基准测试结果。</p>\n<ul>\n<li>被观察者效应所欺骗</li>\n</ul>\n<p>为了避免被观察者效应欺骗，强制重新创建CPU密集型函数使用的数据。</p>\n<h3 id=\"go-test-90\">没有去探索 go test 所有的特性 (#90)</h3>\n<ul>\n<li>代码覆盖率</li>\n</ul>\n<p>使用 <code>-coverprofile</code> 参数可以快速查看代码的测试覆盖情况，方便快速查看哪个部分需要更多的关注。</p>\n<ul>\n<li>在不同的包中执行测试</li>\n</ul>\n<p>单元测试组织到一个独立的包中，对于对外层暴露的接口，需要写一些测试用例。测试应该关注公开的行为，而非内部实现细节。</p>\n<ul>\n<li>Utility 函数</li>\n</ul>\n<p>处理错误时，使用 <code>*testing.T</code> 变量而不是经典的 <code>if err != nil</code> 可以让代码更加简洁易读。</p>\n<ul>\n<li>设置和销毁</li>\n</ul>\n<p>你可以使用 setup 和 teardown 函数来配置一个复杂的环境，比如在集成测试的情况下。</p>\n<h3 id=\"_11\">不使用模糊测试 (社区反馈错误)</h3>\n<p>模糊测试是一种高效的策略，使用它能检测出随机、意料外的和一些恶意的数据输入，来完成一些复杂的操作。</p>\n<p>见: <a href=\"https://github.com/jeromedoucet\">@jeromedoucet</a></p>\n<h2 id=\"_12\">优化技术</h2>\n<h3 id=\"cpu-cache-91\">不理解 CPU cache (#91)</h3>\n<ul>\n<li>CPU 架构</li>\n</ul>\n<p>理解 CPU 缓存的使用对于优化 CPU 密集型应用很重要，因为 L1 缓存比主存快 50 到 100 倍。</p>\n<ul>\n<li>Cache line</li>\n</ul>\n<p>意识到 cache line 概念对于理解如何在数据密集型应用中组织数据非常关键。CPU 并不是一个一个字来获取内存。相反，它通常复制一个 64 字节长度的 cache line。为了获得每个 cache line 的最大效用，需要实施空间局部性。</p>\n<ul>\n<li>\n<p>一系列 struct 元素构成的 slice vs. 多个 slice 字段构成的 struct</p>\n</li>\n<li>\n<p>概率性的问题</p>\n</li>\n</ul>\n<p>提高 CPU 执行代码时的可预测性，也是优化某些函数的一个有效方法。比如，固定步长或连续访问对 CPU 来说是可预测的，但非连续访问（例如链表）就是不可预测的。</p>\n<ul>\n<li>cache 放置策略</li>\n</ul>\n<p>要注意现代缓存是分区的（set associative placement，组相连映射），要注意避免使用 <code>critical stride</code>，这种步长情况下只能利用 cache 的一小部分。</p>\n<blockquote>\n<p>critical stride，这种类型的步长，指的是内存访问的步长刚好等于 cache 大小。这种情况下，只有少部分 cacheline 被利用。</p>\n</blockquote>\n<h3 id=\"false-sharing-92\">写的并发处理逻辑会导致 false sharing (#92)</h3>\n<p>了解 CPU 缓存的较低层的 L1、L2 cache 不会在所有核间共享，编写并发处理逻辑时能避免写出一些降低性能的问题，比如伪共享（false sharing）。内存共享只是一种假象。</p>\n<h3 id=\"93\">没有考虑指令级的并行 (#93)</h3>\n<p>使用指令级并行（<abbr title=\"Instruction-Level Parallelism\">ILP</abbr>）优化代码的特定部分，以允许 CPU 尽可能执行更多可以并行执行的指令。识别指令的数据依赖问题（data hazards）是主要步骤之一。</p>\n<h3 id=\"94\">不了解数据对齐 (#94)</h3>\n<p>记住 Go 中基本类型与其自身大小对齐，例如，按大小降序重新组织结构体的字段可以形成更紧凑的结构体（减少内存分配，更好的空间局部性），这有助于避免一些常见的错误。</p>\n<h3 id=\"stack-vs-heap-95\">不了解 stack vs. heap (#95)</h3>\n<p>了解堆和栈之间的区别是开发人员的核心知识点，特别是要去优化一个 Go 程序时。栈分配的开销几乎为零，而堆分配则较慢，并且依赖 <abbr title=\"Garbage Collector\">GC</abbr> 来清理内存。</p>\n<h3 id=\"api-syncpool-96\">不知道如何减少内存分配次数（API 调整，编译器优化和 <code>sync.Pool</code>） (#96)</h3>\n<p>减少内存分配次数也是优化 Go 应用的一个重要方面。这可以通过不同的方式来实现，比如仔细设计 API 来避免不必要的拷贝，以及使用 <code>sync.Pool</code> 来对分配对象进行池化。</p>\n<h3 id=\"97\">不注意使用内联 (#97)</h3>\n<p>使用快速路径的内联技术来更加有效地减少调用函数的摊销时间。</p>\n<h3 id=\"go-98\"><a href=\"https://100go.co/98-profiling-execution-tracing/\">不使用 Go 问题诊断工具</a> (#98)</h3>\n<p>了解 Go profiling 工具、执行时 tracer 来辅助判断一个应用程序是否正常，以及列出需要优化的部分。</p>\n<h3 id=\"gc-99\">不理解 <abbr title=\"Garbage Collector\">GC</abbr> 是如何工作的 (#99)</h3>\n<p>理解如何调优 <abbr title=\"Garbage Collector\">GC</abbr> 能够带来很多收益，例如有助于更高效地处理突增的负载。</p>\n<h3 id=\"docker-k8s-go-100\">不了解 Docker 或者 K8S 对运行的 Go 应用的性能影响 (#100)</h3>\n<p>为了避免 CPU throttling（CPU 限频）问题，当我们在 Docker 和 Kubernetes 部署应用时，要知道 Go 语言对 <abbr title=\"Completely Fair Scheduler\">CFS</abbr>（完全公平调度器）无感知。</p>\n\n\n\n\n\n\n\n  \n  \n\n\n\n  \n\n\n\n\n<h2 id=\"__comments\">Comments</h2>\n<!-- Insert generated snippet here -->\n<script src=\"https://giscus.app/client.js\" data-repo=\"teivah/100-go-mistakes\" data-repo-id=\"MDEwOlJlcG9zaXRvcnkzMjA4MTg5NjI=\" data-category=\"Discussions\" data-category-id=\"DIC_kwDOEx9PEs4CZQUm\" data-mapping=\"pathname\" data-strict=\"0\" data-reactions-enabled=\"1\" data-emit-metadata=\"0\" data-input-position=\"bottom\" data-theme=\"preferred_color_scheme\" data-lang=\"en\" crossorigin=\"anonymous\" async>\n</script>\n<!-- Synchronize Giscus theme with palette -->\n<script>\n  var giscus = document.querySelector(\"script[src*=giscus]\")\n\n  // Set palette on initial load\n  var palette = __md_get(\"__palette\")\n  if (palette && typeof palette.color === \"object\") {\n    var theme = palette.color.scheme === \"slate\"\n        ? \"transparent_dark\"\n        : \"light\"\n\n    // Instruct Giscus to set theme\n    giscus.setAttribute(\"data-theme\", theme)\n  }\n\n  // Register event handlers after documented loaded\n  document.addEventListener(\"DOMContentLoaded\", function() {\n    var ref = document.querySelector(\"[data-md-component=palette]\")\n    ref.addEventListener(\"change\", function() {\n      var palette = __md_get(\"__palette\")\n      if (palette && typeof palette.color === \"object\") {\n        var theme = palette.color.scheme === \"slate\"\n            ? \"transparent_dark\"\n            : \"light\"\n\n        // Instruct Giscus to change theme\n        var frame = document.querySelector(\".giscus-frame\")\n        frame.contentWindow.postMessage(\n            { giscus: { setConfig: { theme } } },\n            \"https://giscus.app\"\n        )\n      }\n    })\n  })\n</script>\n\n                \n              </article>\n            </div>\n          \n          \n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n        </div>\n        \n      </main>\n      \n        <footer class=\"md-footer\">\n  \n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-copyright\">\n  \n    <div class=\"md-copyright__highlight\">\n      Copyright © 2022 - 2024 Teiva Harsanyi\n    </div>\n  \n  \n    Made with\n    <a href=\"https://squidfunk.github.io/mkdocs-material/\" target=\"_blank\" rel=\"noopener\">\n      Material for MkDocs\n    </a>\n  \n</div>\n      \n        \n<div class=\"md-social\">\n  \n    \n    \n    \n    \n      \n      \n    \n    <a href=\"https://twitter.com/teivah\" target=\"_blank\" rel=\"noopener\" title=\"twitter.com\" class=\"md-social__link\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d=\"M459.4 151.7c.3 4.5.3 9.1.3 13.6 0 138.7-105.6 298.6-298.6 298.6-59.5 0-114.7-17.2-161.1-47.1 8.4 1 16.6 1.3 25.3 1.3 49.1 0 94.2-16.6 130.3-44.8-46.1-1-84.8-31.2-98.1-72.8 6.5 1 13 1.6 19.8 1.6 9.4 0 18.8-1.3 27.6-3.6-48.1-9.7-84.1-52-84.1-103v-1.3c14 7.8 30.2 12.7 47.4 13.3-28.3-18.8-46.8-51-46.8-87.4 0-19.5 5.2-37.4 14.3-53C87.4 130.8 165 172.4 252.1 176.9c-1.6-7.8-2.6-15.9-2.6-24C249.5 95.1 296.3 48 354.4 48c30.2 0 57.5 12.7 76.7 33.1 23.7-4.5 46.5-13.3 66.6-25.3-7.8 24.4-24.4 44.8-46.1 57.8 21.1-2.3 41.6-8.1 60.4-16.2-14.3 20.8-32.2 39.3-52.6 54.3\"></path></svg>\n    </a>\n  \n</div>\n      \n    </div>\n  </div>\n</footer>\n      \n    </div>\n    <div class=\"md-dialog\" data-md-component=\"dialog\">\n      <div class=\"md-dialog__inner md-typeset\"></div>\n    </div>\n    \n    \n    \n      \n      <script id=\"__config\" type=\"application/json\">{\"base\": \"..\", \"features\": [\"navigation.tabs\", \"navigation.tabs.sticky\", \"search.highlight\", \"search.share\", \"search.suggest\", \"content.code.copy\", \"navigation.expand\", \"navigation.sections\", \"announce.dismiss\", \"toc.follow\", \"content.code.annotate\", \"content.tooltips\"], \"search\": \"../assets/javascripts/workers/search.973d3a69.min.js\", \"tags\": null, \"translations\": {\"clipboard.copied\": \"Copied to clipboard\", \"clipboard.copy\": \"Copy to clipboard\", \"search.result.more.one\": \"1 more on this page\", \"search.result.more.other\": \"# more on this page\", \"search.result.none\": \"No matching documents\", \"search.result.one\": \"1 matching document\", \"search.result.other\": \"# matching documents\", \"search.result.placeholder\": \"Type to start searching\", \"search.result.term.missing\": \"Missing\", \"select.version\": \"Select version\"}, \"version\": null}</script>\n    \n    \n      <script src=\"../assets/javascripts/bundle.f55a23d4.min.js\"></script>\n      \n    \n  \n<script id=\"init-glightbox\">const lightbox = GLightbox({\"touchNavigation\": true, \"loop\": false, \"zoomable\": true, \"draggable\": true, \"openEffect\": \"zoom\", \"closeEffect\": \"zoom\", \"slideEffect\": \"slide\"});\ndocument$.subscribe(()=>{ lightbox.reload(); });\n</script></body></html>"
  },
  {
    "path": "src/02-code-project-organization/1-variable-shadowing/main.go",
    "content": "package main\n\nimport (\n\t\"log\"\n\t\"net/http\"\n)\n\nfunc main() {\n\t_ = listing1()\n\t_ = listing2()\n\t_ = listing3()\n\t_ = listing4()\n}\n\nfunc listing1() error {\n\tvar client *http.Client\n\tif tracing {\n\t\tclient, err := createClientWithTracing()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tlog.Println(client)\n\t} else {\n\t\tclient, err := createDefaultClient()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tlog.Println(client)\n\t}\n\n\t_ = client\n\treturn nil\n}\n\nfunc listing2() error {\n\tvar client *http.Client\n\tif tracing {\n\t\tc, err := createClientWithTracing()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tclient = c\n\t} else {\n\t\tc, err := createDefaultClient()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tclient = c\n\t}\n\n\t_ = client\n\treturn nil\n}\n\nfunc listing3() error {\n\tvar client *http.Client\n\tvar err error\n\tif tracing {\n\t\tclient, err = createClientWithTracing()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\tclient, err = createDefaultClient()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t_ = client\n\treturn nil\n}\n\nfunc listing4() error {\n\tvar client *http.Client\n\tvar err error\n\tif tracing {\n\t\tclient, err = createClientWithTracing()\n\t} else {\n\t\tclient, err = createDefaultClient()\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_ = client\n\treturn nil\n}\n\nvar tracing bool\n\nfunc createClientWithTracing() (*http.Client, error) {\n\treturn nil, nil\n}\n\nfunc createDefaultClient() (*http.Client, error) {\n\treturn nil, nil\n}\n"
  },
  {
    "path": "src/02-code-project-organization/10-type-embedding/main.go",
    "content": "package main\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"sync\"\n)\n\ntype Foo struct {\n\tBar\n}\n\ntype Bar struct {\n\tBaz int\n}\n\nfunc fooBar() {\n\tfoo := Foo{}\n\tfoo.Baz = 42\n}\n\ntype InMem struct {\n\tsync.Mutex\n\tm map[string]int\n}\n\nfunc New() *InMem {\n\treturn &InMem{m: make(map[string]int)}\n}\n\nfunc (i *InMem) Get(key string) (int, bool) {\n\ti.Lock()\n\tv, contains := i.m[key]\n\ti.Unlock()\n\treturn v, contains\n}\n\ntype Logger struct {\n\twriteCloser io.WriteCloser\n}\n\nfunc (l Logger) Write(p []byte) (int, error) {\n\treturn l.writeCloser.Write(p)\n}\n\nfunc (l Logger) Close() error {\n\treturn l.writeCloser.Close()\n}\n\nfunc main() {\n\tl := Logger{writeCloser: os.Stdout}\n\t_, _ = l.Write([]byte(\"foo\"))\n\t_ = l.Close()\n}\n"
  },
  {
    "path": "src/02-code-project-organization/11-functional-options/builder/main.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n)\n\nconst defaultHTTPPort = 8080\n\ntype Config struct {\n\tPort int\n}\n\ntype ConfigBuilder struct {\n\tport *int\n}\n\nfunc (b *ConfigBuilder) Port(port int) *ConfigBuilder {\n\tb.port = &port\n\treturn b\n}\n\nfunc (b *ConfigBuilder) Build() (Config, error) {\n\tcfg := Config{}\n\n\tif b.port == nil {\n\t\tcfg.Port = defaultHTTPPort\n\t} else {\n\t\tif *b.port == 0 {\n\t\t\tcfg.Port = randomPort()\n\t\t} else if *b.port < 0 {\n\t\t\treturn Config{}, errors.New(\"port should be positive\")\n\t\t} else {\n\t\t\tcfg.Port = *b.port\n\t\t}\n\t}\n\n\treturn cfg, nil\n}\n\nfunc NewServer(addr string, config Config) (*http.Server, error) {\n\treturn nil, nil\n}\n\nfunc client() error {\n\tbuilder := ConfigBuilder{}\n\tbuilder.Port(8080)\n\tcfg, err := builder.Build()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tserver, err := NewServer(\"localhost\", cfg)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_ = server\n\treturn nil\n}\n\nfunc randomPort() int {\n\treturn 4 // Chosen by fair dice roll, guaranteed to be random.\n}\n"
  },
  {
    "path": "src/02-code-project-organization/11-functional-options/config-struct/main.go",
    "content": "package main\n\ntype Config struct {\n\tPort int\n}\n\nfunc NewServer(addr string, cfg Config) {\n}\n\nfunc main() {\n\tNewServer(\"localhost\", Config{})\n}\n"
  },
  {
    "path": "src/02-code-project-organization/11-functional-options/functional-options/main.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n)\n\nconst defaultHTTPPort = 8080\n\ntype options struct {\n\tport *int\n}\n\ntype Option func(options *options) error\n\nfunc WithPort(port int) Option {\n\treturn func(options *options) error {\n\t\tif port < 0 {\n\t\t\treturn errors.New(\"port should be positive\")\n\t\t}\n\t\toptions.port = &port\n\t\treturn nil\n\t}\n}\n\nfunc NewServer(addr string, opts ...Option) (*http.Server, error) {\n\tvar options options\n\tfor _, opt := range opts {\n\t\terr := opt(&options)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\t// At this stage, the options struct is built and contains the config\n\t// Therefore, we can implement our logic related to port configuration\n\tvar port int\n\tif options.port == nil {\n\t\tport = defaultHTTPPort\n\t} else {\n\t\tif *options.port == 0 {\n\t\t\tport = randomPort()\n\t\t} else {\n\t\t\tport = *options.port\n\t\t}\n\t}\n\n\t_ = port\n\treturn nil, nil\n}\n\nfunc client() {\n\t_, _ = NewServer(\"localhost\", WithPort(8080))\n}\n\nfunc randomPort() int {\n\treturn 4 // Chosen by fair dice roll, guaranteed to be random.\n}\n"
  },
  {
    "path": "src/02-code-project-organization/13-utility-packages/stringset.go",
    "content": "package stringset\n\ntype Set map[string]struct{}\n\nfunc New(...string) Set { return nil }\n\nfunc (s Set) Sort() []string { return nil }\n"
  },
  {
    "path": "src/02-code-project-organization/2-nested-code/main.go",
    "content": "package main\n\nimport \"errors\"\n\nfunc join1(s1, s2 string, max int) (string, error) {\n\tif s1 == \"\" {\n\t\treturn \"\", errors.New(\"s1 is empty\")\n\t} else {\n\t\tif s2 == \"\" {\n\t\t\treturn \"\", errors.New(\"s2 is empty\")\n\t\t} else {\n\t\t\tconcat, err := concatenate(s1, s2)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t} else {\n\t\t\t\tif len(concat) > max {\n\t\t\t\t\treturn concat[:max], nil\n\t\t\t\t} else {\n\t\t\t\t\treturn concat, nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc join2(s1, s2 string, max int) (string, error) {\n\tif s1 == \"\" {\n\t\treturn \"\", errors.New(\"s1 is empty\")\n\t}\n\tif s2 == \"\" {\n\t\treturn \"\", errors.New(\"s2 is empty\")\n\t}\n\tconcat, err := concatenate(s1, s2)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif len(concat) > max {\n\t\treturn concat[:max], nil\n\t}\n\treturn concat, nil\n}\n\nfunc concatenate(s1, s2 string) (string, error) {\n\treturn \"\", nil\n}\n"
  },
  {
    "path": "src/02-code-project-organization/3-init-functions/db/main.go",
    "content": "package main\n\nimport (\n\t\"database/sql\"\n\t\"log\"\n\t\"os\"\n)\n\nvar db *sql.DB\n\nfunc init() {\n\tdataSourceName := os.Getenv(\"MYSQL_DATA_SOURCE_NAME\")\n\td, err := sql.Open(\"mysql\", dataSourceName)\n\tif err != nil {\n\t\tlog.Panic(err)\n\t}\n\terr = d.Ping()\n\tif err != nil {\n\t\tlog.Panic(err)\n\t}\n\tdb = d\n}\n\nfunc createClient(dataSourceName string) (*sql.DB, error) {\n\tdb, err := sql.Open(\"mysql\", dataSourceName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err = db.Ping(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn db, nil\n}\n"
  },
  {
    "path": "src/02-code-project-organization/3-init-functions/main/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/teivah/100-go-mistakes/src/02-code-project-organization/3-init-functions/redis\"\n)\n\nfunc init() {\n\tfmt.Println(\"init 1\")\n}\n\nfunc init() {\n\tfmt.Println(\"init 2\")\n}\n\nfunc main() {\n\terr := redis.Store(\"foo\", \"bar\")\n\t_ = err\n}\n"
  },
  {
    "path": "src/02-code-project-organization/3-init-functions/redis/redis.go",
    "content": "package redis\n\nimport \"fmt\"\n\nfunc init() {\n\tfmt.Println(\"redis\")\n}\n\nfunc Store(key, value string) error {\n\treturn nil\n}\n"
  },
  {
    "path": "src/02-code-project-organization/5-interface-pollution/copy/main.go",
    "content": "package main\n\nimport \"io\"\n\nfunc copySourceToDest(source io.Reader, dest io.Writer) error {\n\tb, err := io.ReadAll(source)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = dest.Write(b)\n\treturn err\n}\n"
  },
  {
    "path": "src/02-code-project-organization/5-interface-pollution/copy/main_test.go",
    "content": "package main\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestCopySourceToDest(t *testing.T) {\n\tconst input = \"foo\"\n\tsource := strings.NewReader(input)\n\tdest := bytes.NewBuffer(make([]byte, 0))\n\n\terr := copySourceToDest(source, dest)\n\tif err != nil {\n\t\tt.FailNow()\n\t}\n\n\tgot := dest.String()\n\tif got != input {\n\t\tt.Errorf(\"expected: %s, got: %s\", input, got)\n\t}\n}\n"
  },
  {
    "path": "src/02-code-project-organization/5-interface-pollution/decoupling/with.go",
    "content": "package main\n\ntype customerStorer interface {\n\tStoreCustomer(Customer) error\n}\n\ntype CustomerService2 struct {\n\tstorer customerStorer\n}\n\nfunc (cs CustomerService2) CreateNewCustomer(id string) error {\n\tcustomer := Customer{id: id}\n\treturn cs.storer.StoreCustomer(customer)\n}\n"
  },
  {
    "path": "src/02-code-project-organization/5-interface-pollution/decoupling/without.go",
    "content": "package main\n\ntype CustomerService struct {\n\tstore Store\n}\n\nfunc (cs CustomerService) CreateNewCustomer(id string) error {\n\tcustomer := Customer{id: id}\n\treturn cs.store.StoreCustomer(customer)\n}\n\ntype Customer struct {\n\tid string\n}\n\ntype Store struct{}\n\nfunc (s Store) StoreCustomer(customer Customer) error {\n\treturn nil\n}\n"
  },
  {
    "path": "src/02-code-project-organization/5-interface-pollution/restricting-behavior/main.go",
    "content": "package main\n\ntype IntConfig struct {\n\tvalue int\n}\n\nfunc (c *IntConfig) Get() int {\n\treturn c.value\n}\n\nfunc (c *IntConfig) Set(value int) {\n\tc.value = value\n}\n\ntype intConfigGetter interface {\n\tGet() int\n}\n\ntype Foo struct {\n\tthreshold intConfigGetter\n}\n\nfunc NewFoo(threshold intConfigGetter) Foo {\n\treturn Foo{threshold: threshold}\n}\n\nfunc (f Foo) Bar() {\n\tthreshold := f.threshold.Get()\n\t_ = threshold\n}\n\nfunc main() {\n\tfoo := NewFoo(&IntConfig{value: 42})\n\tfoo.Bar()\n}\n"
  },
  {
    "path": "src/02-code-project-organization/6-interface-producer/client/client.go",
    "content": "package client\n\nimport \"github.com/teivah/100-go-mistakes/src/02-code-project-organization/6-interface-producer/store\"\n\ntype customersGetter interface {\n\tGetAllCustomers() ([]store.Customer, error)\n}\n"
  },
  {
    "path": "src/02-code-project-organization/6-interface-producer/store/store.go",
    "content": "package store\n\ntype CustomerStorage interface {\n\tStoreCustomer(customer Customer) error\n\tGetCustomer(id string) (Customer, error)\n\tUpdateCustomer(customer Customer) error\n\tGetAllCustomers() ([]Customer, error)\n\tGetCustomersWithoutContract() ([]Customer, error)\n\tGetCustomersWithNegativeBalance() ([]Customer, error)\n}\n\ntype Customer struct{}\n"
  },
  {
    "path": "src/02-code-project-organization/8-any/main.go",
    "content": "package main\n\nfunc main() {\n\tvar i any\n\n\ti = 42\n\ti = \"foo\"\n\ti = struct {\n\t\ts string\n\t}{\n\t\ts: \"bar\",\n\t}\n\ti = f\n\n\t_ = i\n}\n\nfunc f() {}\n"
  },
  {
    "path": "src/02-code-project-organization/8-any/store/after.go",
    "content": "package store\n\nfunc (s *Store) GetContract(id string) (Contract, error) {\n\treturn Contract{}, nil\n}\n\nfunc (s *Store) SetContract(id string, contract Contract) error {\n\treturn nil\n}\n\nfunc (s *Store) GetCustomer(id string) (Customer, error) {\n\treturn Customer{}, nil\n}\n\nfunc (s *Store) SetCustomer(id string, customer Customer) error {\n\treturn nil\n}\n"
  },
  {
    "path": "src/02-code-project-organization/8-any/store/before.go",
    "content": "package store\n\ntype Customer struct {\n\t// Some fields\n}\n\ntype Contract struct {\n\t// Some fields\n}\n\ntype Store struct{}\n\nfunc (s *Store) Get(id string) (any, error) {\n\treturn nil, nil\n}\n\nfunc (s *Store) Set(id string, v any) error {\n\treturn nil\n}\n"
  },
  {
    "path": "src/02-code-project-organization/9-generics/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n)\n\nfunc getKeys(m any) ([]any, error) {\n\tswitch t := m.(type) {\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown type: %T\", t)\n\tcase map[string]int:\n\t\tvar keys []any\n\t\tfor k := range t {\n\t\t\tkeys = append(keys, k)\n\t\t}\n\t\treturn keys, nil\n\tcase map[int]string:\n\t\t// ...\n\t}\n\n\treturn nil, nil\n}\n\nfunc getKeysGenerics[K comparable, V any](m map[K]V) []K {\n\tvar keys []K\n\tfor k := range m {\n\t\tkeys = append(keys, k)\n\t}\n\treturn keys\n}\n\ntype customConstraint interface {\n\t~int | ~string\n}\n\nfunc getKeysWithConstraint[K customConstraint, V any](m map[K]V) []K {\n\treturn nil\n}\n\ntype Node[T any] struct {\n\tVal  T\n\tnext *Node[T]\n}\n\nfunc (n *Node[T]) Add(next *Node[T]) {\n\tn.next = next\n}\n\ntype SliceFn[T any] struct {\n\tS       []T\n\tCompare func(T, T) bool\n}\n\nfunc (s SliceFn[T]) Len() int           { return len(s.S) }\nfunc (s SliceFn[T]) Less(i, j int) bool { return s.Compare(s.S[i], s.S[j]) }\nfunc (s SliceFn[T]) Swap(i, j int)      { s.S[i], s.S[j] = s.S[j], s.S[i] }\n\nfunc main() {\n\ts := SliceFn[int]{\n\t\tS: []int{3, 2, 1},\n\t\tCompare: func(a, b int) bool {\n\t\t\treturn a < b\n\t\t},\n\t}\n\tsort.Sort(s)\n\tfmt.Println(s.S)\n}\n"
  },
  {
    "path": "src/03-data-types/17-octal-literals/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tsum := 100 + 0o10\n\tfmt.Println(sum)\n}\n"
  },
  {
    "path": "src/03-data-types/18-integer-overflows/main.go",
    "content": "package main\n\nimport \"math\"\n\nfunc Inc32(counter int32) int32 {\n\tif counter == math.MaxInt32 {\n\t\tpanic(\"int32 overflow\")\n\t}\n\treturn counter + 1\n}\n\nfunc IncInt(counter int) int {\n\tif counter == math.MaxInt {\n\t\tpanic(\"int overflow\")\n\t}\n\treturn counter + 1\n}\n\nfunc IncUint(counter uint) uint {\n\tif counter == math.MaxUint {\n\t\tpanic(\"uint overflow\")\n\t}\n\treturn counter + 1\n}\n\nfunc AddInt(a, b int) int {\n\tif a > math.MaxInt-b {\n\t\tpanic(\"int overflow\")\n\t}\n\n\treturn a + b\n}\n\nfunc MultiplyInt(a, b int) int {\n\tif a == 0 || b == 0 {\n\t\treturn 0\n\t}\n\n\tresult := a * b\n\tif a == 1 || b == 1 {\n\t\treturn result\n\t}\n\tif a == math.MinInt || b == math.MinInt {\n\t\tpanic(\"integer overflow\")\n\t}\n\tif result/b != a {\n\t\tpanic(\"integer overflow\")\n\t}\n\treturn result\n}\n"
  },
  {
    "path": "src/03-data-types/19-floating-points/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar n float32 = 1.0001\n\tfmt.Println(n * n)\n\n\tvar a float64\n\tpositiveInf := 1 / a\n\tnegativeInf := -1 / a\n\tnan := a / a\n\tfmt.Println(positiveInf, negativeInf, nan)\n}\n\nfunc f1(n int) float64 {\n\tresult := 10_000.\n\tfor i := 0; i < n; i++ {\n\t\tresult += 1.0001\n\t}\n\treturn result\n}\n\nfunc f2(n int) float64 {\n\tresult := 0.\n\tfor i := 0; i < n; i++ {\n\t\tresult += 1.0001\n\t}\n\treturn result + 10_000.\n}\n"
  },
  {
    "path": "src/03-data-types/20-slice-length-cap/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\ts := make([]int, 3, 6)\n\tprint(s)\n\n\ts[1] = 1\n\tprint(s)\n\n\ts = append(s, 2)\n\tprint(s)\n\n\ts = append(s, 3, 4, 5)\n\tprint(s)\n\n\ts1 := make([]int, 3, 6)\n\ts2 := s1[1:3]\n\ts1[1] = 1\n\tprint(s2)\n\n\ts2 = append(s2, 2)\n\tprint(s1)\n\tprint(s2)\n\n\ts2 = append(s2, 3)\n\ts2 = append(s2, 4)\n\ts2 = append(s2, 5)\n\tprint(s1)\n\tprint(s2)\n}\n\nfunc print(s []int) {\n\tfmt.Printf(\"len=%d, cap=%d: %v\\n\", len(s), cap(s), s)\n}\n"
  },
  {
    "path": "src/03-data-types/21-slice-init/main.go",
    "content": "package main\n\nfunc convertEmptySlice(foos []Foo) []Bar {\n\tbars := make([]Bar, 0)\n\n\tfor _, foo := range foos {\n\t\tbars = append(bars, fooToBar(foo))\n\t}\n\treturn bars\n}\n\nfunc convertGivenCapacity(foos []Foo) []Bar {\n\tn := len(foos)\n\tbars := make([]Bar, 0, n)\n\n\tfor _, foo := range foos {\n\t\tbars = append(bars, fooToBar(foo))\n\t}\n\treturn bars\n}\n\nfunc convertGivenLength(foos []Foo) []Bar {\n\tn := len(foos)\n\tbars := make([]Bar, n)\n\n\tfor i, foo := range foos {\n\t\tbars[i] = fooToBar(foo)\n\t}\n\treturn bars\n}\n\ntype Foo struct{}\n\ntype Bar struct{}\n\nfunc fooToBar(foo Foo) Bar {\n\treturn Bar{}\n}\n"
  },
  {
    "path": "src/03-data-types/21-slice-init/main_test.go",
    "content": "package main\n\nimport \"testing\"\n\nconst n = 1_000_000\n\nvar global []Bar\n\nfunc BenchmarkConvert_EmptySlice(b *testing.B) {\n\tvar local []Bar\n\tfoos := make([]Foo, n)\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tlocal = convertEmptySlice(foos)\n\t}\n\tglobal = local\n}\n\nfunc BenchmarkConvert_GivenCapacity(b *testing.B) {\n\tvar local []Bar\n\tfoos := make([]Foo, n)\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tlocal = convertGivenCapacity(foos)\n\t}\n\tglobal = local\n}\n\nfunc BenchmarkConvert_GivenLength(b *testing.B) {\n\tvar local []Bar\n\tfoos := make([]Foo, n)\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tlocal = convertGivenLength(foos)\n\t}\n\tglobal = local\n}\n"
  },
  {
    "path": "src/03-data-types/22-nil-empty-slice/json/main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\nfunc main() {\n\tvar s1 []float32\n\tcustomer1 := customer{\n\t\tID:         \"foo\",\n\t\tOperations: s1,\n\t}\n\tb, _ := json.Marshal(customer1)\n\tfmt.Println(string(b))\n\n\ts2 := make([]float32, 0)\n\tcustomer2 := customer{\n\t\tID:         \"bar\",\n\t\tOperations: s2,\n\t}\n\tb, _ = json.Marshal(customer2)\n\tfmt.Println(string(b))\n}\n\ntype customer struct {\n\tID         string\n\tOperations []float32\n}\n"
  },
  {
    "path": "src/03-data-types/22-nil-empty-slice/slice-init/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n)\n\nfunc main() {\n\tvar s []string\n\tlog(1, s)\n\n\ts = []string(nil)\n\tlog(2, s)\n\n\ts = []string{}\n\tlog(3, s)\n\n\ts = make([]string, 0)\n\tlog(4, s)\n}\n\nfunc log(i int, s []string) {\n\tfmt.Printf(\"%d: empty=%t\\tnil=%t\\n\", i, len(s) == 0, s == nil)\n}\n"
  },
  {
    "path": "src/03-data-types/23-checking-slice-empty/main.go",
    "content": "package main\n\nfunc handleOperations1(id string) {\n\toperations := getOperations(id)\n\tif operations != nil {\n\t\thandle(operations)\n\t}\n}\n\nfunc handleOperations2(id string) {\n\toperations := getOperations(id)\n\tif len(operations) != 0 {\n\t\thandle(operations)\n\t}\n}\n\nfunc getOperations(id string) []float32 {\n\toperations := make([]float32, 0)\n\n\tif id == \"\" {\n\t\treturn operations\n\t}\n\n\t// Add elements to operations\n\n\treturn operations\n}\n\nfunc handle(operations []float32) {}\n"
  },
  {
    "path": "src/03-data-types/24-slice-copy/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc bad() {\n\tsrc := []int{0, 1, 2}\n\tvar dst []int\n\tcopy(dst, src)\n\tfmt.Println(dst)\n\n\t_ = src\n\t_ = dst\n}\n\nfunc correct() {\n\tsrc := []int{0, 1, 2}\n\tdst := make([]int, len(src))\n\tcopy(dst, src)\n\tfmt.Println(dst)\n\n\t_ = src\n\t_ = dst\n}\n\nfunc main() {\n\tbad()\n\tcorrect()\n}\n"
  },
  {
    "path": "src/03-data-types/25-slice-append/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tlisting1()\n\tlisting2()\n\tlisting3()\n}\n\nfunc listing1() {\n\ts := []int{1, 2, 3}\n\n\tf(s[:2])\n\tfmt.Println(s)\n}\n\nfunc listing2() {\n\ts := []int{1, 2, 3}\n\tsCopy := make([]int, 2)\n\tcopy(sCopy, s)\n\n\tf(sCopy)\n\tresult := append(sCopy, s[2])\n\tfmt.Println(result)\n}\n\nfunc listing3() {\n\ts := []int{1, 2, 3}\n\tf(s[:2:2])\n\tfmt.Println(s)\n}\n\nfunc f(s []int) {\n\t_ = append(s, 10)\n}\n"
  },
  {
    "path": "src/03-data-types/26-slice-memory-leak/capacity-leak/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"runtime\"\n)\n\nfunc consumeMessages() {\n\tfor {\n\t\tmsg := receiveMessage()\n\t\t// Do something with msg\n\t\tstoreMessageType(getMessageType(msg))\n\t}\n}\n\nfunc getMessageType(msg []byte) []byte {\n\treturn msg[:5]\n}\n\nfunc getMessageTypeWithCopy(msg []byte) []byte {\n\tmsgType := make([]byte, 5)\n\tcopy(msgType, msg)\n\treturn msgType\n}\n\nfunc receiveMessage() []byte {\n\treturn make([]byte, 1_000_000)\n}\n\nfunc storeMessageType([]byte) {}\n\nfunc printAlloc() {\n\tvar m runtime.MemStats\n\truntime.ReadMemStats(&m)\n\tfmt.Printf(\"%d KB\\n\", m.Alloc/1024)\n}\n"
  },
  {
    "path": "src/03-data-types/26-slice-memory-leak/slice-pointers/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"runtime\"\n)\n\ntype Foo struct {\n\tv []byte\n}\n\nfunc main() {\n\tfoos := make([]Foo, 1_000)\n\tprintAlloc()\n\n\tfor i := 0; i < len(foos); i++ {\n\t\tfoos[i] = Foo{\n\t\t\tv: make([]byte, 1024*1024),\n\t\t}\n\t}\n\tprintAlloc()\n\n\ttwo := keepFirstTwoElementsOnly(foos)\n\truntime.GC()\n\tprintAlloc()\n\truntime.KeepAlive(two)\n}\n\nfunc keepFirstTwoElementsOnly(foos []Foo) []Foo {\n\treturn foos[:2]\n}\n\nfunc keepFirstTwoElementsOnlyCopy(foos []Foo) []Foo {\n\tres := make([]Foo, 2)\n\tcopy(res, foos)\n\treturn res\n}\n\nfunc keepFirstTwoElementsOnlyMarkNil(foos []Foo) []Foo {\n\tfor i := 2; i < len(foos); i++ {\n\t\tfoos[i].v = nil\n\t}\n\treturn foos[:2]\n}\n\nfunc printAlloc() {\n\tvar m runtime.MemStats\n\truntime.ReadMemStats(&m)\n\tfmt.Printf(\"%d KB\\n\", m.Alloc/1024)\n}\n"
  },
  {
    "path": "src/03-data-types/27-map-init/main_test.go",
    "content": "package main\n\nimport \"testing\"\n\nconst n = 1_000_000\n\nvar global map[int]struct{}\n\nfunc BenchmarkMapWithoutSize(b *testing.B) {\n\tvar local map[int]struct{}\n\tfor i := 0; i < b.N; i++ {\n\t\tm := make(map[int]struct{})\n\t\tfor j := 0; j < n; j++ {\n\t\t\tm[j] = struct{}{}\n\t\t}\n\t}\n\tglobal = local\n}\n\nfunc BenchmarkMapWithSize(b *testing.B) {\n\tvar local map[int]struct{}\n\tfor i := 0; i < b.N; i++ {\n\t\tm := make(map[int]struct{}, n)\n\t\tfor j := 0; j < n; j++ {\n\t\t\tm[j] = struct{}{}\n\t\t}\n\t}\n\tglobal = local\n}\n"
  },
  {
    "path": "src/03-data-types/28-map-memory-leak/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"runtime\"\n)\n\nfunc main() {\n\t// Init\n\tn := 1_000_000\n\tm := make(map[int][128]byte)\n\tprintAlloc()\n\n\t// Add elements\n\tfor i := 0; i < n; i++ {\n\t\tm[i] = randBytes()\n\t}\n\tprintAlloc()\n\n\t// Remove elements\n\tfor i := 0; i < n; i++ {\n\t\tdelete(m, i)\n\t}\n\n\t// End\n\truntime.GC()\n\tprintAlloc()\n\truntime.KeepAlive(m)\n}\n\nfunc randBytes() [128]byte {\n\treturn [128]byte{}\n}\n\nfunc printAlloc() {\n\tvar m runtime.MemStats\n\truntime.ReadMemStats(&m)\n\tfmt.Printf(\"%d MB\\n\", m.Alloc/1024/1024)\n}\n"
  },
  {
    "path": "src/03-data-types/29-comparing-values/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\ntype customer1 struct {\n\tid string\n}\n\ntype customer2 struct {\n\tid         string\n\toperations []float64\n}\n\nfunc main() {\n\tcust11 := customer1{id: \"x\"}\n\tcust12 := customer1{id: \"x\"}\n\tfmt.Println(cust11 == cust12)\n\n\tcust21 := customer2{id: \"x\", operations: []float64{1.}}\n\tcust22 := customer2{id: \"x\", operations: []float64{1.}}\n\t// Doesn't compile\n\t// fmt.Println(cust21 == cust22)\n\t_ = cust21\n\t_ = cust22\n\n\tvar a any = 3\n\tvar b any = 3\n\tfmt.Println(a == b)\n\n\tvar cust31 any = customer2{id: \"x\", operations: []float64{1.}}\n\tvar cust32 any = customer2{id: \"x\", operations: []float64{1.}}\n\tfmt.Println(cust31 == cust32)\n\n\tcust41 := customer2{id: \"x\", operations: []float64{1.}}\n\tcust42 := customer2{id: \"x\", operations: []float64{1.}}\n\tfmt.Println(reflect.DeepEqual(cust41, cust42))\n}\n\nfunc (a customer2) equal(b customer2) bool {\n\tif a.id != b.id {\n\t\treturn false\n\t}\n\tif len(a.operations) != len(b.operations) {\n\t\treturn false\n\t}\n\tfor i := 0; i < len(a.operations); i++ {\n\t\tif a.operations[i] != b.operations[i] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "src/04-control-structures/30-range-loop-element-copied/concepts/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\ts := []string{\"a\", \"b\", \"c\"}\n\tfor i, v := range s {\n\t\tfmt.Printf(\"index=%d, value=%s\\n\", i, v)\n\t}\n\n\tfor _, v := range s {\n\t\tfmt.Printf(\"value=%s\\n\", v)\n\t}\n}\n"
  },
  {
    "path": "src/04-control-structures/30-range-loop-element-copied/value-copy/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype account struct {\n\tbalance float32\n}\n\nfunc main() {\n\taccounts := createAccounts()\n\tfor _, a := range accounts {\n\t\ta.balance += 1000\n\t}\n\tfmt.Println(accounts)\n\n\taccounts = createAccounts()\n\tfor i := range accounts {\n\t\taccounts[i].balance += 1000\n\t}\n\tfmt.Println(accounts)\n\n\taccounts = createAccounts()\n\tfor i := 0; i < len(accounts); i++ {\n\t\taccounts[i].balance += 1000\n\t}\n\tfmt.Println(accounts)\n\n\taccountsPtr := createAccountsPtr()\n\tfor _, a := range accountsPtr {\n\t\ta.balance += 1000\n\t}\n\tprintAccountsPtr(accountsPtr)\n}\n\nfunc createAccounts() []account {\n\treturn []account{\n\t\t{balance: 100.},\n\t\t{balance: 200.},\n\t\t{balance: 300.},\n\t}\n}\n\nfunc createAccountsPtr() []*account {\n\treturn []*account{\n\t\t{balance: 100.},\n\t\t{balance: 200.},\n\t\t{balance: 300.},\n\t}\n}\n\nfunc printAccountsPtr(accounts []*account) {\n\tsb := strings.Builder{}\n\tsb.WriteString(\"[\")\n\ts := make([]string, len(accounts))\n\tfor i, account := range accounts {\n\t\ts[i] = fmt.Sprintf(\"{%.0f}\", account.balance)\n\t}\n\tsb.WriteString(strings.Join(s, \" \"))\n\tsb.WriteString(\"]\")\n\tfmt.Println(sb.String())\n}\n"
  },
  {
    "path": "src/04-control-structures/31-range-loop-arg-evaluation/arrays/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc listing1() {\n\ta := [3]int{0, 1, 2}\n\tfor i, v := range a {\n\t\ta[2] = 10\n\t\tif i == 2 {\n\t\t\tfmt.Println(v)\n\t\t}\n\t}\n}\n\nfunc listing2() {\n\ta := [3]int{0, 1, 2}\n\tfor i := range a {\n\t\ta[2] = 10\n\t\tif i == 2 {\n\t\t\tfmt.Println(a[2])\n\t\t}\n\t}\n}\n\nfunc listing3() {\n\ta := [3]int{0, 1, 2}\n\tfor i, v := range &a {\n\t\ta[2] = 10\n\t\tif i == 2 {\n\t\t\tfmt.Println(v)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/04-control-structures/31-range-loop-arg-evaluation/channels/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tch1 := make(chan int, 3)\n\tgo func() {\n\t\tch1 <- 0\n\t\tch1 <- 1\n\t\tch1 <- 2\n\t\tclose(ch1)\n\t}()\n\n\tch2 := make(chan int, 3)\n\tgo func() {\n\t\tch2 <- 10\n\t\tch2 <- 11\n\t\tch2 <- 12\n\t\tclose(ch2)\n\t}()\n\n\tch := ch1\n\tfor v := range ch {\n\t\tfmt.Println(v)\n\t\tch = ch2\n\t}\n}\n"
  },
  {
    "path": "src/04-control-structures/31-range-loop-arg-evaluation/concepts/main.go",
    "content": "package main\n\nfunc main() {\n\ts1 := []int{0, 1, 2}\n\tfor range s1 {\n\t\ts1 = append(s1, 10)\n\t}\n\n\ts2 := []int{0, 1, 2}\n\tfor i := 0; i < len(s2); i++ {\n\t\ts2 = append(s2, 10)\n\t}\n}\n"
  },
  {
    "path": "src/04-control-structures/32-range-loop-pointers/concepts/main.go",
    "content": "package concepts\n\ntype Store struct {\n\tm map[string]*Foo\n}\n\nfunc (s Store) Put(id string, foo *Foo) {\n\ts.m[id] = foo\n\t// ...\n}\n\ntype Foo struct{}\n\nfunc updateMapValue(mapValue map[string]LargeStruct, id string) {\n\tvalue := mapValue[id]\n\tvalue.foo = \"bar\"\n\tmapValue[id] = value\n}\n\nfunc updateMapPointer(mapPointer map[string]*LargeStruct, id string) {\n\tmapPointer[id].foo = \"bar\"\n}\n\ntype LargeStruct struct {\n\tfoo string\n\t_   [1024]int64\n}\n"
  },
  {
    "path": "src/04-control-structures/32-range-loop-pointers/customer-store/main.go",
    "content": "package main\n\nimport \"fmt\"\n\ntype Customer struct {\n\tID      string\n\tBalance float64\n}\n\ntype Store struct {\n\tm map[string]*Customer\n}\n\nfunc main() {\n\ts := Store{\n\t\tm: make(map[string]*Customer),\n\t}\n\ts.storeCustomers([]Customer{\n\t\t{ID: \"1\", Balance: 10},\n\t\t{ID: \"2\", Balance: -10},\n\t\t{ID: \"3\", Balance: 0},\n\t})\n\tprint(s.m)\n}\n\nfunc (s *Store) storeCustomers(customers []Customer) {\n\tfor _, customer := range customers {\n\t\tfmt.Printf(\"%p\\n\", &customer)\n\t\ts.m[customer.ID] = &customer\n\t}\n}\n\nfunc (s *Store) storeCustomers2(customers []Customer) {\n\tfor _, customer := range customers {\n\t\tcurrent := customer\n\t\ts.m[current.ID] = &current\n\t}\n}\n\nfunc (s *Store) storeCustomers3(customers []Customer) {\n\tfor i := range customers {\n\t\tcustomer := &customers[i]\n\t\ts.m[customer.ID] = customer\n\t}\n}\n\nfunc print(m map[string]*Customer) {\n\tfor k, v := range m {\n\t\tfmt.Printf(\"key=%s, value=%#v\\n\", k, v)\n\t}\n}\n"
  },
  {
    "path": "src/04-control-structures/33-map-iteration/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc listing1() {\n\tm := map[int]bool{\n\t\t0: true,\n\t\t1: false,\n\t\t2: true,\n\t}\n\n\tfor k, v := range m {\n\t\tif v {\n\t\t\tm[10+k] = true\n\t\t}\n\t}\n\n\tfmt.Println(m)\n}\n\nfunc listing2() {\n\tm := map[int]bool{\n\t\t0: true,\n\t\t1: false,\n\t\t2: true,\n\t}\n\tm2 := copyMap(m)\n\n\tfor k, v := range m {\n\t\tm2[k] = v\n\t\tif v {\n\t\t\tm2[10+k] = true\n\t\t}\n\t}\n\n\tfmt.Println(m2)\n}\n\nfunc copyMap(m map[int]bool) map[int]bool {\n\tres := make(map[int]bool, len(m))\n\tfor k, v := range m {\n\t\tres[k] = v\n\t}\n\treturn res\n}\n"
  },
  {
    "path": "src/04-control-structures/34-break/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n)\n\nfunc listing1() {\n\tfor i := 0; i < 5; i++ {\n\t\tfmt.Printf(\"%d \", i)\n\n\t\tswitch i {\n\t\tdefault:\n\t\tcase 2:\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc listing2() {\nloop:\n\tfor i := 0; i < 5; i++ {\n\t\tfmt.Printf(\"%d \", i)\n\n\t\tswitch i {\n\t\tdefault:\n\t\tcase 2:\n\t\t\tbreak loop\n\t\t}\n\t}\n}\n\nfunc listing3(ctx context.Context, ch <-chan int) {\n\tfor {\n\t\tselect {\n\t\tcase <-ch:\n\t\t\t// Do something\n\t\tcase <-ctx.Done():\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc listing4(ctx context.Context, ch <-chan int) {\nloop:\n\tfor {\n\t\tselect {\n\t\tcase <-ch:\n\t\t\t// Do something\n\t\tcase <-ctx.Done():\n\t\t\tbreak loop\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/04-control-structures/35-defer-loop/main.go",
    "content": "package main\n\nimport \"os\"\n\nfunc readFiles1(ch <-chan string) error {\n\tfor path := range ch {\n\t\tfile, err := os.Open(path)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tdefer file.Close()\n\n\t\t// Do something with file\n\t}\n\treturn nil\n}\n\nfunc readFiles2(ch <-chan string) error {\n\tfor path := range ch {\n\t\tif err := readFile(path); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc readFile(path string) error {\n\tfile, err := os.Open(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer file.Close()\n\n\t// Do something with file\n\treturn nil\n}\n\nfunc readFiles3(ch <-chan string) error {\n\tfor path := range ch {\n\t\terr := func() error {\n\t\t\tfile, err := os.Open(path)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tdefer file.Close()\n\n\t\t\t// Do something with file\n\t\t\treturn nil\n\t\t}()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "src/05-strings/36-rune/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\ts := \"hello\"\n\tfmt.Println(len(s))\n\n\ts = \"汉\"\n\tfmt.Println(len(s))\n\n\ts = string([]byte{0xE6, 0xB1, 0x89})\n\tfmt.Printf(\"%s\\n\", s)\n}\n"
  },
  {
    "path": "src/05-strings/37-string-iteration/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\ts := \"hêllo\"\n\tfor i := range s {\n\t\tfmt.Printf(\"position %d: %c\\n\", i, s[i])\n\t}\n\tfmt.Printf(\"len=%d\\n\", len(s))\n\n\tfor i, r := range s {\n\t\tfmt.Printf(\"position %d: %c\\n\", i, r)\n\t}\n\n\trunes := []rune(s)\n\tfor i, r := range runes {\n\t\tfmt.Printf(\"position %d: %c\\n\", i, r)\n\t}\n\n\ts2 := \"hello\"\n\tfmt.Printf(\"%c\\n\", rune(s2[4]))\n}\n\nfunc getIthRune(largeString string, i int) rune {\n\tfor idx, v := range largeString {\n\t\tif idx == i {\n\t\t\treturn v\n\t\t}\n\t}\n\treturn -1\n}\n"
  },
  {
    "path": "src/05-strings/38-trim/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc main() {\n\tfmt.Println(strings.TrimRight(\"123oxo\", \"xo\"))\n\n\tfmt.Println(strings.TrimSuffix(\"123oxo\", \"xo\"))\n\n\tfmt.Println(strings.TrimLeft(\"oxo123\", \"ox\"))\n\tfmt.Println(strings.TrimPrefix(\"oxo123\", \"ox\"))\n\n\tfmt.Println(strings.Trim(\"oxo123oxo\", \"ox\"))\n}\n"
  },
  {
    "path": "src/05-strings/39-string-concat/main.go",
    "content": "package main\n\nimport \"strings\"\n\nfunc concat1(values []string) string {\n\ts := \"\"\n\tfor _, value := range values {\n\t\ts += value\n\t}\n\treturn s\n}\n\nfunc concat2(values []string) string {\n\tsb := strings.Builder{}\n\tfor _, value := range values {\n\t\t_, _ = sb.WriteString(value)\n\t}\n\treturn sb.String()\n}\n\nfunc concat3(values []string) string {\n\ttotal := 0\n\tfor i := 0; i < len(values); i++ {\n\t\ttotal += len(values[i])\n\t}\n\n\tsb := strings.Builder{}\n\tsb.Grow(total)\n\tfor _, value := range values {\n\t\t_, _ = sb.WriteString(value)\n\t}\n\treturn sb.String()\n}\n"
  },
  {
    "path": "src/05-strings/39-string-concat/main_test.go",
    "content": "package main\n\nimport \"testing\"\n\nvar global string\n\nfunc BenchmarkConcatV1(b *testing.B) {\n\tvar local string\n\ts := getInput()\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tlocal = concat1(s)\n\t}\n\tglobal = local\n}\n\nfunc BenchmarkConcatV2(b *testing.B) {\n\tvar local string\n\ts := getInput()\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tlocal = concat2(s)\n\t}\n\tglobal = local\n}\n\nfunc BenchmarkConcatV3(b *testing.B) {\n\tvar local string\n\ts := getInput()\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tlocal = concat3(s)\n\t}\n\tglobal = local\n}\n\nfunc getInput() []string {\n\tn := 1_000\n\ts := make([]string, n)\n\tfor i := 0; i < n; i++ {\n\t\ts[i] = string(make([]byte, 1_000))\n\t}\n\treturn s\n}\n"
  },
  {
    "path": "src/05-strings/40-string-conversion/main.go",
    "content": "package main\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"strings\"\n)\n\nfunc getBytes1(reader io.Reader) ([]byte, error) {\n\tb, err := io.ReadAll(reader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn []byte(sanitize1(string(b))), nil\n}\n\nfunc sanitize1(s string) string {\n\treturn strings.TrimSpace(s)\n}\n\nfunc getBytes2(reader io.Reader) ([]byte, error) {\n\tb, err := io.ReadAll(reader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn sanitize2(b), nil\n}\n\nfunc sanitize2(b []byte) []byte {\n\treturn bytes.TrimSpace(b)\n}\n"
  },
  {
    "path": "src/05-strings/41-substring-memory-leak/main.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc main() {\n\ts1 := \"Hello, World!\"\n\ts2 := s1[:5]\n\tfmt.Println(s2)\n\n\ts1 = \"Hêllo, World!\"\n\ts2 = string([]rune(s1)[:5])\n\tfmt.Println(s2)\n}\n\ntype store struct{}\n\nfunc (s store) handleLog1(log string) error {\n\tif len(log) < 36 {\n\t\treturn errors.New(\"log is not correctly formatted\")\n\t}\n\tuuid := log[:36]\n\ts.store(uuid)\n\t// Do something\n\treturn nil\n}\n\nfunc (s store) handleLog2(log string) error {\n\tif len(log) < 36 {\n\t\treturn errors.New(\"log is not correctly formatted\")\n\t}\n\tuuid := string([]byte(log[:36]))\n\ts.store(uuid)\n\t// Do something\n\treturn nil\n}\n\nfunc (s store) handleLog3(log string) error {\n\tif len(log) < 36 {\n\t\treturn errors.New(\"log is not correctly formatted\")\n\t}\n\tuuid := string(strings.Clone(log[:36]))\n\ts.store(uuid)\n\t// Do something\n\treturn nil\n}\n\nfunc (s store) store(uuid string) {\n\t// ...\n}\n"
  },
  {
    "path": "src/06-functions-methods/42-receiver/pointer/main.go",
    "content": "package main\n\nimport \"fmt\"\n\ntype customer struct {\n\tbalance float64\n}\n\nfunc (c *customer) add(operation float64) {\n\tc.balance += operation\n}\n\nfunc main() {\n\tc := customer{balance: 100.0}\n\tc.add(50.0)\n\tfmt.Printf(\"balance: %.2f\\n\", c.balance)\n}\n"
  },
  {
    "path": "src/06-functions-methods/42-receiver/struct-with-pointer/main.go",
    "content": "package main\n\nimport \"fmt\"\n\ntype customer struct {\n\tdata *data\n}\n\ntype data struct {\n\tbalance float64\n}\n\nfunc (c customer) add(operation float64) {\n\tc.data.balance += operation\n}\n\nfunc main() {\n\tc := customer{data: &data{\n\t\tbalance: 100,\n\t}}\n\tc.add(50.)\n\tfmt.Printf(\"balance: %.2f\\n\", c.data.balance)\n}\n"
  },
  {
    "path": "src/06-functions-methods/42-receiver/value/main.go",
    "content": "package main\n\nimport \"fmt\"\n\ntype customer struct {\n\tbalance float64\n}\n\nfunc (c customer) add(v float64) {\n\tc.balance += v\n}\n\nfunc main() {\n\tc := customer{balance: 100.}\n\tc.add(50.)\n\tfmt.Printf(\"balance: %.2f\\n\", c.balance)\n}\n"
  },
  {
    "path": "src/06-functions-methods/43-named-result-parameters/main.go",
    "content": "package main\n\nimport \"io\"\n\nfunc f(a int) (b int) {\n\tb = a\n\treturn\n}\n\ntype locator interface {\n\tgetCoordinates(address string) (float32, float32, error)\n\t// getCoordinates(address string) (lat, lng float32, err error)\n}\n\ntype loc struct{}\n\nfunc (l loc) getCoordinates(address string) (lat, lng float32, err error) {\n\treturn 0, 0, nil\n}\n\nfunc ReadFull(r io.Reader, buf []byte) (n int, err error) {\n\tfor len(buf) > 0 && err == nil {\n\t\tvar nr int\n\t\tnr, err = r.Read(buf)\n\t\tn += nr\n\t\tbuf = buf[nr:]\n\t}\n\treturn\n}\n"
  },
  {
    "path": "src/06-functions-methods/44-side-effects-named-result-parameters/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n)\n\ntype loc struct{}\n\nfunc (l loc) getCoordinates1(ctx context.Context, address string) (\n\tlat, lng float32, err error) {\n\tisValid := l.validateAddress(address)\n\tif !isValid {\n\t\treturn 0, 0, errors.New(\"invalid address\")\n\t}\n\n\tif ctx.Err() != nil {\n\t\treturn 0, 0, err\n\t}\n\n\t// Get and return coordinates\n\treturn 0, 0, nil\n}\n\nfunc (l loc) getCoordinates2(ctx context.Context, address string) (\n\tlat, lng float32, err error) {\n\tisValid := l.validateAddress(address)\n\tif !isValid {\n\t\treturn 0, 0, errors.New(\"invalid address\")\n\t}\n\n\tif err := ctx.Err(); err != nil {\n\t\treturn 0, 0, err\n\t}\n\n\t// Get and return coordinates\n\treturn 0, 0, nil\n}\n\nfunc (l loc) getCoordinates3(ctx context.Context, address string) (\n\tlat, lng float32, err error) {\n\tisValid := l.validateAddress(address)\n\tif !isValid {\n\t\treturn 0, 0, errors.New(\"invalid address\")\n\t}\n\n\tif err = ctx.Err(); err != nil {\n\t\treturn\n\t}\n\n\t// Get and return coordinates\n\treturn 0, 0, nil\n}\n\nfunc (l loc) validateAddress(address string) bool {\n\treturn true\n}\n"
  },
  {
    "path": "src/06-functions-methods/45-nil-receiver/main.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"log\"\n\t\"strings\"\n)\n\ntype MultiError struct {\n\terrs []string\n}\n\nfunc (m *MultiError) Add(err error) {\n\tm.errs = append(m.errs, err.Error())\n}\n\nfunc (m *MultiError) Error() string {\n\treturn strings.Join(m.errs, \";\")\n}\n\ntype Customer struct {\n\tAge  int\n\tName string\n}\n\nfunc (c Customer) Validate1() error {\n\tvar m *MultiError\n\n\tif c.Age < 0 {\n\t\tm = &MultiError{}\n\t\tm.Add(errors.New(\"age is negative\"))\n\t}\n\tif c.Name == \"\" {\n\t\tif m == nil {\n\t\t\tm = &MultiError{}\n\t\t}\n\t\tm.Add(errors.New(\"name is nil\"))\n\t}\n\n\treturn m\n}\n\nfunc (c Customer) Validate2() error {\n\tvar m *MultiError\n\n\tif c.Age < 0 {\n\t\tm = &MultiError{}\n\t\tm.Add(errors.New(\"age is negative\"))\n\t}\n\tif c.Name == \"\" {\n\t\tif m == nil {\n\t\t\tm = &MultiError{}\n\t\t}\n\t\tm.Add(errors.New(\"name is nil\"))\n\t}\n\n\tif m != nil {\n\t\treturn m\n\t}\n\treturn nil\n}\n\nfunc main() {\n\tcustomer := Customer{Age: 33, Name: \"John\"}\n\tif err := customer.Validate1(); err != nil {\n\t\tlog.Fatalf(\"customer is invalid: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "src/06-functions-methods/46-function-input/main.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\t\"os\"\n)\n\nfunc countEmptyLinesInFile(filename string) (int, error) {\n\tfile, err := os.Open(filename)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\t// Handle file closure\n\n\tscanner := bufio.NewScanner(file)\n\tfor scanner.Scan() {\n\t\t// ...\n\t}\n\n\treturn 0, nil\n}\n\nfunc countEmptyLines(reader io.Reader) (int, error) {\n\tscanner := bufio.NewScanner(reader)\n\tfor scanner.Scan() {\n\t\t// ...\n\t}\n\treturn 0, nil\n}\n\nfunc main() {\n\tfile, err := os.Open(\"main.go\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\t_, _ = countEmptyLines(file)\n}\n"
  },
  {
    "path": "src/06-functions-methods/46-function-input/main_test.go",
    "content": "package main\n\nimport (\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestCountEmptyLines(t *testing.T) {\n\temptyLines, err := countEmptyLines(strings.NewReader(\n\t\t`foo\n\t\t\tbar\n\n\t\t\tbaz\n\t\t\t`))\n\t// Test logic\n\t_ = emptyLines\n\t_ = err\n}\n"
  },
  {
    "path": "src/06-functions-methods/47-defer-evaluation/args/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nconst (\n\tStatusSuccess  = \"success\"\n\tStatusErrorFoo = \"error_foo\"\n\tStatusErrorBar = \"error_bar\"\n)\n\nfunc main() {\n\t_ = f1()\n\t_ = f2()\n\t_ = f3()\n}\n\nfunc f1() error {\n\tvar status string\n\tdefer notify(status)\n\tdefer incrementCounter(status)\n\n\tif err := foo(); err != nil {\n\t\tstatus = StatusErrorFoo\n\t\treturn err\n\t}\n\n\tif err := bar(); err != nil {\n\t\tstatus = StatusErrorBar\n\t\treturn err\n\t}\n\n\tstatus = StatusSuccess\n\treturn nil\n}\n\nfunc f2() error {\n\tvar status string\n\tdefer notifyPtr(&status)\n\tdefer incrementCounterPtr(&status)\n\n\tif err := foo(); err != nil {\n\t\tstatus = StatusErrorFoo\n\t\treturn err\n\t}\n\n\tif err := bar(); err != nil {\n\t\tstatus = StatusErrorBar\n\t\treturn err\n\t}\n\n\tstatus = StatusSuccess\n\treturn nil\n}\n\nfunc f3() error {\n\tvar status string\n\tdefer func() {\n\t\tnotify(status)\n\t\tincrementCounter(status)\n\t}()\n\n\tif err := foo(); err != nil {\n\t\tstatus = StatusErrorFoo\n\t\treturn err\n\t}\n\n\tif err := bar(); err != nil {\n\t\tstatus = StatusErrorBar\n\t\treturn err\n\t}\n\n\tstatus = StatusSuccess\n\treturn nil\n}\n\nfunc notify(status string) {\n\tfmt.Println(\"notify:\", status)\n}\n\nfunc incrementCounter(status string) {\n\tfmt.Println(\"increment:\", status)\n}\n\nfunc notifyPtr(status *string) {\n\tfmt.Println(\"notify:\", *status)\n}\n\nfunc incrementCounterPtr(status *string) {\n\tfmt.Println(\"increment:\", *status)\n}\n\nfunc foo() error {\n\treturn nil\n}\n\nfunc bar() error {\n\treturn nil\n}\n"
  },
  {
    "path": "src/06-functions-methods/47-defer-evaluation/receiver/pointer/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\ts := &Struct{id: \"foo\"}\n\tdefer s.print()\n\ts.id = \"bar\"\n}\n\ntype Struct struct {\n\tid string\n}\n\nfunc (s *Struct) print() {\n\tfmt.Println(s.id)\n}\n"
  },
  {
    "path": "src/06-functions-methods/47-defer-evaluation/receiver/value/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\ts := Struct{id: \"foo\"}\n\tdefer s.print()\n\ts.id = \"bar\"\n}\n\ntype Struct struct {\n\tid string\n}\n\nfunc (s Struct) print() {\n\tfmt.Println(s.id)\n}\n"
  },
  {
    "path": "src/07-error-management/48-panic/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tfmt.Println(\"recover\", r)\n\t\t}\n\t}()\n\n\tf()\n}\n\nfunc f() {\n\tfmt.Println(\"a\")\n\tpanic(\"foo\")\n\tfmt.Println(\"b\")\n}\n\nfunc checkWriteHeaderCode(code int) {\n\tif code < 100 || code > 999 {\n\t\tpanic(fmt.Sprintf(\"invalid WriteHeader code %v\", code))\n\t}\n}\n"
  },
  {
    "path": "src/07-error-management/49-error-wrapping/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc bar() error {\n\treturn barError{}\n}\n\ntype barError struct{}\n\nfunc (b barError) Error() string {\n\treturn \"bar error\"\n}\n\nfunc listing1() error {\n\terr := bar()\n\tif err != nil {\n\t\treturn err\n\t}\n\t// ...\n\treturn nil\n}\n\ntype BarError struct {\n\tErr error\n}\n\nfunc (b BarError) Error() string {\n\treturn \"bar failed:\" + b.Err.Error()\n}\n\nfunc listing2() error {\n\terr := bar()\n\tif err != nil {\n\t\treturn BarError{Err: err}\n\t}\n\t// ...\n\treturn nil\n}\n\nfunc listing3() error {\n\terr := bar()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"bar failed: %w\", err)\n\t}\n\t// ...\n\treturn nil\n}\n\nfunc listing4() error {\n\terr := bar()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"bar failed: %v\", err)\n\t}\n\t// ...\n\treturn nil\n}\n"
  },
  {
    "path": "src/07-error-management/50-compare-error-type/main.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n)\n\ntype transientError struct {\n\terr error\n}\n\nfunc (t transientError) Error() string {\n\treturn fmt.Sprintf(\"transient error: %v\", t.err)\n}\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\ttransactionID := r.URL.Query().Get(\"transaction\")\n\n\tamount, err := getTransactionAmount1(transactionID)\n\tif err != nil {\n\t\tswitch err := err.(type) {\n\t\tcase transientError:\n\t\t\thttp.Error(w, err.Error(), http.StatusServiceUnavailable)\n\t\tdefault:\n\t\t\thttp.Error(w, err.Error(), http.StatusBadRequest)\n\t\t}\n\t\treturn\n\t}\n\n\t// Write response\n\t_ = amount\n}\n\nfunc getTransactionAmount1(transactionID string) (float32, error) {\n\tif len(transactionID) != 5 {\n\t\treturn 0, fmt.Errorf(\"id is invalid: %s\", transactionID)\n\t}\n\n\tamount, err := getTransactionAmountFromDB1(transactionID)\n\tif err != nil {\n\t\treturn 0, transientError{err: err}\n\t}\n\treturn amount, nil\n}\n\nfunc getTransactionAmountFromDB1(id string) (float32, error) {\n\treturn 0, nil\n}\n\nfunc handler2(w http.ResponseWriter, r *http.Request) {\n\ttransactionID := r.URL.Query().Get(\"transaction\")\n\n\tamount, err := getTransactionAmount2(transactionID)\n\tif err != nil {\n\t\tif errors.As(err, &transientError{}) {\n\t\t\thttp.Error(w, err.Error(), http.StatusServiceUnavailable)\n\t\t} else {\n\t\t\thttp.Error(w, err.Error(), http.StatusBadRequest)\n\t\t}\n\t\treturn\n\t}\n\n\t// Write response\n\t_ = amount\n}\n\nfunc getTransactionAmount2(transactionID string) (float32, error) {\n\t// Check transaction ID validity\n\n\tamount, err := getTransactionAmountFromDB2(transactionID)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"failed to get transaction %s: %w\",\n\t\t\ttransactionID, err)\n\t}\n\treturn amount, nil\n}\n\nfunc getTransactionAmountFromDB2(transactionID string) (float32, error) {\n\t// ...\n\tvar err error\n\tif err != nil {\n\t\treturn 0, transientError{err: err}\n\t}\n\t// ...\n\treturn 0, nil\n}\n"
  },
  {
    "path": "src/07-error-management/51-comparing-error-value/main.go",
    "content": "package main\n\nimport (\n\t\"database/sql\"\n\t\"errors\"\n)\n\nfunc listing1() {\n\terr := query()\n\tif err != nil {\n\t\tif err == sql.ErrNoRows {\n\t\t\t// ...\n\t\t} else {\n\t\t\t// ...\n\t\t}\n\t}\n}\n\nfunc listing2() {\n\terr := query()\n\tif err != nil {\n\t\tif errors.Is(err, sql.ErrNoRows) {\n\t\t\t// ...\n\t\t} else {\n\t\t\t// ...\n\t\t}\n\t}\n}\n\nfunc query() error {\n\treturn nil\n}\n"
  },
  {
    "path": "src/07-error-management/52-handling-error-twice/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n)\n\ntype Route struct{}\n\nfunc GetRoute1(srcLat, srcLng, dstLat, dstLng float32) (Route, error) {\n\terr := validateCoordinates1(srcLat, srcLng)\n\tif err != nil {\n\t\tlog.Println(\"failed to validate source coordinates\")\n\t\treturn Route{}, err\n\t}\n\n\terr = validateCoordinates1(dstLat, dstLng)\n\tif err != nil {\n\t\tlog.Println(\"failed to validate target coordinates\")\n\t\treturn Route{}, err\n\t}\n\n\treturn getRoute(srcLat, srcLng, dstLat, dstLng)\n}\n\nfunc validateCoordinates1(lat, lng float32) error {\n\tif lat > 90.0 || lat < -90.0 {\n\t\tlog.Printf(\"invalid latitude: %f\", lat)\n\t\treturn fmt.Errorf(\"invalid latitude: %f\", lat)\n\t}\n\tif lng > 180.0 || lng < -180.0 {\n\t\tlog.Printf(\"invalid longitude: %f\", lng)\n\t\treturn fmt.Errorf(\"invalid longitude: %f\", lng)\n\t}\n\treturn nil\n}\n\nfunc GetRoute2(srcLat, srcLng, dstLat, dstLng float32) (Route, error) {\n\terr := validateCoordinates2(srcLat, srcLng)\n\tif err != nil {\n\t\treturn Route{}, err\n\t}\n\n\terr = validateCoordinates2(dstLat, dstLng)\n\tif err != nil {\n\t\treturn Route{}, err\n\t}\n\n\treturn getRoute(srcLat, srcLng, dstLat, dstLng)\n}\n\nfunc validateCoordinates2(lat, lng float32) error {\n\tif lat > 90.0 || lat < -90.0 {\n\t\treturn fmt.Errorf(\"invalid latitude: %f\", lat)\n\t}\n\tif lng > 180.0 || lng < -180.0 {\n\t\treturn fmt.Errorf(\"invalid longitude: %f\", lng)\n\t}\n\treturn nil\n}\n\nfunc GetRoute3(srcLat, srcLng, dstLat, dstLng float32) (Route, error) {\n\terr := validateCoordinates2(srcLat, srcLng)\n\tif err != nil {\n\t\treturn Route{},\n\t\t\tfmt.Errorf(\"failed to validate source coordinates: %w\", err)\n\t}\n\n\terr = validateCoordinates2(dstLat, dstLng)\n\tif err != nil {\n\t\treturn Route{},\n\t\t\tfmt.Errorf(\"failed to validate target coordinates: %w\", err)\n\t}\n\n\treturn getRoute(srcLat, srcLng, dstLat, dstLng)\n}\n\nfunc getRoute(lat, lng, lat2, lng2 float32) (Route, error) {\n\treturn Route{}, nil\n}\n"
  },
  {
    "path": "src/07-error-management/53-not-handling-error/main.go",
    "content": "package main\n\nimport \"errors\"\n\nfunc listing1() {\n\t// ...\n\n\tnotify()\n}\n\nfunc listing2() {\n\t// ...\n\n\t// Notifications are sent in best effort.\n\t// Hence, it's accepted to miss some of them in case of errors.\n\t_ = notify()\n}\n\nfunc notify() error {\n\treturn errors.New(\"failed to notify\")\n}\n"
  },
  {
    "path": "src/07-error-management/54-defer-errors/main.go",
    "content": "package main\n\nimport (\n\t\"database/sql\"\n\t\"log\"\n)\n\nconst query = \"...\"\n\nfunc getBalance1(db *sql.DB, clientID string) (float32, error) {\n\trows, err := db.Query(query, clientID)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tdefer rows.Close()\n\n\t// Use rows\n\treturn 0, nil\n}\n\nfunc getBalance2(db *sql.DB, clientID string) (float32, error) {\n\trows, err := db.Query(query, clientID)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tdefer func() { _ = rows.Close() }()\n\n\t// Use rows\n\treturn 0, nil\n}\n\nfunc getBalance3(db *sql.DB, clientID string) (balance float32, err error) {\n\trows, err := db.Query(query, clientID)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tdefer func() {\n\t\tcloseErr := rows.Close()\n\t\tif err != nil {\n\t\t\tif closeErr != nil {\n\t\t\t\tlog.Printf(\"failed to close rows: %v\", closeErr)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\terr = closeErr\n\t}()\n\n\t// Use rows\n\treturn 0, nil\n}\n"
  },
  {
    "path": "src/08-concurrency-foundations/56-faster/main.go",
    "content": "package main\n\nimport (\n\t\"sync\"\n)\n\nfunc sequentialMergesort(s []int) {\n\tif len(s) <= 1 {\n\t\treturn\n\t}\n\n\tmiddle := len(s) / 2\n\tsequentialMergesort(s[:middle])\n\tsequentialMergesort(s[middle:])\n\tmerge(s, middle)\n}\n\nfunc parallelMergesortV1(s []int) {\n\tif len(s) <= 1 {\n\t\treturn\n\t}\n\n\tmiddle := len(s) / 2\n\n\tvar wg sync.WaitGroup\n\twg.Add(2)\n\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tparallelMergesortV1(s[:middle])\n\t}()\n\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tparallelMergesortV1(s[middle:])\n\t}()\n\n\twg.Wait()\n\tmerge(s, middle)\n}\n\nconst max = 2048\n\nfunc parallelMergesortV2(s []int) {\n\tif len(s) <= 1 {\n\t\treturn\n\t}\n\n\tif len(s) <= max {\n\t\tsequentialMergesort(s)\n\t} else {\n\t\tmiddle := len(s) / 2\n\n\t\tvar wg sync.WaitGroup\n\t\twg.Add(2)\n\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\tparallelMergesortV2(s[:middle])\n\t\t}()\n\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\tparallelMergesortV2(s[middle:])\n\t\t}()\n\n\t\twg.Wait()\n\t\tmerge(s, middle)\n\t}\n}\n\nfunc merge(s []int, middle int) {\n\thelper := make([]int, len(s))\n\tcopy(helper, s)\n\n\thelperLeft := 0\n\thelperRight := middle\n\tcurrent := 0\n\thigh := len(s) - 1\n\n\tfor helperLeft <= middle-1 && helperRight <= high {\n\t\tif helper[helperLeft] <= helper[helperRight] {\n\t\t\ts[current] = helper[helperLeft]\n\t\t\thelperLeft++\n\t\t} else {\n\t\t\ts[current] = helper[helperRight]\n\t\t\thelperRight++\n\t\t}\n\t\tcurrent++\n\t}\n\n\tfor helperLeft <= middle-1 {\n\t\ts[current] = helper[helperLeft]\n\t\tcurrent++\n\t\thelperLeft++\n\t}\n}\n"
  },
  {
    "path": "src/08-concurrency-foundations/56-faster/main_test.go",
    "content": "package main\n\nimport (\n\t\"math/rand\"\n\t\"testing\"\n\t\"time\"\n)\n\nvar global []int\n\nfunc Benchmark_sequentialMergesort(b *testing.B) {\n\tvar local []int\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer()\n\t\tinput := getRandomElements()\n\t\tb.StartTimer()\n\n\t\tsequentialMergesort(input)\n\t\tlocal = input\n\t}\n\tglobal = local\n}\n\nfunc Benchmark_parallelMergesortV1(b *testing.B) {\n\tvar local []int\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer()\n\t\tinput := getRandomElements()\n\t\tb.StartTimer()\n\n\t\tparallelMergesortV1(input)\n\t\tlocal = input\n\t}\n\tglobal = local\n}\n\nfunc Benchmark_parallelMergesortV2(b *testing.B) {\n\tvar local []int\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer()\n\t\tinput := getRandomElements()\n\t\tb.StartTimer()\n\n\t\tparallelMergesortV2(input)\n\t\tlocal = input\n\t}\n\tglobal = local\n}\n\nfunc getRandomElements() []int {\n\tn := 10_000\n\tres := make([]int, n)\n\tsrc := rand.NewSource(time.Now().UnixNano())\n\trnd := rand.New(src)\n\tfor i := 0; i < n; i++ {\n\t\tres[i] = rnd.Int()\n\t}\n\treturn res\n}\n"
  },
  {
    "path": "src/08-concurrency-foundations/58-races/memory-model/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc listing1() {\n\ti := 0\n\tgo func() {\n\t\ti++\n\t}()\n}\n\nfunc listing2() {\n\ti := 0\n\tgo func() {\n\t\ti++\n\t}()\n\tfmt.Println(i)\n}\n\nfunc listing3() {\n\ti := 0\n\tch := make(chan struct{})\n\tgo func() {\n\t\t<-ch\n\t\tfmt.Println(i)\n\t}()\n\ti++\n\tch <- struct{}{}\n}\n\nfunc listing4() {\n\ti := 0\n\tch := make(chan struct{})\n\tgo func() {\n\t\t<-ch\n\t\tfmt.Println(i)\n\t}()\n\ti++\n\tclose(ch)\n}\n\nfunc listing5() {\n\ti := 0\n\tch := make(chan struct{}, 1)\n\tgo func() {\n\t\ti = 1\n\t\t<-ch\n\t}()\n\tch <- struct{}{}\n\tfmt.Println(i)\n}\n\nfunc listing6() {\n\ti := 0\n\tch := make(chan struct{})\n\tgo func() {\n\t\ti = 1\n\t\t<-ch\n\t}()\n\tch <- struct{}{}\n\tfmt.Println(i)\n}\n"
  },
  {
    "path": "src/08-concurrency-foundations/58-races/races/main.go",
    "content": "package races\n\nimport (\n\t\"sync\"\n\t\"sync/atomic\"\n)\n\nfunc listing1() {\n\ti := 0\n\n\tgo func() {\n\t\ti++\n\t}()\n\n\tgo func() {\n\t\ti++\n\t}()\n}\n\nfunc listing2() {\n\tvar i int64\n\n\tgo func() {\n\t\tatomic.AddInt64(&i, 1)\n\t}()\n\n\tgo func() {\n\t\tatomic.AddInt64(&i, 1)\n\t}()\n}\n\nfunc listing3() {\n\ti := 0\n\tmutex := sync.Mutex{}\n\n\tgo func() {\n\t\tmutex.Lock()\n\t\ti++\n\t\tmutex.Unlock()\n\t}()\n\n\tgo func() {\n\t\tmutex.Lock()\n\t\ti++\n\t\tmutex.Unlock()\n\t}()\n}\n\nfunc listing4() {\n\ti := 0\n\tch := make(chan int)\n\n\tgo func() {\n\t\tch <- 1\n\t}()\n\n\tgo func() {\n\t\tch <- 1\n\t}()\n\n\ti += <-ch\n\ti += <-ch\n}\n\nfunc listing5() {\n\ti := 0\n\tmutex := sync.Mutex{}\n\n\tgo func() {\n\t\tmutex.Lock()\n\t\tdefer mutex.Unlock()\n\t\ti = 1\n\t}()\n\n\tgo func() {\n\t\tmutex.Lock()\n\t\tdefer mutex.Unlock()\n\t\ti = 2\n\t}()\n\n\t_ = i\n}\n"
  },
  {
    "path": "src/08-concurrency-foundations/59-workload-type/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"sync\"\n\t\"sync/atomic\"\n)\n\nfunc main() {\n\tres1, _ := read1(&dummyReader{})\n\tfmt.Println(res1)\n\n\tres2, _ := read2(&dummyReader{})\n\tfmt.Println(res2)\n}\n\nfunc read1(r io.Reader) (int, error) {\n\tcount := 0\n\tfor {\n\t\tb := make([]byte, 1024)\n\t\t_, err := r.Read(b)\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn 0, err\n\t\t}\n\t\tcount += task(b)\n\t}\n\treturn count, nil\n}\n\nfunc read2(r io.Reader) (int, error) {\n\tvar count int64\n\twg := sync.WaitGroup{}\n\tn := 10\n\n\tch := make(chan []byte, n)\n\twg.Add(n)\n\tfor i := 0; i < n; i++ {\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\tfor b := range ch {\n\t\t\t\tv := task(b)\n\t\t\t\tatomic.AddInt64(&count, int64(v))\n\t\t\t}\n\t\t}()\n\t}\n\n\tfor {\n\t\tb := make([]byte, 1024)\n\t\t_, err := r.Read(b)\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn 0, err\n\t\t}\n\t\tch <- b\n\t}\n\n\tclose(ch)\n\twg.Wait()\n\treturn int(count), nil\n}\n\nfunc task(b []byte) int {\n\treturn len(b)\n}\n\ntype dummyReader struct {\n\ti int\n}\n\nfunc (c *dummyReader) Read(p []byte) (n int, err error) {\n\tif c.i == 3 {\n\t\treturn 0, io.EOF\n\t}\n\tcopy(p, []byte{0, 1, 2})\n\tc.i++\n\treturn 3, nil\n}\n"
  },
  {
    "path": "src/08-concurrency-foundations/60-contexts/flight/flight.go",
    "content": "package flight\n\ntype Position struct {\n\tLat float32\n\tLng float32\n}\n"
  },
  {
    "path": "src/08-concurrency-foundations/60-contexts/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/teivah/100-go-mistakes/src/08-concurrency-foundations/60-contexts/flight\"\n)\n\ntype publisher interface {\n\tPublish(ctx context.Context, position flight.Position) error\n}\n\ntype publishHandler struct {\n\tpub publisher\n}\n\nfunc (h publishHandler) publishPosition(position flight.Position) error {\n\tctx, cancel := context.WithTimeout(context.Background(), 4*time.Second)\n\tdefer cancel()\n\treturn h.pub.Publish(ctx, position)\n}\n\ntype key string\n\nconst isValidHostKey key = \"isValidHost\"\n\nfunc checkValid(next http.Handler) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tvalidHost := r.Host == \"acme\"\n\t\tctx := context.WithValue(r.Context(), isValidHostKey, validHost)\n\n\t\tnext.ServeHTTP(w, r.WithContext(ctx))\n\t})\n}\n\nfunc handler(ctx context.Context, ch chan Message) error {\n\tfor {\n\t\tselect {\n\t\tcase msg := <-ch:\n\t\t\t// Do something with msg\n\t\t\t_ = msg\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\t}\n\t}\n}\n\ntype Message struct{}\n"
  },
  {
    "path": "src/09-concurrency-practice/61-inappropriate-context/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"time\"\n)\n\nfunc handler1(w http.ResponseWriter, r *http.Request) {\n\tresponse, err := doSomeTask(r.Context(), r)\n\tif err != nil {\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tgo func() {\n\t\terr := publish(r.Context(), response)\n\t\t// Do something with err\n\t\t_ = err\n\t}()\n\n\twriteResponse(response)\n}\n\nfunc handler2(w http.ResponseWriter, r *http.Request) {\n\tresponse, err := doSomeTask(r.Context(), r)\n\tif err != nil {\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tgo func() {\n\t\terr := publish(context.Background(), response)\n\t\t// Do something with err\n\t\t_ = err\n\t}()\n\n\twriteResponse(response)\n}\n\nfunc handler3(w http.ResponseWriter, r *http.Request) {\n\tresponse, err := doSomeTask(r.Context(), r)\n\tif err != nil {\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tgo func() {\n\t\terr := publish(detach{ctx: r.Context()}, response)\n\t\t// Do something with err\n\t\t_ = err\n\t}()\n\n\twriteResponse(response)\n}\n\ntype detach struct {\n\tctx context.Context\n}\n\nfunc (d detach) Deadline() (time.Time, bool) {\n\treturn time.Time{}, false\n}\n\nfunc (d detach) Done() <-chan struct{} {\n\treturn nil\n}\n\nfunc (d detach) Err() error {\n\treturn nil\n}\n\nfunc (d detach) Value(key any) any {\n\treturn d.ctx.Value(key)\n}\n\nfunc doSomeTask(context.Context, *http.Request) (string, error) {\n\treturn \"\", nil\n}\n\nfunc publish(context.Context, string) error {\n\treturn nil\n}\n\nfunc writeResponse(string) {}\n"
  },
  {
    "path": "src/09-concurrency-practice/62-starting-goroutine/listing1/main.go",
    "content": "package main\n\nfunc main() {\n\tnewWatcher()\n\n\t// Run the application\n}\n\nfunc newWatcher() {\n\tw := watcher{}\n\tgo w.watch()\n}\n\ntype watcher struct { /* Some resources */\n}\n\nfunc (w watcher) watch() {}\n"
  },
  {
    "path": "src/09-concurrency-practice/62-starting-goroutine/listing2/main.go",
    "content": "package main\n\nimport \"context\"\n\nfunc main() {\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\n\tnewWatcher(ctx)\n\n\t// Run the application\n}\n\nfunc newWatcher(ctx context.Context) {\n\tw := watcher{}\n\tgo w.watch(ctx)\n}\n\ntype watcher struct { /* Some resources */\n}\n\nfunc (w watcher) watch(context.Context) {}\n"
  },
  {
    "path": "src/09-concurrency-practice/62-starting-goroutine/listing3/main.go",
    "content": "package main\n\nfunc main() {\n\tw := newWatcher()\n\tdefer w.close()\n\n\t// Run the application\n}\n\nfunc newWatcher() watcher {\n\tw := watcher{}\n\tgo w.watch()\n\treturn w\n}\n\ntype watcher struct { /* Some resources */\n}\n\nfunc (w watcher) watch() {}\n\nfunc (w watcher) close() {\n\t// Close the resources\n}\n"
  },
  {
    "path": "src/09-concurrency-practice/63-goroutines-loop-variables/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc listing1() {\n\ts := []int{1, 2, 3}\n\n\tfor _, i := range s {\n\t\tgo func() {\n\t\t\tfmt.Print(i)\n\t\t}()\n\t}\n}\n\nfunc listing2() {\n\ts := []int{1, 2, 3}\n\n\tfor _, i := range s {\n\t\tval := i\n\t\tgo func() {\n\t\t\tfmt.Print(val)\n\t\t}()\n\t}\n}\n\nfunc listing3() {\n\ts := []int{1, 2, 3}\n\n\tfor _, i := range s {\n\t\tgo func(val int) {\n\t\t\tfmt.Print(val)\n\t\t}(i)\n\t}\n}\n"
  },
  {
    "path": "src/09-concurrency-practice/64-select-behavior/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc main() {\n\tmessageCh := make(chan int, 10)\n\tdisconnectCh := make(chan struct{})\n\n\tgo listing1(messageCh, disconnectCh)\n\n\tfor i := 0; i < 10; i++ {\n\t\tmessageCh <- i\n\t}\n\tdisconnectCh <- struct{}{}\n\ttime.Sleep(10 * time.Millisecond)\n}\n\nfunc listing1(messageCh <-chan int, disconnectCh chan struct{}) {\n\tfor {\n\t\tselect {\n\t\tcase v := <-messageCh:\n\t\t\tfmt.Println(v)\n\t\tcase <-disconnectCh:\n\t\t\tfmt.Println(\"disconnection, return\")\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc listing2(messageCh <-chan int, disconnectCh chan struct{}) {\n\tfor {\n\t\tselect {\n\t\tcase v := <-messageCh:\n\t\t\tfmt.Println(v)\n\t\tcase <-disconnectCh:\n\t\t\tfor {\n\t\t\t\tselect {\n\t\t\t\tcase v := <-messageCh:\n\t\t\t\t\tfmt.Println(v)\n\t\t\t\tdefault:\n\t\t\t\t\tfmt.Println(\"disconnection, return\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/09-concurrency-practice/66-nil-channels/main.go",
    "content": "package main\n\nfunc merge1(ch1, ch2 <-chan int) <-chan int {\n\tch := make(chan int, 1)\n\n\tgo func() {\n\t\tfor v := range ch1 {\n\t\t\tch <- v\n\t\t}\n\t\tfor v := range ch2 {\n\t\t\tch <- v\n\t\t}\n\t\tclose(ch)\n\t}()\n\n\treturn ch\n}\n\nfunc merge2(ch1, ch2 <-chan int) <-chan int {\n\tch := make(chan int, 1)\n\n\tgo func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase v := <-ch1:\n\t\t\t\tch <- v\n\t\t\tcase v := <-ch2:\n\t\t\t\tch <- v\n\t\t\t}\n\t\t}\n\t\tclose(ch)\n\t}()\n\n\treturn ch\n}\n\nfunc merge3(ch1, ch2 <-chan int) <-chan int {\n\tch := make(chan int, 1)\n\tch1Closed := false\n\tch2Closed := false\n\n\tgo func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase v, open := <-ch1:\n\t\t\t\tif !open {\n\t\t\t\t\tch1Closed = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tch <- v\n\t\t\tcase v, open := <-ch2:\n\t\t\t\tif !open {\n\t\t\t\t\tch2Closed = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tch <- v\n\t\t\t}\n\n\t\t\tif ch1Closed && ch2Closed {\n\t\t\t\tclose(ch)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\treturn ch\n}\n\nfunc merge4(ch1, ch2 <-chan int) <-chan int {\n\tch := make(chan int, 1)\n\n\tgo func() {\n\t\tfor ch1 != nil || ch2 != nil {\n\t\t\tselect {\n\t\t\tcase v, open := <-ch1:\n\t\t\t\tif !open {\n\t\t\t\t\tch1 = nil\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tch <- v\n\t\t\tcase v, open := <-ch2:\n\t\t\t\tif !open {\n\t\t\t\t\tch2 = nil\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tch <- v\n\t\t\t}\n\t\t}\n\t\tclose(ch)\n\t}()\n\n\treturn ch\n}\n"
  },
  {
    "path": "src/09-concurrency-practice/68-string-formatting/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n)\n\nfunc main() {\n\tcustomer := Customer{}\n\t_ = customer.UpdateAge1(-1)\n\t_ = customer.UpdateAge2(-1)\n\t_ = customer.UpdateAge3(-1)\n}\n\ntype Customer struct {\n\tmutex sync.RWMutex\n\tid    string\n\tage   int\n}\n\nfunc (c *Customer) UpdateAge1(age int) error {\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\n\tif age < 0 {\n\t\treturn fmt.Errorf(\"age should be positive for customer %v\", c)\n\t}\n\n\tc.age = age\n\treturn nil\n}\n\nfunc (c *Customer) UpdateAge2(age int) error {\n\tif age < 0 {\n\t\treturn fmt.Errorf(\"age should be positive for customer %v\", c)\n\t}\n\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\n\tc.age = age\n\treturn nil\n}\n\nfunc (c *Customer) UpdateAge3(age int) error {\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\n\tif age < 0 {\n\t\treturn fmt.Errorf(\"age should be positive for customer id %s\", c.id)\n\t}\n\n\tc.age = age\n\treturn nil\n}\n\nfunc (c *Customer) String() string {\n\tc.mutex.RLock()\n\tdefer c.mutex.RUnlock()\n\treturn fmt.Sprintf(\"id %s, age %d\", c.id, c.age)\n}\n"
  },
  {
    "path": "src/09-concurrency-practice/69-data-race-append/main.go",
    "content": "package main\n\nimport \"fmt\"\n\nfunc listing1() {\n\ts := make([]int, 1)\n\n\tgo func() {\n\t\ts1 := append(s, 1)\n\t\tfmt.Println(s1)\n\t}()\n\n\tgo func() {\n\t\ts2 := append(s, 1)\n\t\tfmt.Println(s2)\n\t}()\n}\n\nfunc listing2() {\n\ts := make([]int, 0, 1)\n\n\tgo func() {\n\t\tsCopy := make([]int, len(s), cap(s))\n\t\tcopy(sCopy, s)\n\n\t\ts1 := append(sCopy, 1)\n\t\tfmt.Println(s1)\n\t}()\n\n\tgo func() {\n\t\tsCopy := make([]int, len(s), cap(s))\n\t\tcopy(sCopy, s)\n\n\t\ts2 := append(sCopy, 1)\n\t\tfmt.Println(s2)\n\t}()\n}\n"
  },
  {
    "path": "src/09-concurrency-practice/70-mutex-slices-maps/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n)\n\nfunc main() {\n\tc := Cache{\n\t\tbalances: make(map[string]float64),\n\t}\n\tc.AddBalance(\"1\", 1.0)\n\tc.AddBalance(\"2\", 3.0)\n\tfmt.Println(c.AverageBalance1())\n\tfmt.Println(c.AverageBalance2())\n\tfmt.Println(c.AverageBalance3())\n}\n\ntype Cache struct {\n\tmu       sync.RWMutex\n\tbalances map[string]float64\n}\n\nfunc (c *Cache) AddBalance(id string, balance float64) {\n\tc.mu.Lock()\n\tc.balances[id] = balance\n\tc.mu.Unlock()\n}\n\nfunc (c *Cache) AverageBalance1() float64 {\n\tc.mu.RLock()\n\tbalances := c.balances\n\tc.mu.RUnlock()\n\n\tsum := 0.\n\tfor _, balance := range balances {\n\t\tsum += balance\n\t}\n\treturn sum / float64(len(balances))\n}\n\nfunc (c *Cache) AverageBalance2() float64 {\n\tc.mu.RLock()\n\tdefer c.mu.RUnlock()\n\n\tsum := 0.\n\tfor _, balance := range c.balances {\n\t\tsum += balance\n\t}\n\treturn sum / float64(len(c.balances))\n}\n\nfunc (c *Cache) AverageBalance3() float64 {\n\tc.mu.RLock()\n\tm := make(map[string]float64, len(c.balances))\n\tfor k, v := range c.balances {\n\t\tm[k] = v\n\t}\n\tc.mu.RUnlock()\n\n\tsum := 0.\n\tfor _, balance := range m {\n\t\tsum += balance\n\t}\n\treturn sum / float64(len(m))\n}\n"
  },
  {
    "path": "src/09-concurrency-practice/71-wait-group/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"sync/atomic\"\n)\n\nfunc listing1() {\n\twg := sync.WaitGroup{}\n\tvar v uint64\n\n\tfor i := 0; i < 3; i++ {\n\t\tgo func() {\n\t\t\twg.Add(1)\n\t\t\tatomic.AddUint64(&v, 1)\n\t\t\twg.Done()\n\t\t}()\n\t}\n\n\twg.Wait()\n\tfmt.Println(v)\n}\n\nfunc listing2() {\n\twg := sync.WaitGroup{}\n\tvar v uint64\n\n\twg.Add(3)\n\tfor i := 0; i < 3; i++ {\n\t\tgo func() {\n\t\t\tatomic.AddUint64(&v, 1)\n\t\t\twg.Done()\n\t\t}()\n\t}\n\n\twg.Wait()\n\tfmt.Println(v)\n}\n\nfunc listing3() {\n\twg := sync.WaitGroup{}\n\tvar v uint64\n\n\tfor i := 0; i < 3; i++ {\n\t\twg.Add(1)\n\t\tgo func() {\n\t\t\tatomic.AddUint64(&v, 1)\n\t\t\twg.Done()\n\t\t}()\n\t}\n\n\twg.Wait()\n\tfmt.Println(v)\n}\n"
  },
  {
    "path": "src/09-concurrency-practice/72-cond/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n)\n\nfunc listing1() {\n\ttype Donation struct {\n\t\tmu      sync.RWMutex\n\t\tbalance int\n\t}\n\tdonation := &Donation{}\n\n\t// Listener goroutines\n\tf := func(goal int) {\n\t\tdonation.mu.RLock()\n\t\tfor donation.balance < goal {\n\t\t\tdonation.mu.RUnlock()\n\t\t\tdonation.mu.RLock()\n\t\t}\n\t\tfmt.Printf(\"$%d goal reached\\n\", donation.balance)\n\t\tdonation.mu.RUnlock()\n\t}\n\tgo f(10)\n\tgo f(15)\n\n\t// Updater goroutine\n\tgo func() {\n\t\tfor {\n\t\t\ttime.Sleep(time.Second)\n\t\t\tdonation.mu.Lock()\n\t\t\tdonation.balance++\n\t\t\tdonation.mu.Unlock()\n\t\t}\n\t}()\n}\n\nfunc listing2() {\n\ttype Donation struct {\n\t\tbalance int\n\t\tch      chan int\n\t}\n\n\tdonation := &Donation{ch: make(chan int)}\n\n\t// Listener goroutines\n\tf := func(goal int) {\n\t\tfor balance := range donation.ch {\n\t\t\tif balance >= goal {\n\t\t\t\tfmt.Printf(\"$%d goal reached\\n\", balance)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\tgo f(10)\n\tgo f(15)\n\n\t// Updater goroutine\n\tfor {\n\t\ttime.Sleep(time.Second)\n\t\tdonation.balance++\n\t\tdonation.ch <- donation.balance\n\t}\n}\n\nfunc listing3() {\n\ttype Donation struct {\n\t\tcond    *sync.Cond\n\t\tbalance int\n\t}\n\n\tdonation := &Donation{\n\t\tcond: sync.NewCond(&sync.Mutex{}),\n\t}\n\n\t// Listener goroutines\n\tf := func(goal int) {\n\t\tdonation.cond.L.Lock()\n\t\tfor donation.balance < goal {\n\t\t\tdonation.cond.Wait()\n\t\t}\n\t\tfmt.Printf(\"%d$ goal reached\\n\", donation.balance)\n\t\tdonation.cond.L.Unlock()\n\t}\n\tgo f(10)\n\tgo f(15)\n\n\t// Updater goroutine\n\tfor {\n\t\ttime.Sleep(time.Second)\n\t\tdonation.cond.L.Lock()\n\t\tdonation.balance++\n\t\tdonation.cond.L.Unlock()\n\t\tdonation.cond.Broadcast()\n\t}\n}\n"
  },
  {
    "path": "src/09-concurrency-practice/73-errgroup/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"golang.org/x/sync/errgroup\"\n)\n\nfunc handler1(ctx context.Context, circles []Circle) ([]Result, error) {\n\tresults := make([]Result, len(circles))\n\twg := sync.WaitGroup{}\n\twg.Add(len(results))\n\n\tfor i, circle := range circles {\n\t\ti := i\n\t\tcircle := circle\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\n\t\t\tresult, err := foo(ctx, circle)\n\t\t\tif err != nil {\n\t\t\t}\n\t\t\t// ?\n\t\t\tresults[i] = result\n\t\t}()\n\t}\n\n\twg.Wait()\n\t// ...\n\treturn results, nil\n}\n\nfunc handler2(ctx context.Context, circles []Circle) ([]Result, error) {\n\tresults := make([]Result, len(circles))\n\tg, ctx := errgroup.WithContext(ctx)\n\n\tfor i, circle := range circles {\n\t\ti := i\n\t\tcircle := circle\n\t\tg.Go(func() error {\n\t\t\tresult, err := foo(ctx, circle)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tresults[i] = result\n\t\t\treturn nil\n\t\t})\n\t}\n\n\tif err := g.Wait(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn results, nil\n}\n\nfunc foo(context.Context, Circle) (Result, error) {\n\treturn Result{}, nil\n}\n\ntype (\n\tCircle struct{}\n\tResult struct{}\n)\n"
  },
  {
    "path": "src/09-concurrency-practice/74-copying-sync/main.go",
    "content": "package main\n\nimport (\n\t\"sync\"\n\t\"time\"\n)\n\nfunc main() {\n\tcounter := NewCounter()\n\n\tgo func() {\n\t\tcounter.Increment1(\"foo\")\n\t}()\n\tgo func() {\n\t\tcounter.Increment1(\"bar\")\n\t}()\n\n\ttime.Sleep(10 * time.Millisecond)\n}\n\ntype Counter struct {\n\tmu       sync.Mutex // bad\n\tcounters map[string]int\n}\n\nfunc NewCounter() Counter {\n\treturn Counter{counters: map[string]int{}}\n}\n\nfunc (c Counter) Increment1(name string) {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\tc.counters[name]++\n}\n\nfunc (c *Counter) Increment2(name string) {\n\t// Same code\n}\n\ntype Counter2 struct {\n\tmu       *sync.Mutex // good\n\tcounters map[string]int\n}\n\nfunc NewCounter2() Counter2 {\n\treturn Counter2{\n\t\tmu:       &sync.Mutex{},\n\t\tcounters: map[string]int{},\n\t}\n}\n"
  },
  {
    "path": "src/10-standard-lib/75-wrong-time-duration/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc main() {\n\tlisting1()\n\t//listing2()\n}\n\nfunc listing1() {\n\tticker := time.NewTicker(1000)\n\tfor {\n\t\tselect {\n\t\tcase <-ticker.C:\n\t\t\tfmt.Println(\"tick\")\n\t\t}\n\t}\n}\n\nfunc listing2() {\n\tticker := time.NewTicker(time.Microsecond)\n\tfor {\n\t\tselect {\n\t\tcase <-ticker.C:\n\t\t\tfmt.Println(\"tick\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/10-standard-lib/76-time-after/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n)\n\nfunc consumer1(ch <-chan Event) {\n\tfor {\n\t\tselect {\n\t\tcase event := <-ch:\n\t\t\thandle(event)\n\t\tcase <-time.After(time.Hour):\n\t\t\tlog.Println(\"warning: no messages received\")\n\t\t}\n\t}\n}\n\nfunc consumer2(ch <-chan Event) {\n\tfor {\n\t\tctx, cancel := context.WithTimeout(context.Background(), time.Hour)\n\t\tselect {\n\t\tcase event := <-ch:\n\t\t\tcancel()\n\t\t\thandle(event)\n\t\tcase <-ctx.Done():\n\t\t\tlog.Println(\"warning: no messages received\")\n\t\t}\n\t}\n}\n\nfunc consumer3(ch <-chan Event) {\n\ttimerDuration := 1 * time.Hour\n\ttimer := time.NewTimer(timerDuration)\n\n\tfor {\n\t\ttimer.Reset(timerDuration)\n\t\tselect {\n\t\tcase event := <-ch:\n\t\t\thandle(event)\n\t\tcase <-timer.C:\n\t\t\tlog.Println(\"warning: no messages received\")\n\t\t}\n\t}\n}\n\ntype Event struct{}\n\nfunc handle(Event) {\n}\n"
  },
  {
    "path": "src/10-standard-lib/77-json-handling/map-any/main.go",
    "content": "package main\n\nimport \"encoding/json\"\n\nfunc listing1() error {\n\tb := getMessage()\n\tvar m map[string]any\n\terr := json.Unmarshal(b, &m)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc getMessage() []byte {\n\treturn nil\n}\n"
  },
  {
    "path": "src/10-standard-lib/77-json-handling/monotonic-clock/main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"time\"\n)\n\ntype Event struct {\n\tTime time.Time\n}\n\nfunc listing1() error {\n\tt := time.Now()\n\tevent1 := Event{\n\t\tTime: t,\n\t}\n\n\tb, err := json.Marshal(event1)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar event2 Event\n\terr = json.Unmarshal(b, &event2)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Println(event1 == event2)\n\treturn nil\n}\n\nfunc listing2() error {\n\tt := time.Now()\n\tevent1 := Event{\n\t\tTime: t.Truncate(0),\n\t}\n\n\tb, err := json.Marshal(event1)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar event2 Event\n\terr = json.Unmarshal(b, &event2)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Println(event1 == event2)\n\treturn nil\n}\n"
  },
  {
    "path": "src/10-standard-lib/77-json-handling/type-embedding/main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc main() {\n\tif err := listing1(); err != nil {\n\t\tpanic(err)\n\t}\n\tif err := listing2(); err != nil {\n\t\tpanic(err)\n\t}\n\tif err := listing3(); err != nil {\n\t\tpanic(err)\n\t}\n}\n\ntype Event1 struct {\n\tID int\n\ttime.Time\n}\n\nfunc listing1() error {\n\tevent := Event1{\n\t\tID:   1234,\n\t\tTime: time.Now(),\n\t}\n\n\tb, err := json.Marshal(event)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Println(string(b))\n\treturn nil\n}\n\ntype Event2 struct {\n\tID   int\n\tTime time.Time\n}\n\nfunc listing2() error {\n\tevent := Event2{\n\t\tID:   1234,\n\t\tTime: time.Now(),\n\t}\n\n\tb, err := json.Marshal(event)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Println(string(b))\n\treturn nil\n}\n\ntype Event3 struct {\n\tID int\n\ttime.Time\n}\n\nfunc (e Event3) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(\n\t\tstruct {\n\t\t\tID   int\n\t\t\tTime time.Time\n\t\t}{\n\t\t\tID:   e.ID,\n\t\t\tTime: e.Time,\n\t\t},\n\t)\n}\n\nfunc listing3() error {\n\tevent := Event3{\n\t\tID:   1234,\n\t\tTime: time.Now(),\n\t}\n\n\tb, err := json.Marshal(event)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Println(string(b))\n\treturn nil\n}\n"
  },
  {
    "path": "src/10-standard-lib/78-sql/null-values/main.go",
    "content": "package main\n\nimport \"database/sql\"\n\nfunc listing1(db *sql.DB, id string) error {\n\trows, err := db.Query(\"SELECT DEP, AGE FROM EMP WHERE ID = ?\", id)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// Defer closing rows\n\n\tvar (\n\t\tdepartment string\n\t\tage        int\n\t)\n\tfor rows.Next() {\n\t\terr := rows.Scan(&department, &age)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// ...\n\t}\n\treturn nil\n}\n\nfunc listing2(db *sql.DB, id string) error {\n\trows, err := db.Query(\"SELECT DEP, AGE FROM EMP WHERE ID = ?\", id)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// Defer closing rows\n\n\tvar (\n\t\tdepartment *string\n\t\tage        int\n\t)\n\tfor rows.Next() {\n\t\terr := rows.Scan(&department, &age)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// ...\n\t}\n\treturn nil\n}\n\nfunc listing3(db *sql.DB, id string) error {\n\trows, err := db.Query(\"SELECT DEP, AGE FROM EMP WHERE ID = ?\", id)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// Defer closing rows\n\n\tvar (\n\t\tdepartment sql.NullString\n\t\tage        int\n\t)\n\tfor rows.Next() {\n\t\terr := rows.Scan(&department, &age)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// ...\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "src/10-standard-lib/78-sql/prepared-statements/main.go",
    "content": "package main\n\nimport \"database/sql\"\n\nfunc listing1(db *sql.DB, id string) error {\n\tstmt, err := db.Prepare(\"SELECT * FROM ORDER WHERE ID = ?\")\n\tif err != nil {\n\t\treturn err\n\t}\n\trows, err := stmt.Query(id)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_ = rows\n\treturn nil\n}\n"
  },
  {
    "path": "src/10-standard-lib/78-sql/rows-iterations-errors/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"log\"\n)\n\nfunc get1(ctx context.Context, db *sql.DB, id string) (string, int, error) {\n\trows, err := db.QueryContext(ctx,\n\t\t\"SELECT DEP, AGE FROM EMP WHERE ID = ?\", id)\n\tif err != nil {\n\t\treturn \"\", 0, err\n\t}\n\tdefer func() {\n\t\terr := rows.Close()\n\t\tif err != nil {\n\t\t\tlog.Printf(\"failed to close rows: %v\\n\", err)\n\t\t}\n\t}()\n\n\tvar (\n\t\tdepartment string\n\t\tage        int\n\t)\n\tfor rows.Next() {\n\t\terr := rows.Scan(&department, &age)\n\t\tif err != nil {\n\t\t\treturn \"\", 0, err\n\t\t}\n\t}\n\n\treturn department, age, nil\n}\n\nfunc get2(ctx context.Context, db *sql.DB, id string) (string, int, error) {\n\trows, err := db.QueryContext(ctx,\n\t\t\"SELECT DEP, AGE FROM EMP WHERE ID = ?\", id)\n\tif err != nil {\n\t\treturn \"\", 0, err\n\t}\n\tdefer func() {\n\t\terr := rows.Close()\n\t\tif err != nil {\n\t\t\tlog.Printf(\"failed to close rows: %v\\n\", err)\n\t\t}\n\t}()\n\n\tvar (\n\t\tdepartment string\n\t\tage        int\n\t)\n\tfor rows.Next() {\n\t\terr := rows.Scan(&department, &age)\n\t\tif err != nil {\n\t\t\treturn \"\", 0, err\n\t\t}\n\t}\n\tif err := rows.Err(); err != nil {\n\t\treturn \"\", 0, err\n\t}\n\n\treturn department, age, nil\n}\n"
  },
  {
    "path": "src/10-standard-lib/78-sql/sql-open/main.go",
    "content": "package main\n\nimport \"database/sql\"\n\nvar dsn = \"\"\n\nfunc listing1() error {\n\tdb, err := sql.Open(\"mysql\", dsn)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := db.Ping(); err != nil {\n\t\treturn err\n\t}\n\n\t_ = db\n\treturn nil\n}\n"
  },
  {
    "path": "src/10-standard-lib/79-closing-resources/http/main.go",
    "content": "package main\n\nimport (\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n)\n\nfunc (h handler) getBody1() (string, error) {\n\tresp, err := h.client.Get(h.url)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn string(body), nil\n}\n\nfunc (h handler) getBody2() (string, error) {\n\tresp, err := h.client.Get(h.url)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tdefer func() {\n\t\terr := resp.Body.Close()\n\t\tif err != nil {\n\t\t\tlog.Printf(\"failed to close response: %v\\n\", err)\n\t\t}\n\t}()\n\n\treturn string(body), nil\n}\n\nfunc (h handler) getStatusCode1(body io.Reader) (int, error) {\n\tresp, err := h.client.Post(h.url, \"application/json\", body)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tdefer func() {\n\t\terr := resp.Body.Close()\n\t\tif err != nil {\n\t\t\tlog.Printf(\"failed to close response: %v\\n\", err)\n\t\t}\n\t}()\n\n\treturn resp.StatusCode, nil\n}\n\nfunc (h handler) getStatusCode2(body io.Reader) (int, error) {\n\tresp, err := h.client.Post(h.url, \"application/json\", body)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tdefer func() {\n\t\terr := resp.Body.Close()\n\t\tif err != nil {\n\t\t\tlog.Printf(\"failed to close response: %v\\n\", err)\n\t\t}\n\t}()\n\n\t_, _ = io.Copy(io.Discard, resp.Body)\n\n\treturn resp.StatusCode, nil\n}\n\ntype handler struct {\n\tclient http.Client\n\turl    string\n}\n"
  },
  {
    "path": "src/10-standard-lib/79-closing-resources/os-file/main.go",
    "content": "package main\n\nimport (\n\t\"log\"\n\t\"os\"\n)\n\nfunc listing1(filename string) error {\n\tf, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, os.ModeAppend)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer func() {\n\t\tif err := f.Close(); err != nil {\n\t\t\tlog.Printf(\"failed to close file: %v\\n\", err)\n\t\t}\n\t}()\n\n\treturn nil\n}\n\nfunc writeToFile1(filename string, content []byte) (err error) {\n\tf, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, os.ModeAppend)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer func() {\n\t\tcloseErr := f.Close()\n\t\tif err == nil {\n\t\t\terr = closeErr\n\t\t}\n\t}()\n\n\t_, err = f.Write(content)\n\treturn\n}\n\nfunc writeToFile2(filename string, content []byte) (err error) {\n\tf, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, os.ModeAppend)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer func() {\n\t\t_ = f.Close()\n\t}()\n\n\t_, err = f.Write(content)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn f.Sync()\n}\n"
  },
  {
    "path": "src/10-standard-lib/79-closing-resources/sql-rows/main.go",
    "content": "package main\n\nimport (\n\t\"database/sql\"\n\t\"log\"\n)\n\nfunc listing1() error {\n\tdb, err := sql.Open(\"postgres\", dataSourceName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\trows, err := db.Query(\"SELECT * FROM CUSTOMERS\")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Use rows\n\t_ = rows\n\n\treturn nil\n}\n\nfunc listing2() error {\n\tdb, err := sql.Open(\"postgres\", dataSourceName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\trows, err := db.Query(\"SELECT * FROM CUSTOMERS\")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer func() {\n\t\tif err := rows.Close(); err != nil {\n\t\t\tlog.Printf(\"failed to close rows: %v\\n\", err)\n\t\t}\n\t}()\n\n\t// Use rows\n\t_ = rows\n\n\treturn nil\n}\n\nvar dataSourceName = \"\"\n"
  },
  {
    "path": "src/10-standard-lib/80-http-return/main.go",
    "content": "package main\n\nimport \"net/http\"\n\nfunc handler1(w http.ResponseWriter, req *http.Request) {\n\terr := foo(req)\n\tif err != nil {\n\t\thttp.Error(w, \"foo\", http.StatusInternalServerError)\n\t}\n\n\t_, _ = w.Write([]byte(\"all good\"))\n\tw.WriteHeader(http.StatusCreated)\n}\n\nfunc handler2(w http.ResponseWriter, req *http.Request) {\n\terr := foo(req)\n\tif err != nil {\n\t\thttp.Error(w, \"foo\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\t_, _ = w.Write([]byte(\"all good\"))\n\tw.WriteHeader(http.StatusCreated)\n}\n\nfunc foo(req *http.Request) error {\n\treturn nil\n}\n"
  },
  {
    "path": "src/10-standard-lib/81-default-http-client-server/client/main.go",
    "content": "package main\n\nimport (\n\t\"net\"\n\t\"net/http\"\n\t\"time\"\n)\n\nfunc main() {\n\tclient := &http.Client{\n\t\tTimeout: 5 * time.Second,\n\t\tTransport: &http.Transport{\n\t\t\tDialContext: (&net.Dialer{\n\t\t\t\tTimeout: time.Second,\n\t\t\t}).DialContext,\n\t\t\tTLSHandshakeTimeout:   time.Second,\n\t\t\tResponseHeaderTimeout: time.Second,\n\t\t},\n\t}\n\t_ = client\n}\n"
  },
  {
    "path": "src/10-standard-lib/81-default-http-client-server/server/main.go",
    "content": "package main\n\nimport (\n\t\"net/http\"\n\t\"time\"\n)\n\nfunc main() {\n\ts := &http.Server{\n\t\tAddr:              \":8080\",\n\t\tReadHeaderTimeout: 500 * time.Millisecond,\n\t\tReadTimeout:       500 * time.Millisecond,\n\t\tHandler:           http.TimeoutHandler(handler{}, time.Second, \"foo\"),\n\t}\n\t_ = s\n}\n\ntype handler struct{}\n\nfunc (h handler) ServeHTTP(http.ResponseWriter, *http.Request) {}\n"
  },
  {
    "path": "src/11-testing/82-categorizing-tests/build-tags/db_test.go",
    "content": "//go:build integration\n// +build integration\n\npackage db\n\nimport (\n\t\"os\"\n\t\"testing\"\n)\n\nfunc TestInsert1(t *testing.T) {\n\t// ...\n}\n\nfunc TestInsert2(t *testing.T) {\n\tif os.Getenv(\"INTEGRATION\") != \"true\" {\n\t\tt.Skip(\"skipping integration test\")\n\t}\n\n\t// ...\n}\n"
  },
  {
    "path": "src/11-testing/82-categorizing-tests/short-mode/main_test.go",
    "content": "package main\n\nimport \"testing\"\n\nfunc TestLongRunning(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skipping long-running test\")\n\t}\n\t// ...\n}\n"
  },
  {
    "path": "src/11-testing/85-table-driven-tests/main.go",
    "content": "package main\n\nimport \"strings\"\n\nfunc removeNewLineSuffixes(s string) string {\n\tif s == \"\" {\n\t\treturn s\n\t}\n\tif strings.HasSuffix(s, \"\\r\\n\") {\n\t\treturn removeNewLineSuffixes(s[:len(s)-2])\n\t}\n\tif strings.HasSuffix(s, \"\\n\") {\n\t\treturn removeNewLineSuffixes(s[:len(s)-1])\n\t}\n\treturn s\n}\n"
  },
  {
    "path": "src/11-testing/85-table-driven-tests/main_test.go",
    "content": "package main\n\nimport \"testing\"\n\nfunc TestRemoveNewLineSuffix_Empty(t *testing.T) {\n\tgot := removeNewLineSuffixes(\"\")\n\texpected := \"\"\n\tif got != expected {\n\t\tt.Errorf(\"got: %s\", got)\n\t}\n}\n\nfunc TestRemoveNewLineSuffix_EndingWithCarriageReturnNewLine(t *testing.T) {\n\tgot := removeNewLineSuffixes(\"a\\r\\n\")\n\texpected := \"a\"\n\tif got != expected {\n\t\tt.Errorf(\"got: %s\", got)\n\t}\n}\n\nfunc TestRemoveNewLineSuffix_EndingWithNewLine(t *testing.T) {\n\tgot := removeNewLineSuffixes(\"a\\n\")\n\texpected := \"a\"\n\tif got != expected {\n\t\tt.Errorf(\"got: %s\", got)\n\t}\n}\n\nfunc TestRemoveNewLineSuffix_EndingWithMultipleNewLines(t *testing.T) {\n\tgot := removeNewLineSuffixes(\"a\\n\\n\\n\")\n\texpected := \"a\"\n\tif got != expected {\n\t\tt.Errorf(\"got: %s\", got)\n\t}\n}\n\nfunc TestRemoveNewLineSuffix_EndingWithoutNewLine(t *testing.T) {\n\tgot := removeNewLineSuffixes(\"a\\n\")\n\texpected := \"a\"\n\tif got != expected {\n\t\tt.Errorf(\"got: %s\", got)\n\t}\n}\n\nfunc TestRemoveNewLineSuffix(t *testing.T) {\n\ttests := map[string]struct {\n\t\tinput    string\n\t\texpected string\n\t}{\n\t\t`empty`: {\n\t\t\tinput:    \"\",\n\t\t\texpected: \"\",\n\t\t},\n\t\t`ending with \\r\\n`: {\n\t\t\tinput:    \"a\\r\\n\",\n\t\t\texpected: \"a\",\n\t\t},\n\t\t`ending with \\n`: {\n\t\t\tinput:    \"a\\n\",\n\t\t\texpected: \"a\",\n\t\t},\n\t\t`ending with multiple \\n`: {\n\t\t\tinput:    \"a\\n\\n\\n\",\n\t\t\texpected: \"a\",\n\t\t},\n\t\t`ending without newline`: {\n\t\t\tinput:    \"a\",\n\t\t\texpected: \"a\",\n\t\t},\n\t}\n\tfor name, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := removeNewLineSuffixes(tt.input)\n\t\t\tif got != tt.expected {\n\t\t\t\tt.Errorf(\"got: %s, expected: %s\", got, tt.expected)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "src/11-testing/86-sleeping/main.go",
    "content": "package main\n\ntype Handler struct {\n\tn         int\n\tpublisher publisher\n}\n\ntype publisher interface {\n\tPublish([]Foo)\n}\n\nfunc (h Handler) getBestFoo(someInputs int) Foo {\n\tfoos := getFoos(someInputs)\n\tbest := foos[0]\n\n\tgo func() {\n\t\tif len(foos) > h.n {\n\t\t\tfoos = foos[:h.n]\n\t\t}\n\t\th.publisher.Publish(foos)\n\t}()\n\n\treturn best\n}\n\nfunc getFoos(inputs int) []Foo {\n\treturn make([]Foo, 100)\n}\n\ntype Foo struct{}\n"
  },
  {
    "path": "src/11-testing/86-sleeping/main_test.go",
    "content": "package main\n\nimport (\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n)\n\ntype publisherMock1 struct {\n\tmu  sync.RWMutex\n\tgot []Foo\n}\n\nfunc (p *publisherMock1) Publish(got []Foo) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tp.got = got\n}\n\nfunc (p *publisherMock1) Get() []Foo {\n\tp.mu.RLock()\n\tdefer p.mu.RUnlock()\n\treturn p.got\n}\n\nfunc TestGetBestFoo(t *testing.T) {\n\tmock := publisherMock1{}\n\th := Handler{\n\t\tpublisher: &mock,\n\t\tn:         2,\n\t}\n\n\tfoo := h.getBestFoo(42)\n\t// Check foo\n\t_ = foo\n\n\ttime.Sleep(10 * time.Millisecond)\n\tpublished := mock.Get()\n\t// Check published\n\t_ = published\n}\n\nfunc assert(t *testing.T, assertion func() bool,\n\tmaxRetry int, waitTime time.Duration) {\n\tfor i := 0; i < maxRetry; i++ {\n\t\tif assertion() {\n\t\t\treturn\n\t\t}\n\t\ttime.Sleep(waitTime)\n\t}\n\tt.Fail()\n}\n\ntype publisherMock2 struct {\n\tch chan []Foo\n}\n\nfunc (p *publisherMock2) Publish(got []Foo) {\n\tp.ch <- got\n}\n\nfunc TestGetBestFoo2(t *testing.T) {\n\tmock := publisherMock2{\n\t\tch: make(chan []Foo),\n\t}\n\tdefer close(mock.ch)\n\n\th := Handler{\n\t\tpublisher: &mock,\n\t\tn:         2,\n\t}\n\tfoo := h.getBestFoo(42)\n\t// Check foo\n\t_ = foo\n\n\tif v := len(<-mock.ch); v != 2 {\n\t\tt.Fatalf(\"expected 2, got %d\", v)\n\t}\n}\n"
  },
  {
    "path": "src/11-testing/87-time-api/listing1/main.go",
    "content": "package listing1\n\nimport (\n\t\"sync\"\n\t\"time\"\n)\n\ntype Cache struct {\n\tmu     sync.RWMutex\n\tevents []Event\n}\n\ntype Event struct {\n\tTimestamp time.Time\n\tData      string\n}\n\nfunc (c *Cache) TrimOlderThan(since time.Duration) {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\n\tt := time.Now().Add(-since)\n\tfor i := 0; i < len(c.events); i++ {\n\t\tif c.events[i].Timestamp.After(t) {\n\t\t\tc.events = c.events[i:]\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (c *Cache) Add(events []Event) {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\n\tc.events = append(c.events, events...)\n}\n\nfunc (c *Cache) GetAll() []Event {\n\tc.mu.RLock()\n\tdefer c.mu.RUnlock()\n\n\treturn c.events\n}\n"
  },
  {
    "path": "src/11-testing/87-time-api/listing1/main_test.go",
    "content": "package listing1\n\nimport (\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestCache_TrimOlderThan(t *testing.T) {\n\tevents := []Event{\n\t\t{Timestamp: time.Now().Add(-20 * time.Millisecond)},\n\t\t{Timestamp: time.Now().Add(-10 * time.Millisecond)},\n\t\t{Timestamp: time.Now().Add(10 * time.Millisecond)},\n\t}\n\tcache := &Cache{}\n\tcache.Add(events)\n\tcache.TrimOlderThan(15 * time.Millisecond)\n\tgot := cache.GetAll()\n\texpected := 2\n\tif len(got) != expected {\n\t\tt.Fatalf(\"expected %d, got %d\", expected, len(got))\n\t}\n}\n"
  },
  {
    "path": "src/11-testing/87-time-api/listing2/main.go",
    "content": "package listing1\n\nimport (\n\t\"sync\"\n\t\"time\"\n)\n\ntype now func() time.Time\n\ntype Cache struct {\n\tmu     sync.RWMutex\n\tevents []Event\n\tnow    now\n}\n\nfunc NewCache() *Cache {\n\treturn &Cache{\n\t\tevents: make([]Event, 0),\n\t\tnow:    time.Now,\n\t}\n}\n\ntype Event struct {\n\tTimestamp time.Time\n\tData      string\n}\n\nfunc (c *Cache) TrimOlderThan(since time.Duration) {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\n\tt := time.Now().Add(-since)\n\tfor i := 0; i < len(c.events); i++ {\n\t\tif c.events[i].Timestamp.After(t) {\n\t\t\tc.events = c.events[i:]\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (c *Cache) Add(events []Event) {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\n\tc.events = append(c.events, events...)\n}\n\nfunc (c *Cache) GetAll() []Event {\n\tc.mu.RLock()\n\tdefer c.mu.RUnlock()\n\n\treturn c.events\n}\n"
  },
  {
    "path": "src/11-testing/87-time-api/listing2/main_test.go",
    "content": "package listing1\n\nimport (\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestCache_TrimOlderThan(t *testing.T) {\n\tevents := []Event{\n\t\t{Timestamp: parseTime(t, \"2020-01-01T12:00:00.04Z\")},\n\t\t{Timestamp: parseTime(t, \"2020-01-01T12:00:00.05Z\")},\n\t\t{Timestamp: parseTime(t, \"2020-01-01T12:00:00.06Z\")},\n\t}\n\tcache := &Cache{now: func() time.Time {\n\t\treturn parseTime(t, \"2020-01-01T12:00:00.06Z\")\n\t}}\n\tcache.Add(events)\n\tcache.TrimOlderThan(15 * time.Millisecond)\n\t// ...\n}\n\nfunc parseTime(t *testing.T, timestamp string) time.Time {\n\tts, err := time.Parse(time.RFC3339, timestamp)\n\tif err != nil {\n\t\tt.FailNow()\n\t}\n\treturn ts\n}\n"
  },
  {
    "path": "src/11-testing/87-time-api/listing3/main.go",
    "content": "package listing1\n\nimport (\n\t\"sync\"\n\t\"time\"\n)\n\ntype Cache struct {\n\tmu     sync.RWMutex\n\tevents []Event\n}\n\ntype Event struct {\n\tTimestamp time.Time\n\tData      string\n}\n\nfunc (c *Cache) TrimOlderThan(now time.Time, since time.Duration) {\n\tc.mu.RLock()\n\tdefer c.mu.RUnlock()\n\n\tt := now.Add(-since)\n\tfor i := 0; i < len(c.events); i++ {\n\t\tif c.events[i].Timestamp.After(t) {\n\t\t\tc.events = c.events[i:]\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (c *Cache) Add(events []Event) {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\n\tc.events = append(c.events, events...)\n}\n\nfunc (c *Cache) GetAll() []Event {\n\tc.mu.RLock()\n\tdefer c.mu.RUnlock()\n\n\treturn c.events\n}\n"
  },
  {
    "path": "src/11-testing/87-time-api/listing3/main_test.go",
    "content": "package listing1\n\nimport (\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestCache_TrimOlderThan(t *testing.T) {\n\tevents := []Event{\n\t\t{Timestamp: parseTime(t, \"2020-01-01T12:00:00.04Z\")},\n\t\t{Timestamp: parseTime(t, \"2020-01-01T12:00:00.05Z\")},\n\t\t{Timestamp: parseTime(t, \"2020-01-01T12:00:00.06Z\")},\n\t}\n\tcache := &Cache{}\n\tcache.Add(events)\n\tcache.TrimOlderThan(parseTime(t, \"2020-01-01T12:00:00.06Z\"), 15*time.Millisecond)\n\tgot := cache.GetAll()\n\texpected := 2\n\tif len(got) != expected {\n\t\tt.Fatalf(\"expected %d, got %d\", expected, len(got))\n\t}\n}\n\nfunc parseTime(t *testing.T, timestamp string) time.Time {\n\tts, err := time.Parse(time.RFC3339, timestamp)\n\tif err != nil {\n\t\tt.FailNow()\n\t}\n\treturn ts\n}\n"
  },
  {
    "path": "src/11-testing/87-time-api/listing4/main.go",
    "content": "package listing1\n\nimport (\n\t\"sync\"\n\t\"time\"\n)\n\ntype Cache struct {\n\tmu     sync.RWMutex\n\tevents []Event\n}\n\ntype Event struct {\n\tTimestamp time.Time\n\tData      string\n}\n\nfunc (c *Cache) TrimOlderThan(t time.Time) {\n\tc.mu.RLock()\n\tdefer c.mu.RUnlock()\n\n\tfor i := 0; i < len(c.events); i++ {\n\t\tif c.events[i].Timestamp.After(t) {\n\t\t\tc.events = c.events[i:]\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (c *Cache) Add(events []Event) {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\n\tc.events = append(c.events, events...)\n}\n\nfunc (c *Cache) GetAll() []Event {\n\tc.mu.RLock()\n\tdefer c.mu.RUnlock()\n\n\treturn c.events\n}\n"
  },
  {
    "path": "src/11-testing/87-time-api/listing4/main_test.go",
    "content": "package listing1\n\nimport (\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestCache_TrimOlderThan(t *testing.T) {\n\tevents := []Event{\n\t\t{Timestamp: parseTime(t, \"2020-01-01T12:00:00.04Z\")},\n\t\t{Timestamp: parseTime(t, \"2020-01-01T12:00:00.05Z\")},\n\t\t{Timestamp: parseTime(t, \"2020-01-01T12:00:00.06Z\")},\n\t}\n\tcache := &Cache{}\n\tcache.Add(events)\n\tcache.TrimOlderThan(parseTime(t, \"2020-01-01T12:00:00.06Z\").\n\t\tAdd(-15 * time.Millisecond))\n\tgot := cache.GetAll()\n\texpected := 2\n\tif len(got) != expected {\n\t\tt.Fatalf(\"expected %d, got %d\", expected, len(got))\n\t}\n}\n\nfunc parseTime(t *testing.T, timestamp string) time.Time {\n\tts, err := time.Parse(time.RFC3339, timestamp)\n\tif err != nil {\n\t\tt.FailNow()\n\t}\n\treturn ts\n}\n"
  },
  {
    "path": "src/11-testing/88-utility-package/httptest/main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n)\n\nfunc Handler(w http.ResponseWriter, r *http.Request) {\n\tw.Header().Add(\"X-API-VERSION\", \"1.0\")\n\tb, _ := io.ReadAll(r.Body)\n\t_, _ = w.Write(append([]byte(\"hello \"), b...))\n\tw.WriteHeader(http.StatusCreated)\n}\n\nfunc (c DurationClient) GetDuration(url string, lat1, lng1, lat2, lng2 float64) (time.Duration, error) {\n\tresp, err := c.client.Post(\n\t\turl, \"application/json\",\n\t\tbuildRequestBody(lat1, lng1, lat2, lng2),\n\t)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn parseResponseBody(resp.Body)\n}\n\ntype request struct {\n\tDuration int\n}\n\nfunc buildRequestBody(lat1, lng1, lat2, lng2 float64) io.Reader {\n\treturn strings.NewReader(\"\")\n}\n\ntype DurationClient struct {\n\tclient *http.Client\n}\n\nfunc NewDurationClient() DurationClient {\n\treturn DurationClient{\n\t\tclient: http.DefaultClient,\n\t}\n}\n\nfunc parseResponseBody(r io.ReadCloser) (time.Duration, error) {\n\tb, err := io.ReadAll(r)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tdefer func() {\n\t\t_ = r.Close()\n\t}()\n\n\tvar req request\n\terr = json.Unmarshal(b, &req)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn time.Duration(req.Duration) * time.Second, nil\n}\n"
  },
  {
    "path": "src/11-testing/88-utility-package/httptest/main_test.go",
    "content": "package main\n\nimport (\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestHandler(t *testing.T) {\n\treq := httptest.NewRequest(http.MethodGet, \"http://localhost\",\n\t\tstrings.NewReader(\"foo\"))\n\tw := httptest.NewRecorder()\n\tHandler(w, req)\n\n\tif got := w.Result().Header.Get(\"X-API-VERSION\"); got != \"1.0\" {\n\t\tt.Errorf(\"api version: expected 1.0, got %s\", got)\n\t}\n\n\tbody, _ := ioutil.ReadAll(w.Body)\n\tif got := string(body); got != \"hello foo\" {\n\t\tt.Errorf(\"body: expected hello foo, got %s\", got)\n\t}\n\n\tif http.StatusOK != w.Result().StatusCode {\n\t\tt.FailNow()\n\t}\n}\n\nfunc TestDurationClientGet(t *testing.T) {\n\tsrv := httptest.NewServer(\n\t\thttp.HandlerFunc(\n\t\t\tfunc(w http.ResponseWriter, r *http.Request) {\n\t\t\t\t_, _ = w.Write([]byte(`{\"duration\": 314}`))\n\t\t\t},\n\t\t),\n\t)\n\tdefer srv.Close()\n\n\tclient := NewDurationClient()\n\tduration, err :=\n\t\tclient.GetDuration(srv.URL, 51.551261, -0.1221146, 51.57, -0.13)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif duration != 314*time.Second {\n\t\tt.Errorf(\"expected 314 seconds, got %v\", duration)\n\t}\n}\n"
  },
  {
    "path": "src/11-testing/88-utility-package/iotest/main.go",
    "content": "package main\n\nimport (\n\t\"io\"\n)\n\ntype LowerCaseReader struct {\n\treader io.Reader\n}\n\nfunc (l LowerCaseReader) Read(p []byte) (int, error) {\n\treturn 0, nil\n}\n\nfunc foo1(r io.Reader) error {\n\tb, err := io.ReadAll(r)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// ...\n\t_ = b\n\treturn nil\n}\n\nfunc foo2(r io.Reader) error {\n\tb, err := readAll(r, 3)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// ...\n\t_ = b\n\treturn nil\n}\n\nfunc readAll(r io.Reader, retries int) ([]byte, error) {\n\tb := make([]byte, 0, 512)\n\tfor {\n\t\tif len(b) == cap(b) {\n\t\t\tb = append(b, 0)[:len(b)]\n\t\t}\n\t\tn, err := r.Read(b[len(b):cap(b)])\n\t\tb = b[:len(b)+n]\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\tretries--\n\t\t\tif retries < 0 {\n\t\t\t\treturn b, err\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/11-testing/88-utility-package/iotest/main_test.go",
    "content": "package main\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\t\"testing/iotest\"\n)\n\nfunc TestLowerCaseReader(t *testing.T) {\n\terr := iotest.TestReader(\n\t\t&LowerCaseReader{reader: strings.NewReader(\"aBcDeFgHiJ\")},\n\t\t[]byte(\"acegi\"),\n\t)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc TestFoo1(t *testing.T) {\n\terr := foo1(iotest.TimeoutReader(\n\t\tstrings.NewReader(randomString(1024)),\n\t))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc TestFoo2(t *testing.T) {\n\terr := foo2(iotest.TimeoutReader(\n\t\tstrings.NewReader(randomString(1024)),\n\t))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc randomString(i int) string {\n\treturn string(make([]byte, i))\n}\n"
  },
  {
    "path": "src/11-testing/89-benchmark/compiler-optimizations/main.go",
    "content": "package main\n\nconst (\n\tm1  = 0x5555555555555555\n\tm2  = 0x3333333333333333\n\tm4  = 0x0f0f0f0f0f0f0f0f\n\th01 = 0x0101010101010101\n)\n\nfunc popcnt(x uint64) uint64 {\n\tx -= (x >> 1) & m1\n\tx = (x & m2) + ((x >> 2) & m2)\n\tx = (x + (x >> 4)) & m4\n\treturn (x * h01) >> 56\n}\n"
  },
  {
    "path": "src/11-testing/89-benchmark/compiler-optimizations/main_test.go",
    "content": "package main\n\nimport \"testing\"\n\nfunc BenchmarkPopcnt1(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\tpopcnt(uint64(i))\n\t}\n}\n\nvar global uint64\n\nfunc BenchmarkPopcnt2(b *testing.B) {\n\tvar v uint64\n\tfor i := 0; i < b.N; i++ {\n\t\tv = popcnt(uint64(i))\n\t}\n\tglobal = v\n}\n"
  },
  {
    "path": "src/11-testing/89-benchmark/observer-effect/main.go",
    "content": "package main\n\nfunc calculateSum512(s [][512]int64) int64 {\n\tvar sum int64\n\tfor i := 0; i < len(s); i++ {\n\t\tfor j := 0; j < 8; j++ {\n\t\t\tsum += s[i][j]\n\t\t}\n\t}\n\treturn sum\n}\n\nfunc calculateSum513(s [][513]int64) int64 {\n\tvar sum int64\n\tfor i := 0; i < len(s); i++ {\n\t\tfor j := 0; j < 8; j++ {\n\t\t\tsum += s[i][j]\n\t\t}\n\t}\n\treturn sum\n}\n"
  },
  {
    "path": "src/11-testing/89-benchmark/observer-effect/main_test.go",
    "content": "package main\n\nimport \"testing\"\n\nconst rows = 1000\n\nvar res int64\n\nfunc BenchmarkCalculateSum512_1(b *testing.B) {\n\tvar sum int64\n\ts := createMatrix512(rows)\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tsum = calculateSum512(s)\n\t}\n\tres = sum\n}\n\nfunc BenchmarkCalculateSum513_1(b *testing.B) {\n\tvar sum int64\n\ts := createMatrix513(rows)\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tsum = calculateSum513(s)\n\t}\n\tres = sum\n}\n\nfunc BenchmarkCalculateSum512_2(b *testing.B) {\n\tvar sum int64\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer()\n\t\ts := createMatrix512(rows)\n\t\tb.StartTimer()\n\t\tsum = calculateSum512(s)\n\t}\n\tres = sum\n}\n\nfunc BenchmarkCalculateSum513_2(b *testing.B) {\n\tvar sum int64\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer()\n\t\ts := createMatrix512(rows)\n\t\tb.StartTimer()\n\t\tsum = calculateSum512(s)\n\t}\n\tres = sum\n}\n\nfunc createMatrix512(r int) [][512]int64 {\n\treturn make([][512]int64, r)\n}\n\nfunc createMatrix513(r int) [][513]int64 {\n\treturn make([][513]int64, r)\n}\n"
  },
  {
    "path": "src/11-testing/89-benchmark/timer/main_test.go",
    "content": "package timer\n\nimport \"testing\"\n\nfunc BenchmarkFoo1(b *testing.B) {\n\texpensiveSetup()\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tfunctionUnderTest()\n\t}\n}\n\nfunc BenchmarkFoo2(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer()\n\t\texpensiveSetup()\n\t\tb.StartTimer()\n\t\tfunctionUnderTest()\n\t}\n}\n\nfunc functionUnderTest() {\n}\n\nfunc expensiveSetup() {\n}\n"
  },
  {
    "path": "src/11-testing/89-benchmark/wrong-assumptions/main_test.go",
    "content": "package main\n\nimport (\n\t\"sync/atomic\"\n\t\"testing\"\n)\n\nfunc BenchmarkAtomicStoreInt32(b *testing.B) {\n\tvar v int32\n\tfor i := 0; i < b.N; i++ {\n\t\tatomic.StoreInt32(&v, 1)\n\t}\n}\n\nfunc BenchmarkAtomicStoreInt64(b *testing.B) {\n\tvar v int64\n\tfor i := 0; i < b.N; i++ {\n\t\tatomic.StoreInt64(&v, 1)\n\t}\n}\n"
  },
  {
    "path": "src/11-testing/90-testing-features/different-package/main.go",
    "content": "package counter\n\nimport \"sync/atomic\"\n\nvar count uint64\n\nfunc Inc() uint64 {\n\tatomic.AddUint64(&count, 1)\n\treturn count\n}\n"
  },
  {
    "path": "src/11-testing/90-testing-features/different-package/main_test.go",
    "content": "package counter_test\n\nimport (\n\t\"testing\"\n\n\tcounter \"github.com/teivah/100-go-mistakes/src/11-testing/90-testing-features/different-package\"\n)\n\nfunc TestCount(t *testing.T) {\n\tif counter.Inc() != 1 {\n\t\tt.Errorf(\"expected 1\")\n\t}\n}\n"
  },
  {
    "path": "src/11-testing/90-testing-features/setup-teardown/main_test.go",
    "content": "package main\n\nimport (\n\t\"database/sql\"\n\t\"os\"\n\t\"testing\"\n)\n\nfunc TestMySQLIntegration(t *testing.T) {\n\tsetupMySQL()\n\tdefer teardownMySQL()\n\n\t// ...\n}\n\nfunc createConnection(t *testing.T, dsn string) *sql.DB {\n\tdb, err := sql.Open(\"mysql\", dsn)\n\tif err != nil {\n\t\tt.FailNow()\n\t}\n\tt.Cleanup(\n\t\tfunc() {\n\t\t\t_ = db.Close()\n\t\t})\n\treturn db\n}\n\nfunc TestMain(m *testing.M) {\n\tsetupMySQL()\n\tcode := m.Run()\n\tteardownMySQL()\n\tos.Exit(code)\n}\n\nfunc setupMySQL() {}\n\nfunc teardownMySQL() {}\n"
  },
  {
    "path": "src/11-testing/90-testing-features/utility-function/main.go",
    "content": "package main\n\ntype Customer struct {\n\tid string\n}\n"
  },
  {
    "path": "src/11-testing/90-testing-features/utility-function/main_test.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"testing\"\n)\n\nfunc TestCustomer1(t *testing.T) {\n\tcustomer, err := createCustomer1(\"foo\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\t// ...\n\t_ = customer\n}\n\nfunc createCustomer1(someArg string) (Customer, error) {\n\tcustomer, err := customerFactory(someArg)\n\tif err != nil {\n\t\treturn Customer{}, err\n\t}\n\treturn customer, nil\n}\n\nfunc TestCustomer2(t *testing.T) {\n\tcustomer := createCustomer2(t, \"foo\")\n\t// ...\n\t_ = customer\n}\n\nfunc createCustomer2(t *testing.T, someArg string) Customer {\n\tcustomer, err := customerFactory(someArg)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\treturn customer\n}\n\nfunc customerFactory(someArg string) (Customer, error) {\n\tif someArg == \"\" {\n\t\treturn Customer{}, errors.New(\"empty\")\n\t}\n\treturn Customer{id: someArg}, nil\n}\n"
  },
  {
    "path": "src/12-optimizations/91-cpu-caches/cache-line/main.go",
    "content": "package main\n\nfunc sum2(s []int64) int64 {\n\tvar total int64\n\tfor i := 0; i < len(s); i += 2 {\n\t\ttotal += s[i]\n\t}\n\treturn total\n}\n\nfunc sum8(s []int64) int64 {\n\tvar total int64\n\tfor i := 0; i < len(s); i += 8 {\n\t\ttotal += s[i]\n\t}\n\treturn total\n}\n"
  },
  {
    "path": "src/12-optimizations/91-cpu-caches/cache-line/main_test.go",
    "content": "package main\n\nimport \"testing\"\n\nvar global int64\n\nfunc BenchmarkSum2(b *testing.B) {\n\tvar local int64\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer()\n\t\ts := make([]int64, 1_000_000)\n\t\tb.StartTimer()\n\t\tlocal = sum2(s)\n\t}\n\tglobal = local\n}\n\nfunc BenchmarkSum8(b *testing.B) {\n\tvar local int64\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer()\n\t\ts := make([]int64, 1_000_000)\n\t\tb.StartTimer()\n\t\tlocal = sum8(s)\n\t}\n\tglobal = local\n}\n"
  },
  {
    "path": "src/12-optimizations/91-cpu-caches/predictability/main.go",
    "content": "package main\n\ntype node struct {\n\tvalue int64\n\tnext  *node\n}\n\nfunc linkedList(n *node) int64 {\n\tvar total int64\n\tfor n != nil {\n\t\ttotal += n.value\n\t\tn = n.next\n\t}\n\treturn total\n}\n\nfunc sum2(s []int64) int64 {\n\tvar total int64\n\tfor i := 0; i < len(s); i += 2 {\n\t\ttotal += s[i]\n\t}\n\treturn total\n}\n"
  },
  {
    "path": "src/12-optimizations/91-cpu-caches/predictability/main_test.go",
    "content": "package main\n\nimport \"testing\"\n\nvar global int64\n\nconst n = 1_000_000\n\nfunc BenchmarkLinkedList(b *testing.B) {\n\tvar local int64\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer()\n\t\tnodes := make([]node, n)\n\t\tfor i := 0; i < n-1; i++ {\n\t\t\tnodes[i].next = &nodes[i+1]\n\t\t}\n\t\tb.StartTimer()\n\t\tlocal = linkedList(&nodes[0])\n\t}\n\tglobal = local\n}\n\nfunc BenchmarkSum2(b *testing.B) {\n\tvar local int64\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer()\n\t\ts := make([]int64, n)\n\t\tb.StartTimer()\n\t\tlocal = sum2(s)\n\t}\n\tglobal = local\n}\n"
  },
  {
    "path": "src/12-optimizations/91-cpu-caches/slice-structs/main.go",
    "content": "package main\n\ntype Foo struct {\n\ta int64\n\tb int64\n}\n\nfunc sumFoo(foos []Foo) int64 {\n\tvar total int64\n\tfor i := 0; i < len(foos); i++ {\n\t\ttotal += foos[i].a\n\t}\n\treturn total\n}\n\ntype Bar struct {\n\ta []int64\n\tb []int64\n}\n\nfunc sumBar(bar Bar) int64 {\n\tvar total int64\n\tfor i := 0; i < len(bar.a); i++ {\n\t\ttotal += bar.a[i]\n\t}\n\treturn total\n}\n"
  },
  {
    "path": "src/12-optimizations/91-cpu-caches/slice-structs/main_test.go",
    "content": "package main\n\nimport \"testing\"\n\nvar global int64\n\nconst n = 1_000_000\n\nfunc BenchmarkSumFoo(b *testing.B) {\n\tvar local int64\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer()\n\t\ts := make([]Foo, n)\n\t\tb.StartTimer()\n\t\tlocal = sumFoo(s)\n\t}\n\tglobal = local\n}\n\nfunc BenchmarkSumBar(b *testing.B) {\n\tvar local int64\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer()\n\t\tbar := Bar{\n\t\t\ta: make([]int64, n),\n\t\t\tb: make([]int64, n),\n\t\t}\n\t\tb.StartTimer()\n\t\tlocal = sumBar(bar)\n\t}\n\tglobal = local\n}\n"
  },
  {
    "path": "src/12-optimizations/92-false-sharing/main.go",
    "content": "package main\n\nimport \"sync\"\n\ntype Input struct {\n\ta int64\n\tb int64\n}\n\ntype Result1 struct {\n\tsumA int64\n\tsumB int64\n}\n\nfunc count1(inputs []Input) Result1 {\n\twg := sync.WaitGroup{}\n\twg.Add(2)\n\n\tresult := Result1{}\n\n\tgo func() {\n\t\tfor i := 0; i < len(inputs); i++ {\n\t\t\tresult.sumA += inputs[i].a\n\t\t}\n\t\twg.Done()\n\t}()\n\n\tgo func() {\n\t\tfor i := 0; i < len(inputs); i++ {\n\t\t\tresult.sumB += inputs[i].b\n\t\t}\n\t\twg.Done()\n\t}()\n\n\twg.Wait()\n\treturn result\n}\n\ntype Result2 struct {\n\tsumA int64\n\t_    [56]byte\n\tsumB int64\n}\n\nfunc count2(inputs []Input) Result2 {\n\twg := sync.WaitGroup{}\n\twg.Add(2)\n\n\tresult := Result2{}\n\n\tgo func() {\n\t\tfor i := 0; i < len(inputs); i++ {\n\t\t\tresult.sumA += inputs[i].a\n\t\t}\n\t\twg.Done()\n\t}()\n\n\tgo func() {\n\t\tfor i := 0; i < len(inputs); i++ {\n\t\t\tresult.sumB += inputs[i].b\n\t\t}\n\t\twg.Done()\n\t}()\n\n\twg.Wait()\n\treturn result\n}\n"
  },
  {
    "path": "src/12-optimizations/92-false-sharing/main_test.go",
    "content": "package main\n\nimport \"testing\"\n\nconst n = 1_000_000\n\nvar globalResult1 Result1\n\nfunc BenchmarkCount1(b *testing.B) {\n\tvar local Result1\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer()\n\t\tinputs := make([]Input, n)\n\t\tb.StartTimer()\n\t\tlocal = count1(inputs)\n\t}\n\tglobalResult1 = local\n}\n\nvar globalResult2 Result2\n\nfunc BenchmarkCount2(b *testing.B) {\n\tvar local Result2\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StopTimer()\n\t\tinputs := make([]Input, n)\n\t\tb.StartTimer()\n\t\tlocal = count2(inputs)\n\t}\n\tglobalResult2 = local\n}\n"
  },
  {
    "path": "src/12-optimizations/93-instruction-level-parallelism/main.go",
    "content": "package main\n\nconst n = 1_000_000\n\nfunc add(s [2]int64) [2]int64 {\n\tfor i := 0; i < n; i++ {\n\t\ts[0]++\n\t\tif s[0]%2 == 0 {\n\t\t\ts[1]++\n\t\t}\n\t}\n\treturn s\n}\n\nfunc add2(s [2]int64) [2]int64 {\n\tfor i := 0; i < n; i++ {\n\t\tv := s[0]\n\t\ts[0] = v + 1\n\t\tif v%2 != 0 {\n\t\t\ts[1]++\n\t\t}\n\t}\n\treturn s\n}\n"
  },
  {
    "path": "src/12-optimizations/93-instruction-level-parallelism/main_test.go",
    "content": "package main\n\nimport \"testing\"\n\nvar global [2]int64\n\nfunc BenchmarkAdd(b *testing.B) {\n\ta := [2]int64{}\n\tvar local [2]int64\n\tfor i := 0; i < b.N; i++ {\n\t\tlocal = add(a)\n\t}\n\tglobal = local\n}\n\nfunc BenchmarkAdd2(b *testing.B) {\n\ta := [2]int64{}\n\tvar local [2]int64\n\tfor i := 0; i < b.N; i++ {\n\t\tlocal = add2(a)\n\t}\n\tglobal = local\n}\n"
  },
  {
    "path": "src/12-optimizations/94-data-alignment/main.go",
    "content": "package main\n\ntype Foo1 struct {\n\tb1 byte\n\ti  int64\n\tb2 byte\n}\n\nfunc sum1(foos []Foo1) int64 {\n\tvar s int64\n\tfor i := 0; i < len(foos); i++ {\n\t\ts += foos[i].i\n\t}\n\treturn s\n}\n\ntype Foo2 struct {\n\ti  int64\n\tb1 byte\n\tb2 byte\n}\n\nfunc sum2(foos []Foo2) int64 {\n\tvar s int64\n\tfor i := 0; i < len(foos); i++ {\n\t\ts += foos[i].i\n\t}\n\treturn s\n}\n"
  },
  {
    "path": "src/12-optimizations/94-data-alignment/main_test.go",
    "content": "package main\n\nimport \"testing\"\n\nconst n = 1_000_000\n\nvar global int64\n\nfunc BenchmarkSum1(b *testing.B) {\n\tvar local int64\n\ts := make([]Foo1, n)\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tlocal = sum1(s)\n\t}\n\tglobal = local\n}\n\nfunc BenchmarkSum2(b *testing.B) {\n\tvar local int64\n\ts := make([]Foo2, n)\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tlocal = sum2(s)\n\t}\n\tglobal = local\n}\n"
  },
  {
    "path": "src/12-optimizations/95-stack-heap/main.go",
    "content": "package main\n\nfunc listing1() {\n\ta := 3\n\tb := 2\n\n\tc := sumValue(a, b)\n\tprintln(c)\n}\n\n//go:noinline\nfunc sumValue(x, y int) int {\n\tz := x + y\n\treturn z\n}\n\nfunc listing2() {\n\ta := 3\n\tb := 2\n\n\tc := sumPtr(a, b)\n\tprintln(*c)\n}\n\n//go:noinline\nfunc sumPtr(x, y int) *int {\n\tz := x + y\n\treturn &z\n}\n\nfunc listing3() {\n\ta := 3\n\tb := 2\n\tc := sum(&a, &b)\n\tprintln(c)\n}\n\n//go:noinline\nfunc sum(x, y *int) int {\n\treturn *x + *y\n}\n"
  },
  {
    "path": "src/12-optimizations/95-stack-heap/main_test.go",
    "content": "package main\n\nimport \"testing\"\n\nvar (\n\tglobalValue int\n\tglobalPtr   *int\n)\n\nfunc BenchmarkSumValue(b *testing.B) {\n\tb.ReportAllocs()\n\tvar local int\n\tfor i := 0; i < b.N; i++ {\n\t\tlocal = sumValue(i, i)\n\t}\n\tglobalValue = local\n}\n\nfunc BenchmarkSumPtr(b *testing.B) {\n\tb.ReportAllocs()\n\tvar local *int\n\tfor i := 0; i < b.N; i++ {\n\t\tlocal = sumPtr(i, i)\n\t}\n\tglobalValue = *local\n}\n"
  },
  {
    "path": "src/12-optimizations/96-reduce-allocations/compiler/main.go",
    "content": "package main\n\ntype cache struct {\n\tm map[string]int\n}\n\nfunc (c *cache) get1(bytes []byte) (v int, contains bool) {\n\tkey := string(bytes)\n\tv, contains = c.m[key]\n\treturn\n}\n\nfunc (c *cache) get2(bytes []byte) (v int, contains bool) {\n\tv, contains = c.m[string(bytes)]\n\treturn\n}\n"
  },
  {
    "path": "src/12-optimizations/96-reduce-allocations/sync-pool/main.go",
    "content": "package main\n\nimport (\n\t\"io\"\n\t\"sync\"\n)\n\nvar pool = sync.Pool{\n\tNew: func() any {\n\t\tb := make([]byte, 1024)\n\t\treturn &b\n\t},\n}\n\nfunc write(w io.Writer) {\n\tbPtr := pool.Get().(*[]byte)\n\tdefer func() {\n\t\t*bPtr = (*bPtr)[:0]\n\t\tpool.Put(bPtr)\n\t}()\n\n\tb := *bPtr\n\tgetResponse(b)\n\t_, _ = w.Write(b)\n}\n\nfunc getResponse([]byte) {\n}\n"
  }
]